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); }
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); }