Search code examples
c#xamarinxamarin.formsskiasharp

What is the difference between `InstallPixels()` and `SetPixels()` in `SkiaSharp.SKBitmap`?


I'm not clear on how SKBitmap.InstallPixels() and SKBitmap.SetPixels() work. Here's the documentation for one of each method (there are several method overloads):

// Summary:
//     Installs the specified pixels into the bitmap.
//
// Parameters:
//   info:
//     The image information describing the pixels.
//
//   pixels:
//     The pixels to install.
//
// Returns:
//     Returns true on success, or false on failure. If there was an error, the bitmap
//     will be set to empty.
public bool InstallPixels(SKImageInfo info, IntPtr pixels);

// Summary:
//     Replaces the current pixel address for the bitmap.
//
// Parameters:
//   pixels:
//     The new pixel address.
public void SetPixels(IntPtr pixels);

My guess is that InstallPixels() copies the data from the IntPtr to a local byte array, whereas SetPixels() makes the passed IntPtr the byte array to use.

If my assumption is correct, does that mean that if I want to use InstallPixels() I need to first call TryAllocPixels() to create the internal byte array? If I want to use SetPixels(), do I need to manually dispose of the byte array or does it get disposed when the SKBitmap is disposed?


Solution

  • So, this is probably two years too late to be useful, but I've found this question popping up in my searches once again so I'll furnish an answer in the hopes it might be useful for someone.

    • InstallPixels is capable of completely changing the image. It takes as arguments either a separate SkImageInfo and pointer to a pixel array, or an SkPixmap which bundles the image info and pixel array pointer together. Because it can update the image info, InstallPixels can be used to change the size, pixel format or colour space of an image. You can freely use InstallPixels on an empty image created with new SkBitmap().

      InstallPixels also optionally takes a delegate that will be invoked on the supplied pixel array pointer when the bitmap is disposed of. This can be used to do things like unpin arrays, release GC handles, free memory on the non-GC heap and so on. This lets you pass ownership of a memory buffer to an SkBitmap instance, and not have to worry about keeping it alive or cleaning it up yourself.

    • By comparison, SetPixels takes only a pointer to a pixel array. You cannot change the size, pixel format or colour space of the bitmap, so the pointed-to array should have the same size and layout as the bitmap you're modifying.

      SetPixels doesn't take a release delegate. This means that responsibility for keeping the pointed-to pixels valid for the lifetime of the bitmap and then tidying them up when no longer needed (eg. by unpinning, releasing GC handles or freeing non-GC memory) remains with your code.

    Under normal circumstances, I suspect that InstallPixels is the method you probably want to use. SetPixels can only do a subset of what InstallPixels can, and requires you to deal with memory and lifetime issues yourself.