source/SkiaSharp.Views/SkiaSharp.Views.WinUI/UWPExtensions.cs (132 lines of code) (raw):
using System;
using Windows.Foundation;
using Windows.UI;
using Windows.Storage.Streams;
#if !HAS_UNO
using SkiaSharp.Views.WinUI.Native;
#endif
#if WINDOWS || WINUI
using Microsoft.UI.Xaml.Media.Imaging;
#else
using Windows.UI.Xaml.Media.Imaging;
#endif
#if WINDOWS || WINUI
namespace SkiaSharp.Views.Windows
#else
namespace SkiaSharp.Views.UWP
#endif
{
#if WINDOWS
public static class WindowsExtensions
#else
public static class UWPExtensions
#endif
{
// Point
public static SKPoint ToSKPoint(this Point point)
{
return new SKPoint((float)point.X, (float)point.Y);
}
public static Point ToPoint(this SKPoint point)
{
return new Point(point.X, point.Y);
}
// Rect
public static SKRect ToSKRect(this Rect rect)
{
return new SKRect((float)rect.Left, (float)rect.Top, (float)rect.Right, (float)rect.Bottom);
}
public static Rect ToRect(this SKRect rect)
{
return new Rect(rect.Left, rect.Top, rect.Right, rect.Bottom);
}
// Size
public static SKSize ToSKSize(this Size size)
{
return new SKSize((float)size.Width, (float)size.Height);
}
public static Size ToSize(this SKSize size)
{
return new Size(size.Width, size.Height);
}
// Color
public static SKColor ToSKColor(this Color color)
{
return new SKColor(color.R, color.G, color.B, color.A);
}
public static Color ToColor(this SKColor color)
{
return Color.FromArgb(color.Alpha, color.Red, color.Green, color.Blue);
}
#if !HAS_UNO
// WriteableBitmap
public static WriteableBitmap ToWriteableBitmap(this SKPicture picture, SKSizeI dimensions)
{
using (var image = SKImage.FromPicture(picture, dimensions))
{
return image?.ToWriteableBitmap();
}
}
public static WriteableBitmap ToWriteableBitmap(this SKImage skiaImage)
{
// TODO: maybe keep the same color types where we can, instead of just going to the platform default
// TODO: remove this as it is old/default logic
//using (var tempImage = SKImage.Create(info))
//using (var pixmap = tempImage.PeekPixels())
//using (var data = SKData.Create(pixmap.GetPixels(), info.BytesSize))
//{
// skiaImage.ReadPixels(pixmap, 0, 0);
// using (var stream = bitmap.PixelBuffer.AsStream())
// {
// data.SaveTo(stream);
// }
//}
var info = new SKImageInfo(skiaImage.Width, skiaImage.Height);
var bitmap = new WriteableBitmap(info.Width, info.Height);
using (var pixmap = new SKPixmap(info, bitmap.GetPixels()))
{
skiaImage.ReadPixels(pixmap, 0, 0);
}
bitmap.Invalidate();
return bitmap;
}
public static WriteableBitmap ToWriteableBitmap(this SKBitmap skiaBitmap)
{
using var pixmap = skiaBitmap.PeekPixels();
using var image = SKImage.FromPixels(pixmap);
var wb = image.ToWriteableBitmap();
GC.KeepAlive(skiaBitmap);
return wb;
}
public static WriteableBitmap ToWriteableBitmap(this SKPixmap pixmap)
{
using (var image = SKImage.FromPixels(pixmap))
{
return image.ToWriteableBitmap();
}
}
public static SKBitmap ToSKBitmap(this WriteableBitmap bitmap)
{
// TODO: maybe keep the same color types where we can, instead of just going to the platform default
var info = new SKImageInfo(bitmap.PixelWidth, bitmap.PixelHeight);
var skiaBitmap = new SKBitmap(info);
using (var pixmap = skiaBitmap.PeekPixels())
{
bitmap.ToSKPixmap(pixmap);
}
return skiaBitmap;
}
public static SKImage ToSKImage(this WriteableBitmap bitmap)
{
// TODO: maybe keep the same color types where we can, instead of just going to the platform default
var info = new SKImageInfo(bitmap.PixelWidth, bitmap.PixelHeight);
var image = SKImage.Create(info);
using (var pixmap = image.PeekPixels())
{
bitmap.ToSKPixmap(pixmap);
}
return image;
}
public static bool ToSKPixmap(this WriteableBitmap bitmap, SKPixmap pixmap)
{
// TODO: maybe keep the same color types where we can, instead of just going to the platform default
if (pixmap.ColorType == SKImageInfo.PlatformColorType)
{
using var image = SKImage.FromPixels(pixmap.Info, bitmap.GetPixels());
return image.ReadPixels(pixmap, 0, 0);
}
else
{
// we have to copy the pixels into a format that we understand
// and then into a desired format
// TODO: we can still do a bit more for other cases where the color types are the same
using (var tempImage = bitmap.ToSKImage())
{
return tempImage.ReadPixels(pixmap, 0, 0);
}
}
}
internal static IntPtr GetPixels(this WriteableBitmap bitmap) =>
bitmap.PixelBuffer.GetByteBuffer();
internal static IntPtr GetByteBuffer(this IBuffer buffer) =>
(IntPtr)BufferExtensions.GetByteBuffer(buffer);
#endif
}
}