예제 #1
0
        public bool CopyTo(SKBitmap destination, SKColorType colorType)
        {
            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            if (!CanCopyTo(colorType))
            {
                return(false);
            }

            var srcPM = PeekPixels();

            if (srcPM == null)
            {
                return(false);
            }

            var dstInfo = srcPM.Info.WithColorType(colorType);

            switch (colorType)
            {
            case SKColorType.Rgb565:
                // CopyTo() is not strict on alpha type. Here we set the src to opaque to allow
                // the call to ReadPixels() to succeed and preserve this lenient behavior.
                if (srcPM.AlphaType != SKAlphaType.Opaque)
                {
                    srcPM = srcPM.WithAlphaType(SKAlphaType.Opaque);
                }
                dstInfo.AlphaType = SKAlphaType.Opaque;
                break;

            case SKColorType.RgbaF16:
                // The caller does not have an opportunity to pass a dst color space.
                // Assume that they want linear sRGB.
                dstInfo.ColorSpace = SKColorSpace.CreateSrgbLinear();
                if (srcPM.ColorSpace == null)
                {
                    // We can't do a sane conversion to F16 without a dst color space.
                    // Guess sRGB in this case.
                    srcPM = srcPM.WithColorSpace(SKColorSpace.CreateSrgb());
                }
                break;
            }

            var tmpDst = new SKBitmap();

            if (!tmpDst.TryAllocPixels(dstInfo))
            {
                return(false);
            }

            var dstPM = tmpDst.PeekPixels();

            if (dstPM == null)
            {
                return(false);
            }

            // We can't do a sane conversion from F16 without a src color space. Guess sRGB in this case.
            if (srcPM.ColorType == SKColorType.RgbaF16 && dstPM.ColorSpace == null)
            {
                dstPM = dstPM.WithColorSpace(SKColorSpace.CreateSrgb());
            }

            // ReadPixels does not yet support color spaces with parametric transfer functions. This
            // works around that restriction when the color spaces are equal.
            if (colorType != SKColorType.RgbaF16 && srcPM.ColorType != SKColorType.RgbaF16 && dstPM.ColorSpace == srcPM.ColorSpace)
            {
                dstPM = dstPM.WithColorSpace(null);
                srcPM = srcPM.WithColorSpace(null);
            }

            if (!srcPM.ReadPixels(dstPM))
            {
                return(false);
            }

            destination.Swap(tmpDst);

            return(true);
        }
예제 #2
0
        public bool CopyTo(SKBitmap destination, SKColorType colorType)
        {
            // TODO: instead of working on `destination` directly, we should
            //       create a temporary bitmap and then inject the data

            if (destination == null)
            {
                throw new ArgumentNullException(nameof(destination));
            }

            if (!CanCopyTo(colorType))
            {
                return(false);
            }

            SKPixmap srcPM = PeekPixels();

            if (srcPM == null)
            {
                return(false);
            }

            SKImageInfo dstInfo = srcPM.Info.WithColorType(colorType);

            switch (colorType)
            {
            case SKColorType.Rgb565:
                // CopyTo() is not strict on alpha type. Here we set the src to opaque to allow
                // the call to ReadPixels() to succeed and preserve this lenient behavior.
                if (srcPM.AlphaType != SKAlphaType.Opaque)
                {
                    srcPM = srcPM.WithAlphaType(SKAlphaType.Opaque);
                }
                dstInfo.AlphaType = SKAlphaType.Opaque;
                break;

            case SKColorType.RgbaF16:
                // The caller does not have an opportunity to pass a dst color space.
                // Assume that they want linear sRGB.
                dstInfo.ColorSpace = SKColorSpace.CreateSrgbLinear();
                if (srcPM.ColorSpace == null)
                {
                    // We can't do a sane conversion to F16 without a dst color space.
                    // Guess sRGB in this case.
                    srcPM = srcPM.WithColorSpace(SKColorSpace.CreateSrgb());
                }
                break;
            }

            destination.Reset();              // TODO: is this needed?
            if (!destination.TryAllocPixels(dstInfo, colorType == SKColorType.Index8 ? ColorTable : null))
            {
                return(false);
            }

            SKPixmap dstPM = destination.PeekPixels();

            if (dstPM == null)
            {
                return(false);
            }

            // We can't do a sane conversion from F16 without a src color space. Guess sRGB in this case.
            if (srcPM.ColorType == SKColorType.RgbaF16 && dstPM.ColorSpace == null)
            {
                dstPM = dstPM.WithColorSpace(SKColorSpace.CreateSrgb());
            }

            // ReadPixels does not yet support color spaces with parametric transfer functions. This
            // works around that restriction when the color spaces are equal.
            if (colorType != SKColorType.RgbaF16 && srcPM.ColorType != SKColorType.RgbaF16 && dstPM.ColorSpace == srcPM.ColorSpace)
            {
                dstPM = dstPM.WithColorSpace(null);
                srcPM = srcPM.WithColorSpace(null);
            }

            if (!srcPM.ReadPixels(dstPM))
            {
                return(false);
            }

            return(true);
        }