我目前正在开发一个项目,该项目包含使用具有自定义RGBA值的PNG。这是我用来创建包含我的自定义RGBA值的PNG NSData
的代码的预览(所有这些都正常工作):
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef gtx = CGBitmapContextCreate(&pixelData, width, height, bitsPerComponent, BytesPerRow, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedLast);
CGImageRef toCGImage = CGBitmapContextCreateImage(gtx);
NSBitmapImageRep *newRep = [[NSBitmapImageRep alloc] initWithCGImage:toCGImage];
NSData *pngData = [newRep representationUsingType:NSPNGFileType properties:nil];
当我创建pixelData
(包含所有RGBA值的uint8_t
数组)时,我将每个像素的Alpha
索引设置为255,{{当我创建它们时,每个像素的每个R / G / B的值都是相同的
这是一个RGBA示例(int
= 255) - > (72,101,114,255)
现在,如果我将所有像素的Alpha
设置为100,而不是255,则上述RGBA示例将如下所示:(184,255,255,100) 。
正如您所看到的,RGB值与我最初创建的完全不同,我确实需要保留原始值(在创建Alpha
或类似的东西时通过自定义属性)或计算它们的方法返回,无论NSData
值是多少。有没有办法做到这一点?
谢谢!
答案 0 :(得分:0)
您的数据未经过预乘(按Alpha)颜色分量。 Core Graphics期待预乘alpha。
根据您构建pixelData
数组的方式,您可以在自己的代码中预先乘以它(例如premultipliedRed = unpremultipliedRed * alpha / 255.0
),也可以使用Accelerate框架将其转换为事实。您可以使用函数vImagePremultiplyData_RGBA8888()
来执行此操作:
vImage_Buffer buffer = { pixelData, width, height, BytesPerRow };
vImagePremultiplyData_RGBA8888(&buffer, &buffer, 0);
如果稍后您返回预乘数据并且需要转换回非预乘,则可以使用vImageUnpremultiplyData_RGBA8888()
执行相反操作。往返行程可能会有一些精度损失,因此您无法保证能够逐位取回原始源数据。这是在无预乘和预乘之间进行转换的必然结果。如果这是一个问题,您需要保留原始源数据或不使用Core Graphics。