如何设置 UIImage 的透明度/alpha?

我知道你可以用 UIImageView 做到这一点,但是它可以用 UIImage 做到吗?我想有一个 UIImageView 的动画图像数组属性是一个数组相同的图像,但不同的不透明度。有什么想法吗?

120561 次浏览

Set the opacity of its view it is showed in.

UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithName:@"SomeName.png"]];
imageView.alpha = 0.5; //Alpha runs from 0.0 to 1.0

Use this in an animation. You can change the alpha in an animation for an duration.

[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
//Set alpha
[UIView commitAnimations];

I realize this is quite late, but I needed something like this so I whipped up a quick and dirty method to do this.

+ (UIImage *) image:(UIImage *)image withAlpha:(CGFloat)alpha{


// Create a pixel buffer in an easy to use format
CGImageRef imageRef = [image CGImage];
NSUInteger width = CGImageGetWidth(imageRef);
NSUInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();


UInt8 * m_PixelBuf = malloc(sizeof(UInt8) * height * width * 4);


NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(m_PixelBuf, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);


CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);


//alter the alpha
int length = height * width * 4;
for (int i=0; i<length; i+=4)
{
m_PixelBuf[i+3] =  255*alpha;
}




//create a new image
CGContextRef ctx = CGBitmapContextCreate(m_PixelBuf, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);


CGImageRef newImgRef = CGBitmapContextCreateImage(ctx);
CGColorSpaceRelease(colorSpace);
CGContextRelease(ctx);
free(m_PixelBuf);


UIImage *finalImage = [UIImage imageWithCGImage:newImgRef];
CGImageRelease(newImgRef);


return finalImage;
}

I just needed to do this, but thought Steven's solution would be slow. This should hopefully use graphics HW. Create a category on UIImage:

- (UIImage *)imageByApplyingAlpha:(CGFloat) alpha {
UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);


CGContextRef ctx = UIGraphicsGetCurrentContext();
CGRect area = CGRectMake(0, 0, self.size.width, self.size.height);


CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -area.size.height);


CGContextSetBlendMode(ctx, kCGBlendModeMultiply);


CGContextSetAlpha(ctx, alpha);


CGContextDrawImage(ctx, area, self.CGImage);


UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();


UIGraphicsEndImageContext();


return newImage;
}

there is much easier solution:

- (UIImage *)tranlucentWithAlpha:(CGFloat)alpha
{
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[self drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:alpha];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

Based on Alexey Ishkov's answer, but in Swift

I used an extension of the UIImage class.

Swift 2:

UIImage Extension:

extension UIImage {
func imageWithAlpha(alpha: CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
drawAtPoint(CGPointZero, blendMode: .Normal, alpha: alpha)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}

To use:

let image = UIImage(named: "my_image")
let transparentImage = image.imageWithAlpha(0.5)

Swift 3/4/5:

Note that this implementation returns an optional UIImage. This is because in Swift 3 UIGraphicsGetImageFromCurrentImageContext now returns an optional. This value could be nil if the context is nil or what not created with UIGraphicsBeginImageContext.

UIImage Extension:

extension UIImage {
func image(alpha: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(at: .zero, blendMode: .normal, alpha: alpha)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}

To use:

let image = UIImage(named: "my_image")
let transparentImage = image?.image(alpha: 0.5)

Hey hey thanks from Xamarin user! :) Here it goes translated to c#

//***************************************************************************
public static class ImageExtensions
//***************************************************************************
{
//-------------------------------------------------------------
public static UIImage WithAlpha(this UIImage image, float alpha)
//-------------------------------------------------------------
{
UIGraphics.BeginImageContextWithOptions(image.Size,false,image.CurrentScale);
image.Draw(CGPoint.Empty, CGBlendMode.Normal, alpha);
var newImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return newImage;
}


}

Usage example:

var MySupaImage = UIImage.FromBundle("opaquestuff.png").WithAlpha(0.15f);

same result as others, different style:

extension UIImage {


func withAlpha(_ alpha: CGFloat) -> UIImage {
return UIGraphicsImageRenderer(size: size).image { _ in
draw(at: .zero, blendMode: .normal, alpha: alpha)
}
}


}

If you're experimenting with Metal rendering & you're extracting the CGImage generated by imageByApplyingAlpha in the first reply, you may end up with a Metal rendering that's larger than you expect. While experimenting with Metal, you may want to change one line of code in imageByApplyingAlpha:

    UIGraphicsBeginImageContextWithOptions (self.size, NO, 1.0f);
//  UIGraphicsBeginImageContextWithOptions (self.size, NO, 0.0f);

If you're using a device with a scale factor of 3.0, like the iPhone 11 Pro Max, the 0.0 scale factor shown above will give you an CGImage that's three times larger than you're expecting. Changing the scale factor to 1.0 should avoid any scaling.

Hopefully, this reply will save beginners a lot of aggravation.

Swift 5:

extension UIImage {
func withAlphaComponent(_ alpha: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
defer { UIGraphicsEndImageContext() }


draw(at: .zero, blendMode: .normal, alpha: alpha)
return UIGraphicsGetImageFromCurrentImageContext()
}
}