【发布时间】:2011-07-02 08:58:37
【问题描述】:
我知道你可以用 UIImageView 做到这一点,但它可以做到 UIImage 吗?我想让 UIImageView 的动画图像数组属性成为相同图像但具有不同不透明度的数组。想法?
【问题讨论】:
标签: ios uiimageview uiimage opacity alpha
我知道你可以用 UIImageView 做到这一点,但它可以做到 UIImage 吗?我想让 UIImageView 的动画图像数组属性成为相同图像但具有不同不透明度的数组。想法?
【问题讨论】:
标签: ios uiimageview uiimage opacity alpha
我只是需要这样做,但认为 Steven 的解决方案会很慢。这应该希望使用图形硬件。在 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;
}
【讨论】:
设置其显示的视图的不透明度。
UIImageView *imageView = [[UIImageView alloc] initWithImage:[UIImage imageWithName:@"SomeName.png"]];
imageView.alpha = 0.5; //Alpha runs from 0.0 to 1.0
在动画中使用它。您可以在一段时间内更改动画中的 alpha。
[UIView beginAnimations:nil context:NULL];
[UIView setAnimationDuration:1.0];
//Set alpha
[UIView commitAnimations];
【讨论】:
UIButton 上工作,正是我需要的。
基于 Alexey Ishkov 的回答,但在 Swift 中
我使用了 UIImage 类的扩展。
斯威夫特 2:
UIImage 扩展:
extension UIImage {
func imageWithAlpha(alpha: CGFloat) -> UIImage {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
drawAtPoint(CGPointZero, blendMode: .Normal, alpha: alpha)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
使用方法:
let image = UIImage(named: "my_image")
let transparentImage = image.imageWithAlpha(0.5)
斯威夫特 3/4/5:
请注意,此实现返回一个可选的 UIImage。这是因为在 Swift 3 UIGraphicsGetImageFromCurrentImageContext 现在返回一个可选的。如果上下文为 nil 或不是使用 UIGraphicsBeginImageContext 创建的,则此值可能为 nil。
UIImage 扩展:
extension UIImage {
func image(alpha: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
draw(at: .zero, blendMode: .normal, alpha: alpha)
let newImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return newImage
}
}
使用方法:
let image = UIImage(named: "my_image")
let transparentImage = image?.image(alpha: 0.5)
【讨论】:
Swift 3 版本。
有更简单的解决方案:
- (UIImage *)tranlucentWithAlpha:(CGFloat)alpha
{
UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);
[self drawAtPoint:CGPointZero blendMode:kCGBlendModeNormal alpha:alpha];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
【讨论】:
嘿嘿感谢 Xamarin 用户! :) 这里翻译成 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;
}
}
使用示例:
var MySupaImage = UIImage.FromBundle("opaquestuff.png").WithAlpha(0.15f);
【讨论】:
我意识到这已经很晚了,但我需要这样的东西,所以我想出了一个快速而肮脏的方法来做到这一点。
+ (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;
}
【讨论】:
setImage:withAlpha:
image:withAlpha:?
斯威夫特 5:
extension UIImage {
func withAlphaComponent(_ alpha: CGFloat) -> UIImage? {
UIGraphicsBeginImageContextWithOptions(size, false, scale)
defer { UIGraphicsEndImageContext() }
draw(at: .zero, blendMode: .normal, alpha: alpha)
return UIGraphicsGetImageFromCurrentImageContext()
}
}
【讨论】:
结果和别人一样,风格不同:
extension UIImage {
func withAlpha(_ alpha: CGFloat) -> UIImage {
return UIGraphicsImageRenderer(size: size).image { _ in
draw(at: .zero, blendMode: .normal, alpha: alpha)
}
}
}
【讨论】:
如果您正在尝试使用 Metal 渲染并且您在第一个回复中提取由 imageByApplyingAlpha 生成的 CGImage,那么您最终可能会得到比您预期更大的 Metal 渲染。在尝试使用 Metal 时,您可能需要更改 imageByApplyingAlpha 中的一行代码:
UIGraphicsBeginImageContextWithOptions (self.size, NO, 1.0f);
// UIGraphicsBeginImageContextWithOptions (self.size, NO, 0.0f);
如果您使用比例因子为 3.0 的设备,例如 iPhone 11 Pro Max,则上面显示的 0.0 比例因子将为您提供比预期大三倍的 CGImage。将比例因子更改为 1.0 应该可以避免任何缩放。
希望这个回复可以为初学者省去很多麻烦。
【讨论】: