Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to find PixelFormat for decoded bitmap using SkiaSharp

In System.Drawing we retrieve the PixelFormat from Image object, but SkiaSharp.SkImage does not provide API to find the PixelFormat of decoded image. Whether it has any other workaround to find the PixelFormat of decoded images and also how can we create Image with PixelFormat value as equivalent of System.Drawing.Image

like image 812
Parthi Avatar asked Dec 26 '17 10:12

Parthi


1 Answers

Short answer

There is this aspect, but it is split into two types: SKColorType and SKAlphaType. These properties are found on the SKImageInfo type.

SKImage vs SKBitmap

Before I share the real answer, a brief intro to the differences between the two image types.

SKBitmap (raster only)

A SKBitmap is a raster-only graphic, this means that the color and alpha type information is readily available. This is in the Info property.

SKBitmap bitmap = ...;
SKColorType colorType = bitmap.Info.ColorType;
SKAlphaType alphaType = bitmap.Info.AlphaType;

SKImage (raster or texture)

SKImage is a bit different in that it may not actually be a raster bitmap. An SKImage could be a GPU object, such as a OpenGL Texture. As such, this color type does not apply. So in your case where you are using raster bitmaps, use SKBitmap instead of SKImage.

However, there is still hope with SKImage, because a raster-based SKImage actually uses a SKBitmap under the hood. If you know your SKImage is a raster image, then you can use the PeekPixels() method to get a SKPixmap object which will also have an Info property. SKPixmap is a thin type that contains a reference to the image data, the info and a few other properties.

To check if a certain SKImage is a texture image or a raster image, you can use the IsTextureBacked property.

SKImage image = ...;
if (!image.IsTextureBacked) {
    using (SKPixmap pixmap = image.PeekPixels()) {
        SKColorType colorType = pixmap.ColorType;
        SKAlphaType alphaType = pixmap.AlphaType;
    }
} else {
    // this is a texture on the GPU and can't be determined easily
}

Longer answer

So now the longer answer... The SKColorType and SKAlphaType types together form the equivalent of the PixelFormat.

For example:

  • PixelFormat.Format16bppRgb565 is equivalent to:
    SKColorType.Rgb565 and SKAlphaType.Opaque
  • PixelFormat.Format32bppArgb is equivalent to:
    SKColorType.Rgba8888 (or SKColorType.Bgra8888 on Windows) and SKAlphaType.Unpremul
  • PixelFormat.Format32bppPArgb is equivalent to:
    SKColorType.Rgba8888 (or SKColorType.Bgra8888 on Windows) and SKAlphaType.Premul

The main difference between Rgba8888 and Bgra8888 is the platform that the app is running on. Typically, you would check the color type against the SKImageInfo.PlatformColorType as this will know what the native color type is supposed to be.

like image 54
Matthew Avatar answered Oct 17 '22 10:10

Matthew