Previously, I’ve described a basic architecture for accessing and manipulating pixel data from a Xamarin.Forms project. A Xamarin.Forms PCL project defines the IBitmap interface, which specifies the operations that must be implemented in each platform-specific project to access and manipulate pixel data. I then explained the operation of the Bitmap class in the Xamarin.Forms iOS project, which implements the IBitmap interface.
Over Christmas I revisited my iOS implementation of the Bitmap class and discovered that I had redundant copies of pixel data from unmanaged memory to managed memory. In particular, the pixel data did not need placing into unmanaged memory in the first place. This blog post will outline the improvements I’ve made to the Bitmap class on iOS.
Disclaimer: The code featured here is alpha code, so all the usual caveats apply.
The following code shows the revised Bitmap class implementation on iOS:
The big changes are to the ToPixelArray and ToImage methods. Previously the ToPixelArray method placed the pixel data into unmanaged memory, before copying it to managed memory and freeing the unmanaged memory. This was redundant and wasteful, and I was able to eliminate it once I discovered that one of the CGBitmapContext constructor overloads allowed the placing of pixel data direct into managed memory.
Similarly, the ToImage method also contained a redundant operation in that previously a new UIImage was created by creating a CGDataProvider and a CGImage, with the UIImage then being created from the CGImage instance. This has now been slightly streamlined to creating a new CGBitmapContext, with the UIImage then being created from the CGBitmapContext instance.
I also explored options for increasing the performance of the TransformImage method, including parallelism and discovered that the performance of the method is not presenting a bottleneck.
This blog post has revisited how to access and manipulate pixel data in a Xamarin.Forms iOS project, by more efficiently implementing the Bitmap class. A redundant copying of pixel data from unmanaged memory to managed memory has been eliminated, and in doing so has removed a potential source of memory leaks. In addition, following pixel manipulation, the creation of a new UIImage has been slightly streamlined.