source/SkiaSharp.Views/SkiaSharp.Views.WPF/WPFExtensions.cs (107 lines of code) (raw):
using System;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
namespace SkiaSharp.Views.WPF
{
public static class WPFExtensions
{
// 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.Width, rect.Height);
}
// 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);
}
// 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
var info = new SKImageInfo(skiaImage.Width, skiaImage.Height);
var bitmap = new WriteableBitmap(info.Width, info.Height, 96, 96, PixelFormats.Pbgra32, null);
bitmap.Lock();
// copy
using (var pixmap = new SKPixmap(info, bitmap.BackBuffer, bitmap.BackBufferStride))
{
skiaImage.ReadPixels(pixmap, 0, 0);
}
bitmap.AddDirtyRect(new Int32Rect(0, 0, info.Width, info.Height));
bitmap.Unlock();
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 BitmapSource 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 BitmapSource 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 void ToSKPixmap(this BitmapSource 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)
{
var info = pixmap.Info;
var converted = new FormatConvertedBitmap(bitmap, PixelFormats.Pbgra32, null, 0);
converted.CopyPixels(new Int32Rect(0, 0, info.Width, info.Height), pixmap.GetPixels(), info.BytesSize, info.RowBytes);
}
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();
tempImage.ReadPixels(pixmap, 0, 0);
}
}
}
}