如何加载一个PNG文件没有alpha预乘在IOS?

我正在制作一个游戏,其中我使用alpha值,在某些情况下用于透明度,其他用于遮挡,在另一些情况下用于HDR。

我正在加载像这样的图像(这是MonoTouch,但Objective-C可以很容易地转换为C#):

CGImage bitmap = new UIImage(resourcePath).CGImage; width = bitmap.Width; height = bitmap.Height; IntPtr pixels = Marshal.AllocHGlobal(bitmap.Width * bitmap.Height * 4); using (var context = new CGBitmapContext(pixels, bitmap.Width, bitmap.Height, 8, bitmap.Width * 4, CGColorSpace.CreateDeviceRGB(), CGImageAlphaInfo.PremultipliedLast)) { var dest = new RectangleF(0, 0, bitmap.Width, bitmap.Height); context.ClearRect(dest); context.DrawImage(dest, bitmap); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, width, height, 0, PixelFormat.Rgba, PixelType.UnsignedByte, pixels); } Marshal.FreeHGlobal(pixels); bitmap.Dispose(); 

但是,这通过将它们预先乘以alpha值来屠宰我所有的像素。

这背后的原因是,我用CGImageAlphaInfo.PremultipliedLast创建CGImageAlphaInfo.PremultipliedLast 。 我尝试使用CGImageAlphaInfo.Last ,但创建上下文失败。 核心graphics只适用于预乘alpha,如下所述。

我尝试使用CGDataProviderCopyData ,以及pngcs 。 但是,他们都简单地解码位图,而不是将像素转换为RGBA,这是存储8位,24位PNG或索引PNG时相关的(我有很多这些,这是结果优化我的PNG文件的大小)。

所以我迷路了 我需要一种方法来解码PNG文件,以便将它们转换为RGBA, 而不用通过alpha值预乘我的颜色。 那是过分的要求? GDI,GDI +,System.Drawing,DirectX,Mono for Android以及PSM都可以做到这一点…

另外,为什么iOS开发必须如此挑剔?

我尝试使用CGDataProviderCopyData,以及pngcs。 但是,它们都只是对位图进行解码,而不是将像素转换为RGBA,这与存储8位,24位PNG或索引PNG时相关。

你看看ImageLineHelper.Palette2rgb()吗? 你缺less什么function?

(免责声明:我是PngCs开发者)

C代码:

 CFURLRef url = CFURLCreateWith...("path/to/file.png"); CGDataProviderRef dp = CGDataProviderCreateWithURL(url); CGImageRef img = CGImageCreateWithPNGDataProvider(dp, nil, NO, kCGRenderingIntentDefault); CFDataRef data = CGDataProviderCopyData(CGImageGetDataProvider(img)); UInt8* pixelData = CFDataGetBytePtr(data); // not premultiplied RGBA8 data // use pixelData CFRelease(data); CGImageRelease(img); CGDataProviderRelease(dp); CFRelease(url);