public static Bitmap ToBitmap(this SKBitmap skiaBitmap) { // TODO: replace all this with a SKBitmap.PeekPixels // and call the overload var info = skiaBitmap.Info; // try keep the pixel format var config = Bitmap.Config.Argb8888; switch (info.ColorType) { case SKColorType.Alpha8: config = Bitmap.Config.Alpha8; break; case SKColorType.Rgb565: config = Bitmap.Config.Rgb565; break; case SKColorType.Argb4444: config = Bitmap.Config.Argb4444; break; } var bmp = Bitmap.CreateBitmap(info.Width, info.Height, config); var ptr = bmp.LockPixels(); var success = true; if (config == Bitmap.Config.Argb8888 && info.ColorType != SKColorType.Rgba8888) { // wrap the pixels so we can copy in one action var tempInfo = new SKImageInfo(info.Width, info.Height, SKColorType.Rgba8888, SKAlphaType.Premul); // TODO: replace this with a SKPixmap.ReadPixels var tempBmp = new SKBitmap(); tempBmp.InstallPixels(tempInfo, ptr); success = skiaBitmap.CopyTo(tempBmp, SKColorType.Rgba8888); tempBmp.Reset(); tempBmp.Dispose(); } else { // must multiply HEIGHT * rowBytes to get total number of bytes success = skiaBitmap.CopyPixelsTo(ptr, bmp.Height * bmp.RowBytes); } bmp.UnlockPixels(); if (!success) { bmp.Recycle(); bmp.Dispose(); bmp = null; } return(bmp); }