【问题标题】:Is there a way to preserve the RGB values of a pixel with an Alpha different from 255 in a PNG?有没有办法在 PNG 中保留 Alpha 不同于 255 的像素的 RGB 值?
【发布时间】:2014-08-29 05:04:03
【问题描述】:

我目前正在开展一个项目,该项目涉及使用具有自定义 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/ 的 int 值当我创建它们时,每个像素的 G/B 都是相同的。
这是一个 RGBA 示例 (Alpha = 255) -> (72, 101, 114, 255)
现在,如果我将所有像素的 Alpha 设置为 100,而不是 255,则上述 RGBA 示例将如下所示:(184, 255, 255, 100)。 如您所见,RGB 值与我最初创建的完全不同,我确实需要保留原始值(通过创建NSData 或类似的东西时的自定义属性)或计算它们的方法,不管Alpha 的值是什么。有没有办法做到这一点?
谢谢!

【问题讨论】:

  • 尝试kCGImageAlphaLast 而不是kCGImageAlphaPremultipliedLast。无论你做什么来改变 alpha 都会为你预乘:184 = 72 * (255 / 100)。其他两个值被剪裁为 255。
  • 尝试使用kCGImageAlphaLast 但现在它给了我一个错误并且没有创建图像。更多细节在这里:pastebin.com/SRde1HP7
  • 是的,kCGImageAlphaLast 不在位图图形上下文的supported pixel formats 列表中。
  • 在没有 alpha 的情况下运行一次并在最后预乘 alpha 的情况下运行一次是可接受的解决方法吗?这将是一个双重解码,但你要优化什么——努力、速度、代码大小,什么?

标签: objective-c macos cocoa rgb alpha


【解决方案1】:

您的数据具有未预乘(按 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。

【讨论】:

    猜你喜欢
    • 2021-10-05
    • 2019-09-05
    • 1970-01-01
    • 1970-01-01
    • 2020-07-04
    • 2011-01-31
    • 1970-01-01
    • 2014-07-16
    • 2017-04-26
    相关资源
    最近更新 更多