Example #1
0
        public SKBitmap ImageBufferToSKBitmap(IImageBuffer imageBuffer)
        {
            if (imageBuffer == null)
            {
                return(null);
            }

            imageBuffer = imageBuffer.ToU8();

            SKBitmap     bitmap     = null;
            SKColorSpace colorSpace = null;

            if (imageBuffer.Format.ColorSpace == ColorSpace.Srgb)
            {
                colorSpace = SKColorSpace.CreateSrgb();
            }
            else if (imageBuffer.Format.ColorSpace == ColorSpace.LinearRgb)
            {
                colorSpace = SKColorSpace.CreateSrgbLinear();
            }

            try
            {
                // for RGBA-images
                if (imageBuffer.Format.PixelType == PixelType.U8C3)
                {
                    // convert to 32bpp
                    var src = imageBuffer is I <byte>?((I <byte>)imageBuffer).Data.Buffer : imageBuffer.ToByteArray();
                    var dst = new byte[imageBuffer.Height * imageBuffer.Width * 4];
                    int i = 0, j = 0;
                    while (i < dst.Length)
                    {
                        dst[i + 0] = src[j + 0];
                        dst[i + 1] = src[j + 1];
                        dst[i + 2] = src[j + 2];
                        dst[i + 3] = 0xff;
                        i         += 4;
                        j         += 3;
                    }

                    SKColorType colorType = SKColorType.Rgba8888;
                    switch (imageBuffer.Format.PixelChannels)
                    {
                    case PixelChannels.Rgb:
                        colorType = SKColorType.Rgba8888;
                        break;

                    case PixelChannels.Bgra:
                        colorType = SKColorType.Bgra8888;
                        break;
                    }

                    using (var pinnedImage = new Utilities.PinnedGCHandle(dst))
                    {
                        var sourceInfo = new SKImageInfo(imageBuffer.Width, imageBuffer.Height, colorType, SKAlphaType.Opaque);
                        if (colorSpace != null)
                        {
                            sourceInfo.ColorSpace = colorSpace;
                        }
                        bitmap = new SKBitmap();
                        Debug.Assert(sourceInfo.RowBytes == imageBuffer.Width * 4);
                        if (!bitmap.InstallPixels(sourceInfo, pinnedImage.Pointer))
                        {
                            throw new Exception("InstallPixels poperation of Skia bitmap failed.");
                        }
                    }
                }
                // for RGBA-images
                else if (imageBuffer.Format.PixelType == PixelType.U8C4)
                {
                    // try direct copy
                    using (var pinnedImage = imageBuffer.Pin())
                    {
                        SKAlphaType alphaType = SKAlphaType.Unknown;
                        SKColorType colorType = SKColorType.Rgba8888;
                        switch (imageBuffer.Format.PixelChannels)
                        {
                        case PixelChannels.Rgbx:
                            alphaType = SKAlphaType.Opaque;
                            colorType = SKColorType.Rgba8888;
                            break;

                        case PixelChannels.Rgba:
                            alphaType = SKAlphaType.Unpremul;
                            colorType = SKColorType.Rgba8888;
                            break;

                        case PixelChannels.Bgrx:
                            alphaType = SKAlphaType.Opaque;
                            colorType = SKColorType.Bgra8888;
                            break;

                        case PixelChannels.Bgra:
                            alphaType = SKAlphaType.Unpremul;
                            colorType = SKColorType.Bgra8888;
                            break;
                        }
                        var sourceInfo = new SKImageInfo(imageBuffer.Width, imageBuffer.Height, colorType, alphaType);
                        Debug.Assert(sourceInfo.RowBytes == imageBuffer.Width * 4);
                        if (colorSpace != null)
                        {
                            sourceInfo.ColorSpace = colorSpace;
                        }
                        bitmap = new SKBitmap();
                        if (!bitmap.InstallPixels(sourceInfo, pinnedImage.Pointer))
                        {
                            throw new Exception("InstallPixels poperation of Skia bitmap failed.");
                        }
                    }
                }
                // for gray-scale
                else if (imageBuffer.Format.PixelType == PixelType.U8C1)
                {
                    // try direct copy
                    using (var pinnedImage = imageBuffer.Pin())
                    {
                        var sourceInfo = new SKImageInfo(imageBuffer.Width, imageBuffer.Height, SKColorType.Gray8);
                        Debug.Assert(sourceInfo.RowBytes == imageBuffer.Width);
                        bitmap = new SKBitmap();
                        if (!bitmap.InstallPixels(sourceInfo, pinnedImage.Pointer))
                        {
                            throw new Exception("InstallPixels poperation of Skia bitmap failed.");
                        }
                    }
                }
                else
                {
                    throw new Exception("PixelFormat not yet implemented for preview image.");
                }

                SKBitmap result = bitmap;
                bitmap     = null;
                colorSpace = null;
                return(result);
            }
            finally
            {
                if (bitmap != null)
                {
                    bitmap.Dispose();
                    if (colorSpace != null)
                    {
                        colorSpace.Dispose();
                    }
                }
            }
        }