2

我有 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;
    }
}
4

2 回答 2

1

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

可能 OptimizedPNG 有 bug;我不知道。尝试使用UIImagePNGRepresentation.

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

还要确保你的观点opaque是 NO 并且它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];

test.png然后我使用 Xcode Organizer 从我的设备复制。我在预览中打开文件进行检查。它仍然有一个 Alpha 通道。

如果您仍然遇到问题,您需要向我们展示处理图像所涉及的所有代码,因为您遗漏了一些内容。编辑您的问题以包含更多详细信息和代码。

于 2012-08-16T04:09:43.440 回答
0

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

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

于 2012-08-16T04:09:30.393 回答