0
votes

(I'm working on a Xamarin.Forms project targeting iOS, but I get the feeling I need to use monotouch to accomplish my goals.)

I have an array I get from a function, and this array represents some bitmap data I would like to save and display later. I've been looking at the documentation, and I don't see a path from bytes to bitmap to file that is as clear as I'd expect. In WinForms, I'd create a System.Drawing.Bitmap, then use the Save() method. In Xamarin for Android, Android.Graphics.Bitmap has a Compress() method that lets me output to a stream. I'm having trouble figuring out what the equivalent in Xamarin iOS would be.

The pixel data is 32 bits per pixel, 8 bits per component, ARGB. I've got as far as figuring out I can create a CGImage from that, currently via a CGBitmapContext. I can get a UIImage from that, but the next clear method is UIImage.SaveToPhotoStream() which isn't what I want to do. I see AsPng() returns an NSData, and that seems like a way to go. I don't quite have it working yet (because for some reason the provider decided to output int[] instead of byte[]) but I'm curious: is there an easier way to go from raw pixel data to a PNG file?

2

2 Answers

3
votes

You can use ImageIO that gives you a little bit more control over what to serialize.

You still need to get yourself a CGImage to work with though.

Use one of the three CGImageDestination.Create overloads to select the kind of output you want to produce (save to a NSMutableData object, to an NSUrl, or to your own data provider), add the image, and then close the CGImageDestination.

Something like this:

var storage = new NSMutableData ()
var dest = CGImageDestination.Create (storage, MobileCoreServices.UTType.PNG, imageCount: 1);
dest.AddImage (yourImage);
dest.Close ();   // This saves the data

You can change the parameter in Create for imageCount to other numbers if you want to create images that have multiple frames, in that case, you will also call AddImage repeatedly.

0
votes

If you are looking to write the image to a file then it would be quite simple:

var bytes = image.AsPNG().ToArray();
await stream.WriteAsync(bytes, 0, bytes.Length);