我有苹果iOS优化的BGRA PNG格式的PNG(我使用OptimizedPNG得到的),并希望以一种告诉CoreGraphics不要忽略图像的alpha组件的方式绘制它们。我正在画drawRect:
的CGContextRef
编辑:渲染的图像在应该完全透明的地方显示黑色(有时是其他随机伪影)。不透明区域正常呈现。 我从图像中得到CGImageAlphaInfo
是kCGImageAlphaNoneSkipLast
,这似乎表明优化PNG保存图像的方式存在问题。我认为这应该是kCGImageAlphaPremultipliedLast
.
也许PNG块是错误的,但我看不出IHDR有什么问题,而且我能找到的关于CgBI块的东西很少。
以下是 OptimizedPNG 保存颜色数据的方式:
// IDAT
int size = width*height*4;
unsigned char *buffer = malloc(size);
CGContextRef context = CGBitmapContextCreate(buffer, width, height, 8, width*4, CGImageGetColorSpace(originalImage.CGImage), kCGImageAlphaPremultipliedLast);
CGRect rect = CGRectMake(0.0, 0.0, (CGFloat)width, (CGFloat)height);
CGContextDrawImage(context, rect, originalImage.CGImage);
CGContextRelease(context);
int size_line = 1 + width*4;
int size_in = height*size_line;
unsigned char *buffer_in = malloc(size_in);
for(int y = 0; y < height; ++y){
unsigned char *src = &buffer[y*width*4];
unsigned char *dst = &buffer_in[y*size_line];
*dst++ = 1;
unsigned char r = 0, g = 0, b = 0, a = 0;
for(int x = 0; x < width; ++x){
dst[0] = src[2] - b;
dst[1] = src[1] - g;
dst[2] = src[0] - r;
dst[3] = src[3] - a;
r = src[0], g = src[1], b = src[2], a = src[3];
src += 4;
dst += 4;
}
}
听起来您的 PNG 缺少 alpha 通道。
也许优化的PNG中有一个错误;我不知道。 尝试使用 UIImagePNGRepresentation
.
也许您的原始图像没有 Alpha 通道。 您可以在"预览"中查看("显示检查器"工具>然后在"更多信息">"常规")中查找"已使用 Alpha")。
还要确保您的视图opaque
为"否",其backgroundColor
为 clearColor
。 如果未绘制到系统创建的上下文,请确保使用 Alpha 通道创建上下文。
根据您的评论,我在运行iOS 3的iPad 5.1.1上测试了此代码:
UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://upload.wikimedia.org/wikipedia/commons/f/fb/Wikisource-logo.png"]]];
NSData *data = UIImagePNGRepresentation(image);
NSURL *documentDirectoryURL = [[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask].lastObject;
NSURL *url = [documentDirectoryURL URLByAppendingPathComponent:@"test.png"];
[data writeToURL:url atomically:YES];
然后我使用Xcode Organizer从我的设备复制test.png
。 我在预览中打开了文件进行检查。 它仍然有一个阿尔法通道。
如果您仍然遇到问题,则需要向我们展示处理图像所涉及的所有代码,因为您遗漏了一些内容。 编辑您的问题以包含更多详细信息和代码。
根据您告诉我们的内容,没有理由使用透明层。透明度图层用于组合两个或多个对象,以生成被视为单个对象的复合图形。如果要将效果应用于复合对象而不是每个单独的对象,这将非常有用。一种非常常见的情况是将阴影应用于多个对象的复合。
仅使用 CGContextDrawImage()
就会将图像合成到考虑 alpha 通道的图形上下文中。新图像在图形内容中已有的任何内容上的合成方式取决于为图形内容设置的混合模式。您可以使用 CGContextSetBlendMode()
设置混合模式。详细的描述可以在 Quartz 2D 编程指南:位图图像和蒙版中找到。从参考资料中可以看出,如何合成图像有很多选项,但我可能猜你想到了kCGBlendModeMultiply
或kCGBlendModeNormal
。请注意,默认值为 kCGBlendModeNormal
,它只是将源图像样本绘制在上下文中当前与 alpha 值相关的任何内容上。