diff --git a/HPPH.Benchmark/HPPH.Benchmark.csproj b/HPPH.Benchmark/HPPH.Benchmark.csproj
index 1147eb0..40c261e 100644
--- a/HPPH.Benchmark/HPPH.Benchmark.csproj
+++ b/HPPH.Benchmark/HPPH.Benchmark.csproj
@@ -13,6 +13,7 @@
+
diff --git a/HPPH.SkiaSharp/HPPH.SkiaSharp.csproj b/HPPH.SkiaSharp/HPPH.SkiaSharp.csproj
new file mode 100644
index 0000000..c2837f1
--- /dev/null
+++ b/HPPH.SkiaSharp/HPPH.SkiaSharp.csproj
@@ -0,0 +1,18 @@
+
+
+
+ net8.0
+ enable
+ enable
+ true
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/HPPH.SkiaSharp/ImageExtension.cs b/HPPH.SkiaSharp/ImageExtension.cs
new file mode 100644
index 0000000..9ebd9de
--- /dev/null
+++ b/HPPH.SkiaSharp/ImageExtension.cs
@@ -0,0 +1,32 @@
+// ReSharper disable InconsistentNaming
+
+using System.Runtime.InteropServices;
+using System.Runtime.Versioning;
+using SkiaSharp;
+
+namespace HPPH.SkiaSharp;
+
+public static class ImageExtension
+{
+ public static unsafe SKImage ToSKImage(this IImage image) => SKImage.FromBitmap(image.ToSKBitmap());
+
+ public static unsafe SKBitmap ToSKBitmap(this IImage image)
+ {
+ SKBitmap bitmap = new(image.Width, image.Height, SKColorType.Bgra8888, SKAlphaType.Unpremul);
+ nint pixelPtr = bitmap.GetPixels(out nint length);
+ image.ConvertTo().CopyTo(new Span((void*)pixelPtr, (int)length));
+
+ return bitmap;
+ }
+
+ public static byte[] ToPng(this IImage image)
+ {
+ using SKImage skImage = image.ToSKImage();
+ return skImage.Encode(SKEncodedImageFormat.Png, 100).ToArray();
+ }
+
+ public static IImage ToImage(this SKImage skImage) => SKBitmap.FromImage(skImage).ToImage();
+
+ public static IImage ToImage(this SKBitmap bitmap)
+ => Image.Create(MemoryMarshal.Cast(bitmap.Pixels), bitmap.Width, bitmap.Height);
+}
\ No newline at end of file
diff --git a/HPPH.SkiaSharp/ImageHelper.cs b/HPPH.SkiaSharp/ImageHelper.cs
new file mode 100644
index 0000000..bf3cbe7
--- /dev/null
+++ b/HPPH.SkiaSharp/ImageHelper.cs
@@ -0,0 +1,18 @@
+using SkiaSharp;
+
+namespace HPPH.SkiaSharp;
+
+public static class ImageHelper
+{
+ public static IImage LoadImage(string path)
+ {
+ using SKImage image = SKImage.FromEncodedData(path);
+ return image.ToImage();
+ }
+
+ public static IImage LoadImage(Stream stream)
+ {
+ using SKImage image = SKImage.FromEncodedData(stream);
+ return image.ToImage();
+ }
+}
\ No newline at end of file
diff --git a/HPPH.sln b/HPPH.sln
index 88cae5d..fb8abc5 100644
--- a/HPPH.sln
+++ b/HPPH.sln
@@ -13,7 +13,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HPPH.Reference", "HPPH.Refe
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HPPH.Generators", "HPPH.Generators\HPPH.Generators.csproj", "{C247512B-E6D2-4591-8AFA-F2268F1AEAB2}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HPPH.System.Drawing", "HPPH.System.Drawing\HPPH.System.Drawing.csproj", "{16EC37E4-3EF1-47AF-B257-465334B36571}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HPPH.System.Drawing", "HPPH.System.Drawing\HPPH.System.Drawing.csproj", "{16EC37E4-3EF1-47AF-B257-465334B36571}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "HPPH.SkiaSharp", "HPPH.SkiaSharp\HPPH.SkiaSharp.csproj", "{E70CD72D-1A41-413E-B0C6-24958733A773}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
@@ -45,6 +47,10 @@ Global
{16EC37E4-3EF1-47AF-B257-465334B36571}.Debug|Any CPU.Build.0 = Debug|Any CPU
{16EC37E4-3EF1-47AF-B257-465334B36571}.Release|Any CPU.ActiveCfg = Release|Any CPU
{16EC37E4-3EF1-47AF-B257-465334B36571}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E70CD72D-1A41-413E-B0C6-24958733A773}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E70CD72D-1A41-413E-B0C6-24958733A773}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E70CD72D-1A41-413E-B0C6-24958733A773}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E70CD72D-1A41-413E-B0C6-24958733A773}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE