PNG图像与BGRA CgBI预乘alpha

时间:2012-08-16 02:42:45

标签: ios core-graphics cgcontext alpha-transparency premultiplied-alpha

我使用Apple的iOS优化BGRA PNG格式的PNG(我使用OptimizedPNG得到的),并希望以告诉CoreGraphics不要忽略图像的alpha分量的方式绘制它们。我正在CGContextRef

中吸引drawRect:

编辑:渲染图像显示黑色应该完全透明(有时是其他随机工件)。不透明区域正常呈现。 CGImageAlphaInfo我从图片中得到kCGImageAlphaNoneSkipLast似乎表示OptimizedPNG保存图片的方式存在问题。我认为这应该是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;
    }
}

2 个答案:

答案 0 :(得分:1)

听起来你的PNG缺少alpha通道。

也许OptimizedPNG中存在错误;我不知道。尝试使用UIImagePNGRepresentation

也许你的原始图片没有alpha通道。您可以在预览(工具&gt;显示检查器)中查看,然后在更多信息&gt;常规中查找“Has Alpha”。

同时确保您的观看次数opaque为“否”,其backgroundColorclearColor。如果您没有绘制系统创建的上下文,请确保使用Alpha通道创建上下文。

根据您的评论,我在运行iOS 5.1.1的iPad 3上测试了此代码:

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。我在预览中打开文件进行检查。它仍然有一个alpha通道。

如果您仍然遇到问题,则需要向我们展示所有操作图片所涉及的代码,因为您要留下一些东西。编辑您的问题以包含更多详细信息和代码。

答案 1 :(得分:0)

根据您告诉我们的内容,没有理由使用透明层。透明层用于组合两个或多个对象以生成被视为单个对象的复合图形。如果要将效果应用于复合对象而不是每个单独的对象,这将非常有用。一个非常常见的情况是将阴影应用于多个对象的合成。

仅使用CGContextDrawImage()会将图像合成到考虑alpha通道的图形上下文中。确切地说,新图像如何通过图形内容中已有的任何内容进行合成取决于为图形内容设置的混合模式。您可以使用CGContextSetBlendMode()设置混合模式。详细说明可在Quartz 2D Programming Guide: Bitmaps Images and Masks中找到。正如您从参考资料中看到的,有很多选项可以合成图像,但我可能会猜到您已经考虑过kCGBlendModeMultiplykCGBlendModeNormal。请注意,默认值为kCGBlendModeNormal,它仅绘制源图像样本,而不是当前在上下文中关于alpha值的任何内容。