我有几个具有alpha透明度的PNG图像。这些显示适用于一般石英的东西,如在用户界面。但是,当我去拍摄图像并将其导入OpenGL时,我发现我得到的数据具有255的固定alpha值。我正在使用通常的UIImage转换为CGImage并渲染到上下文中。我将在下面发布相关代码。iOS PNG在将UIImage转换为CGImage for OpenGL时,Alpha通道是固定的
我做了很多搜索,最后偶然发现了这个问题,我想在这里分享一下,但它很慢,因为它必须遍历每个像素,并将原始alpha复制到alpha通道中。我很想知道解决这个问题的方法。我没有任何转换选项PNG在我的版本(不知道在哪里设置),看看它是否有助于..
感谢
首先我从我的应用程序一个UIImage我添加这样的:
UIImage *image = [UIImage imageNamed:imageName];
然后我转换为CGImageRef,我做平常环境中创建像仅此相关行:
CGContextRef spriteContext = CGBitmapContextCreate(spriteData, width, height,
bitsPerComponent, bytesPerRow,
CGImageGetColorSpace(spriteImage),
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
然后将这些接下来的两行是魔术让我在真正的PNG生达ta ...我可能应该检查RGBA vs其他格式,但我很懒...之后,我画了图像,然后回去修复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重绘()?你不应该需要后者,或者你的循环。 –
好点....我应该尝试一下。我确实尝试过以其他方式使用它,它给出了一个错误,因为它当然是只读的,但也限制了我传入...我忘记了它是什么...好主意tho ...我应该提到这个代码来自Apple。还有的是,在它与正确的代码读取无需预先MULT阿尔法..文件的范例苴我真正的问题是,为什么是正确的,CGImage是不正确的...... – mcomet
CGBitmapContextCreate()只支持预乘alpha(iOS上,至少),但CGDataProviderCopyData()从图像中提取原始像素数据,我相信这通常不是预乘。 –