【发布时间】:2014-01-04 18:30:16
【问题描述】:
我有几个具有 alpha 透明度的 PNG 图像。这些在用于一般 Quartz 内容(例如在 UI 中)时会正确显示。然而,当我去获取图像并将其放入 OpenGL 时,我发现我得到的数据具有 255 的稳定 alpha。我使用的似乎是通常的 UIImage 转换为 CGImage 并渲染到上下文中。我将在下面发布相关的代码。
我做了很多搜索,最后偶然发现了一种解决方法,我想在这里分享,但它很慢,因为它必须遍历每个像素,并将原始 alpha 复制到 alpha 通道中。我很想知道解决这个问题的方法。我没有在我的构建中切换任何 PNG 选项(不确定在哪里设置)看看它是否有帮助..
谢谢
首先,我从我的应用中获得一个 UIImage,如下所示:
UIImage *image = [UIImage imageNamed:imageName];
然后我转换为一个 CGImageRef 并且我只像这个相关行一样创建通常的上下文:
CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height,
bitsPerComponent, bytesPerRow,
CGImageGetColorSpace(spriteImage),
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
接下来的两行是让我获得真实 png 原始数据的魔力……我可能应该检查 RGBA 与其他格式,但我很懒……之后我绘制图像,然后返回并修复alpha……是的,我知道我可以在一个循环中执行此操作并跳过字节,这现在更具可读性……
// THIS data actually HAS the alpha!!
CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(spriteImage));
GLubyte *pixels = (GLubyte *)CFDataGetBytePtr(data);
// 3
CGContextDrawImage(spriteContext, CGRectMake(0, 0, width, height), spriteImage);
// Sadly we now have to loop and fix the ALPHA directly from the raw PNG source
// data as otherwise we get wrong/missing alpha...
for (int y=0; y < height; ++y) {
for (int x=0; x < width; ++x) {
int byteIndex = (bytesPerRow * y) + (x * bytesPerPixel);
spriteData[byteIndex + 3] = pixels[byteIndex +3 ];
}
}
然后我执行通常的 glTexture 调用等……它工作正常。如果我忽略上面的复制循环,我会得到没有 alpha 的实体精灵。如果我执行上述操作,我的精灵会以透明度正确绘制。
我知道 iOS 所做的所有预乘的事情,但这似乎是坏的……至少希望以上内容可能对某人有所帮助,但必须有更好的方法???
想法?谢谢!
【问题讨论】:
-
如果 CGDataProviderCopyData() 为您提供正确的原始数据,为什么不将其用于您的纹理,而不是使用 CGContextDrawImage() 重绘它呢?你不应该需要后者,或者你的循环。
-
好点....我应该试试。我确实尝试过以其他方式使用它,但它给出了一个错误,因为它当然是只读的,但也限制了我传入......我忘记了它是什么......好主意......我应该提到这段代码来自苹果。有一个示例有它和正确的代码来读取没有 pre-mult alpha 的文件。虽然我真正的问题仍然是为什么那是正确的而 CGImage 是不正确的......
-
CGBitmapContextCreate() 仅支持预乘 alpha(至少在 iOS 上是这样),但 CGDataProviderCopyData() 从图像中提取原始像素数据,我认为通常不会预乘。
-
那行得通,我不得不将 glTexImage2D 中的第二个格式三元组更改为 GL_BGRA,因为 CopyData 的格式是我的图像的格式。所以我想至少这真的很快,更干净,并且不需要上下文等......
-
哦,如前所述,这是来自苹果的 GLImageProcessing 示例……它具有从 RGB 到 BGR 等转换的正确代码……可在此处获得:developer.apple.com/library/ios/samplecode/GLImageProcessing/…
标签: ios opengl-es png alpha cgimage