在iOS中加载4通道纹理数据

我想从iOS中的文件加载4通道纹理数据,所以我将纹理视为(连续)地图

[0,1]x[0,1] -> [0,1]x[0,1]x[0,1]x[0,1] 

如果我使用fileformat .png ,则XCode / iOS会将该文件视为图像,并将每个组件rgb与(预乘alpha)相乘,从而损坏我的数据。 我应该如何解决这个问题? 例子可能是

  • 使用两个纹理与组件rgb (3通道)
  • postadvide阿尔法
  • 使用另一种文件格式

其中,我认为最好的解决scheme是使用另一种文件格式。 GL压缩的文件格式(PVRTC?)不是苹果平台独立的,似乎是低分辨率(4位)( 参考 )。

编辑:如果我自己的答案如下,这是不可能得到在iOS的4通道数据的PNG的。 由于OpenGL是关于创build图像而不是呈现图像,因此应该可以以某种方式加载4通道数据。 PNG是图像的文件格式( 压缩取决于所有4个通道 但是一个频道的压缩与其他频道无关),所以有人可能会说我应该使用另一种文件格式。 那么,我应该使用哪些其他压缩文件格式,这很容易在iOS中读取/集成?

更新:“组合”提到了加载4通道非预乘纹理的方式,所以我不得不给他正确的答案。 但是,这个解决scheme有一些我不喜欢的限制。 我的下一个问题是“从iOS中的png文件访问原始的4通道数据”:)

我认为这是一个不好的库devise,不能读取4通道PNG数据。 我不喜欢系统比我自己更聪明。

正如你考虑PVRTC那么使用GLKit可能是一个选项。 这包括GLKTextureLoader ,它允许你加载纹理而不需要预乘alpha。 使用例如:

 + (GLKTextureInfo *)textureWithContentsOfFile:(NSString *)fileName options:(NSDictionary *)textureOperations error:(NSError **)outError 

并传递一个选项字典包含:

 GLKTextureLoaderApplyPremultiplication = NO 

您可以简单地要求Xcode不“压缩”您的PNG文件。 点击左上方的项目,select“构build设置”,find“压缩PNG文件”,并将选项设置为“否”。

至于你的其他选项,postdividing不是一个不好的解决scheme,但显然你会失去整体的精度,我相信TIFF和BMP也支持。 PVRTC是PowerVR专用的,所以它不是苹果专用的,但它也不是完全平台独立的,并且被专门devise成有损压缩,在GPU上很lessinput的情况下解压缩是微不足道的。 你通常会增加你的纹理分辨率来改善每像素的低位数。

在这里输入图像说明

你应该使用libpng来加载没有预乘颜色的PNG。

它是用C编写的,应该为iOS编译。

我有类似的问题与Android,也不得不使用第三方库加载非预乘色PNG文件。

这是试图回答我自己的问题。

不能加载非预乘的.png文件。

选项kCGImageAlphaLast是一个有效的选项,但不提供CGBitmapContextCreate ( reference )的有效组合。 然而,它是CGImageRef的一个有效选项。

上面提到的XCode中的构build设置COMPRESS_PNG_FILES作用是将.png文件转换为其他文件格式,并将通道rgb与( 引用 )相乘。 我希望禁用此选项将使我可以达到我的实际.png文件中的频道数据。 但是我不确定这是否可能。 以下示例尝试以低级别访问.png数据,如CGImageRef

 void test_cgimage(const char* path) { CGDataProviderRef dataProvider = CGDataProviderCreateWithFilename(path); CGImageRef cg_image = CGImageCreateWithPNGDataProvider(dataProvider, NULL, NO, kCGRenderingIntentDefault); CGImageAlphaInfo info = CGImageGetAlphaInfo(cg_image); switch (info) { case kCGImageAlphaNone: printf("kCGImageAlphaNone\n"); break; case kCGImageAlphaPremultipliedLast: printf("kCGImageAlphaPremultipliedLast\n"); break; case kCGImageAlphaPremultipliedFirst: printf("kCGImageAlphaPremultipliedFirst\n"); break; case kCGImageAlphaLast: printf("kCGImageAlphaLast\n"); break; case kCGImageAlphaFirst: printf("kCGImageAlphaFirst\n"); break; case kCGImageAlphaNoneSkipLast: printf("kCGImageAlphaNoneSkipLast\n"); break; case kCGImageAlphaNoneSkipFirst: printf("kCGImageAlphaNoneSkipFirst\n"); break; default: break; } } 

其中给出“kCGImageAlphaPrepultipliedLast”与禁用COMPRESS_PNG_FILES 。 所以我觉得iOS总是转换.png文件,即使在运行时。

不是100%你想要什么,但我解决了使用这种方法的问题:将alpha通道放入一个单独的黑色和白色PNG,并保存原始png没有alpha。 所以采取的空间大致相同。 然后在我的纹理加载器加载两个图像,并结合成一个纹理。

我知道这只是一个解决方法,但至less它给出了正确的结果。 是的,这是非常烦人的,iOS不允许你加载PNG纹理没有预乘alpha。