iOS的Monotouch中透明的PNG

我有一个问题,我在这里发布之前一直在寻找解决scheme的月份。

问题是关于Monotouch中的透明PNG文件:

我正在尝试在上下文中加载透明的PNG ,以读取和写入像素颜色 。 我正在使用下面的代码,它与非透明的PNG完美配合。 (我也包括其他几个尝试获得正确结果的尝试)

透明PNG的问题似乎是,我必须在预乘alpha 字符CGImageAlphaInfo.PremultipliedLast )的上下文中加载图像。 这会导致RGB值在上下文中加载时从其原始值更改。

我试图用CGImageAlphaInfo.Last创build一个上下文(这在理论上是正确的),但是我得到一个exception(不可接受的参数组合)。

我想用CoreImage尝试,但这会限制我们的用户到iOS 5或更高版本,我决定这是不能接受的。

我迫切需要find一种方法来获取和设置透明的PNG像素,因为我正在创build一个需要处理透明PNG的跨平台软件(iPhone,iPad,Mac,使用MonoMac和Windows)。

任何帮助将不胜感激。 谢谢!

using System; using System.Collections.Generic; using System.Linq; using MonoTouch.Foundation; using MonoTouch.UIKit; using System.Drawing; using MonoTouch.CoreGraphics; using System.Runtime.InteropServices; using MonoTouch.CoreImage; namespace TestPNG { // The UIApplicationDelegate for the application. This class is responsible for launching the // User Interface of the application, as well as listening (and optionally responding) to // application events from iOS. [Register ("AppDelegate")] public partial class AppDelegate : UIApplicationDelegate { // class-level declarations UIWindow window; TestPNGViewController viewController; // // This method is invoked when the application has loaded and is ready to run. In this // method you should instantiate the window, load the UI into it and then make the window // visible. // // You have 17 seconds to return from this method, or iOS will terminate your application. // public override bool FinishedLaunching (UIApplication app, NSDictionary options) { window = new UIWindow (UIScreen.MainScreen.Bounds); viewController = new TestPNGViewController (); window.RootViewController = viewController; window.MakeKeyAndVisible (); UIImage _CarrierImage = UIImage.FromFile ("Blue50.png"); int width = _CarrierImage.CGImage.Width; int height = _CarrierImage.CGImage.Height; CGImage cg = _CarrierImage.CGImage; Console.WriteLine ("width: " + width.ToString ("000") + ", height: " + height.ToString ("000")); Console.WriteLine ("BitsPerComponent: " + cg.BitsPerComponent.ToString ()); Console.WriteLine ("BytesPerRow: " + cg.BytesPerRow.ToString ()); Console.WriteLine ("BitsPerPixel: " + cg.BitsPerPixel.ToString ()); Console.WriteLine ("ColorSpace: " + cg.ColorSpace.ToString ()); Console.WriteLine ("For image Blue0.png should have values: R:0, G:0, B:255, A: 0"); Console.WriteLine ("For image Blue50.png should have values: R:0, G:0, B:255, A: 128"); Console.WriteLine ("For image Blue100.png should have values: R:0, G:0, B:255, A: 255"); // METHOD 1 // CGDataProvider p = CGDataProvider.FromFile("Blue50.png"); // CGImage cgimg = CGImage.FromPNG(p,null,false,CGColorRenderingIntent.Default); // UIImage _CarrierImage = new UIImage(cgimg); // METHOD 2 // NSData dt = _CarrierImage.AsPNG(); // IntPtr bitmapData = dt.Bytes; // // Console.WriteLine("Length: " + dt.Length.ToString()); // for (int i=0; i < dt.Length; i++) // { // Console.WriteLine("i: " + i.ToString("00") + ", byte: " + dt[i].ToString()); // } // // METHOD 3 // UIGraphics.BeginImageContext (_CarrierImage.Size); // CGContext ctx = UIGraphics.GetCurrentContext (); // ctx.DrawImage (new RectangleF (0, 0, _CarrierImage.Size.Width, _CarrierImage.Size.Height), _CarrierImage.CGImage); // IntPtr dt = ctx.Handle; // for (int i=0; i < 100; i++) // { // Console.WriteLine("i: " + i.ToString("00") + ", byte: " + GetByte(i, dt).ToString ()); // } // UIGraphics.EndImageContext(); // METHOD 4 int bitmapBytesPerRow = width * 4; IntPtr bitmapData = Marshal.AllocHGlobal (width * 4 * height); CGBitmapContext ctxt = new CGBitmapContext (bitmapData, width, height, cg.BitsPerComponent, bitmapBytesPerRow, cg.ColorSpace, CGImageAlphaInfo.PremultipliedLast); RectangleF rect = new RectangleF (0.0f, 0.0f, width, height); ctxt.DrawImage (rect, _CarrierImage.CGImage); IntPtr dt = ctxt.Data; Console.WriteLine ("R: " + GetByte (0, dt).ToString ()); Console.WriteLine ("G: " + GetByte (1, dt).ToString ()); Console.WriteLine ("B: " + GetByte (2, dt).ToString ()); Console.WriteLine ("A: " + GetByte (3, dt).ToString ()); return true; } unsafe byte GetByte (int offset, IntPtr buffer) { byte* bufferAsBytes = (byte*)buffer; return bufferAsBytes [offset]; } } }