diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/Bitmap.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs
similarity index 62%
rename from IronSoftware.Drawing/IronSoftware.Drawing.Common/Bitmap.cs
rename to IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs
index b711cb8..1d2dc53 100644
--- a/IronSoftware.Drawing/IronSoftware.Drawing.Common/Bitmap.cs
+++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs
@@ -10,10 +10,34 @@ namespace IronSoftware.Drawing
/// Implicit casting means that using this class to input and output Bitmap and image types from public API's gives full compatibility to all image type fully supported by Microsoft.
/// Unlike System.Drawing.Bitmap this bitmap object is self memory managing and does not need to be explicitly 'used' or 'disposed'
///
- public partial class Bitmap
+ public partial class AnyBitmap
{
private byte[] Binary { get; set; }
+ ///
+ /// Width of the image.
+ ///
+ public int Width
+ {
+ get
+ {
+ SkiaSharp.SKBitmap sKBitmap = SkiaSharp.SKBitmap.Decode(Binary);
+ return sKBitmap.Width;
+ }
+ }
+
+ ///
+ /// Height of the image.
+ ///
+ public int Height
+ {
+ get
+ {
+ SkiaSharp.SKBitmap sKBitmap = SkiaSharp.SKBitmap.Decode(Binary);
+ return sKBitmap.Height;
+ }
+ }
+
///
/// Number of raw image bytes stored
///
@@ -26,16 +50,16 @@ public int Length
}
///
- /// Allows Comparability and equality.
+ /// Allows Comparability and equality.
///
- /// Another
+ /// Another
/// True if the Bitmaps have exactly the same raw binary data.
public override bool Equals(object bitmap)
{
- Bitmap comp = bitmap as Bitmap;
+ AnyBitmap comp = bitmap as AnyBitmap;
if (comp == null) { return false; }
- return Binary == ((Bitmap)bitmap).ExportBytes();
+ return Binary == ((AnyBitmap)bitmap).ExportBytes();
}
///
@@ -76,12 +100,12 @@ public System.IO.MemoryStream GetStream()
}
///
- /// Creates an exact duplicate
+ /// Creates an exact duplicate
///
///
- public Bitmap Clone()
+ public AnyBitmap Clone()
{
- return new Bitmap(this.Binary);
+ return new AnyBitmap(this.Binary);
}
///
@@ -89,8 +113,8 @@ public Bitmap Clone()
/// Add SkiaSharp, System.Drawing.Common or SixLabors.ImageSharp to your project to enable this feature.
///
/// An image encoding format.
- /// Jped and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality , 100 is highest.
- /// Transcoded image bytes.[
+ /// Jped and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality , 100 is highest.
+ /// Transcoded image bytes.
public byte[] ExportBytes(ImageFormat Format = ImageFormat.Default, int Lossy = 100)
{
using var mem = new System.IO.MemoryStream();
@@ -102,10 +126,10 @@ public byte[] ExportBytes(ImageFormat Format = ImageFormat.Default, int Lossy =
/// Exports the Bitmap as a file encoded in the of your choice.
/// Add SkiaSharp, System.Drawing.Common or SixLabors.ImageSharp to your project to enable the encoding feature.
///
- /// A fully qualified file path
+ /// A fully qualified file path.
/// An image encoding format.
- /// Jpeg and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality , 100 is highest.
- /// Void. Saves a file to disk.[
+ /// Jpeg and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality, 100 is highest.
+ /// Void. Saves a file to disk.
public void ExportFile(string File, ImageFormat Format = ImageFormat.Default, int Lossy = 100)
{
@@ -120,7 +144,7 @@ public void ExportFile(string File, ImageFormat Format = ImageFormat.Default, in
/// Add SkiaSharp, System.Drawing.Common or SixLabors.ImageSharp to your project to enable the encoding feature.
///
/// An image encoding format.
- /// Jped and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality , 100 is highest.
+ /// Jped and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality, 100 is highest.
/// Transcoded image bytes in a .
public System.IO.MemoryStream ToStream(ImageFormat Format = ImageFormat.Default, int Lossy = 100)
{
@@ -135,8 +159,8 @@ public System.IO.MemoryStream ToStream(ImageFormat Format = ImageFormat.Default,
///
/// An image encoding format.
/// An image encoding format.
- /// Jpeg and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality , 100 is highest.
- /// Void. Saves Transcoded image bytes to you .
+ /// Jpeg and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality, 100 is highest.
+ /// Void. Saves Transcoded image bytes to you .
public void ExportStream(System.IO.Stream Stream, ImageFormat Format = ImageFormat.Default, int Lossy = 100)
{
if (Format == ImageFormat.Default)
@@ -158,6 +182,7 @@ public void ExportStream(System.IO.Stream Stream, ImageFormat Format = ImageForm
skdata.SaveTo(Stream);
return;
}
+#if NETSTANDARD
else if (Type.GetType("SixLabors.ImageSharp.Image") != null)
{
using SixLabors.ImageSharp.Image img = this; // magic implicit cast
@@ -174,9 +199,10 @@ public void ExportStream(System.IO.Stream Stream, ImageFormat Format = ImageForm
default: enc = new SixLabors.ImageSharp.Formats.Bmp.BmpEncoder(); break;
}
- img.Save(Stream, enc);
+ img.Save(Stream, enc);
return;
}
+#endif
else if (Type.GetType("System.Drawing.Imaging.ImageFormat") != null)
{
using System.Drawing.Bitmap img = (System.Drawing.Bitmap)this; // magic implicit cast
@@ -188,7 +214,8 @@ public void ExportStream(System.IO.Stream Stream, ImageFormat Format = ImageForm
case ImageFormat.Gif: exportFormat = System.Drawing.Imaging.ImageFormat.Gif; break;
case ImageFormat.Png: exportFormat = System.Drawing.Imaging.ImageFormat.Png; break;
case ImageFormat.Tiff: exportFormat = System.Drawing.Imaging.ImageFormat.Tiff; break;
-
+ case ImageFormat.Wmf: exportFormat = System.Drawing.Imaging.ImageFormat.Wmf; break;
+ case ImageFormat.Icon: exportFormat = System.Drawing.Imaging.ImageFormat.Icon; break;
default: exportFormat = System.Drawing.Imaging.ImageFormat.Bmp; break;
}
@@ -218,7 +245,7 @@ public void ExportStream(System.IO.Stream Stream, ImageFormat Format = ImageForm
/// Saves the raw image data to a file.
///
/// A fully qualified file path.
- ///
+ ///
public void SaveAs(string File)
{
System.IO.File.WriteAllBytes(File, Binary);
@@ -226,14 +253,14 @@ public void SaveAs(string File)
///
/// Saves the image data to a file. Allows for the image to be transcoded to popular image formats.
- /// Add SkiaSharp, System.Drawing.Common or SixLabors.ImageSharp to your project to enable the encoding feature.
+ /// Add SkiaSharp, System.Drawing.Common or SixLabors.ImageSharp to your project to enable the encoding feature.
///
/// A fully qualified file path.
/// An image encoding format.
- /// Jpeg and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality , 100 is highest.
+ /// Jpeg and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality , 100 is highest.
/// Void. Saves Transcoded image bytes to your File.
///
- ///
+ ///
public void SaveAs(string File, ImageFormat Format, int Lossy = 100)
{
System.IO.File.WriteAllBytes(File, Binary);
@@ -241,11 +268,11 @@ public void SaveAs(string File, ImageFormat Format, int Lossy = 100)
///
/// Tries to Save the image data to a file. Allows for the image to be transcoded to popular image formats.
- /// Add SkiaSharp, System.Drawing.Common or SixLabors.ImageSharp to your project to enable the encoding feature.
+ /// Add SkiaSharp, System.Drawing.Common or SixLabors.ImageSharp to your project to enable the encoding feature.
///
/// A fully qualified file path.
/// An image encoding format.
- /// Jpeg and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality , 100 is highest.
+ /// Jpeg and WebP encoding quality (ignored for all other values of ). Higher values return larger file sizes. 0 is lowest quality , 100 is highest.
/// returns true on success, false on failure.
///
public bool TrySaveAs(string File, ImageFormat Format, int Lossy = 100)
@@ -263,11 +290,11 @@ public bool TrySaveAs(string File, ImageFormat Format, int Lossy = 100)
}
///
- /// Tries to Save the raw image data to a file.
- /// returns true on success, false on failure.
+ /// Tries to Save the raw image data to a file.
+ /// returns true on success, false on failure.
///
/// A fully qualified file path.
- ///
+ ///
public bool TrySaveAs(string File)
{
try
@@ -283,18 +310,18 @@ public bool TrySaveAs(string File)
}
///
- /// Generic method to convert popular image types to .
- /// Support includes SixLabors.ImageSharp.Image, SkiaSharp.SKImage, SkiaSharp.SKBitmap, System.Drawing.Bitmap, System.Drawing.Image and Microsoft.Maui.Graphics formats.
- /// Syntax sugar. Explicit casts already also exist to and from and all supported types.
+ /// Generic method to convert popular image types to .
+ /// Support includes SixLabors.ImageSharp.Image, SkiaSharp.SKImage, SkiaSharp.SKBitmap, System.Drawing.Bitmap, System.Drawing.Image and Microsoft.Maui.Graphics formats.
+ /// Syntax sugar. Explicit casts already also exist to and from and all supported types.
///
- /// The Type to cast from. Support includes SixLabors.ImageSharp.Image, SkiaSharp.SKImage, SkiaSharp.SKBitmap, System.Drawing.Bitmap, System.Drawing.Image and Microsoft.Maui.Graphics formats.
+ /// The Type to cast from. Support includes SixLabors.ImageSharp.Image, SkiaSharp.SKImage, SkiaSharp.SKBitmap, System.Drawing.Bitmap, System.Drawing.Image and Microsoft.Maui.Graphics formats.
/// A bitmap or image format from another graphics library.
- /// A
- public static Bitmap FromBitmap(T OtherBitmapFormat)
+ /// A
+ public static AnyBitmap FromBitmap(T OtherBitmapFormat)
{
try
{
- Bitmap result = (Bitmap)Convert.ChangeType(OtherBitmapFormat, typeof(Bitmap));
+ AnyBitmap result = (AnyBitmap)Convert.ChangeType(OtherBitmapFormat, typeof(AnyBitmap));
return result;
}
catch (Exception e)
@@ -303,13 +330,12 @@ public static Bitmap FromBitmap(T OtherBitmapFormat)
}
}
///
- /// Generic method to convert to popular image types.
- /// Support includes SixLabors.ImageSharp.Image, SkiaSharp.SKImage, SkiaSharp.SKBitmap, System.Drawing.Bitmap, System.Drawing.Image and Microsoft.Maui.Graphics formats.
- /// Syntax sugar. Explicit casts already also exist to and from and all supported types.
+ /// Generic method to convert to popular image types.
+ /// Support includes SixLabors.ImageSharp.Image, SkiaSharp.SKImage, SkiaSharp.SKBitmap, System.Drawing.Bitmap, System.Drawing.Image and Microsoft.Maui.Graphics formats.
+ /// Syntax sugar. Explicit casts already also exist to and from and all supported types.
///
- /// The Type to cast to. Support includes SixLabors.ImageSharp.Image, SkiaSharp.SKImage, SkiaSharp.SKBitmap, System.Drawing.Bitmap, System.Drawing.Image and Microsoft.Maui.Graphics formats.
-
- /// A
+ /// The Type to cast to. Support includes SixLabors.ImageSharp.Image, SkiaSharp.SKImage, SkiaSharp.SKBitmap, System.Drawing.Bitmap, System.Drawing.Image and Microsoft.Maui.Graphics formats.
+ /// A
public T ToBitmap()
{
try
@@ -326,43 +352,43 @@ public T ToBitmap()
///
/// Create a new Bitmap from a a Byte Array.
///
- /// A ByteArray of image data in any common format/
+ /// A ByteArray of image data in any common format.
///
- ///
- public static Bitmap FromBytes(byte[] Bytes)
+ ///
+ public static AnyBitmap FromBytes(byte[] Bytes)
{
- return new Bitmap(Bytes);
+ return new AnyBitmap(Bytes);
}
///
- /// Construct a new Bitmap from binary data (bytes)
+ /// Construct a new Bitmap from binary data (bytes).
///
- /// A ByteArray of image data in any common format/
+ /// A ByteArray of image data in any common format.
///
- ///
+ ///
- public Bitmap(byte[] Bytes)
+ public AnyBitmap(byte[] Bytes)
{
Binary = Bytes;
}
///
- /// Create a new Bitmap from a (bytes)
+ /// Create a new Bitmap from a (bytes).
///
- /// A of image data in any common format/
+ /// A of image data in any common format.
///
- ///
- public static Bitmap FromStream(System.IO.Stream Stream)
+ ///
+ public static AnyBitmap FromStream(System.IO.Stream Stream)
{
- return new Bitmap(Stream);
+ return new AnyBitmap(Stream);
}
///
- /// Construct a new Bitmap from a (bytes)
+ /// Construct a new Bitmap from a (bytes).
///
- /// A of image data in any common format/
+ /// A of image data in any common format.
///
- ///
- public Bitmap(System.IO.Stream Stream)
+ ///
+ public AnyBitmap(System.IO.Stream Stream)
{
using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
{
@@ -371,127 +397,135 @@ public Bitmap(System.IO.Stream Stream)
}
///
- /// Create a new Bitmap from a file. (bytes)
+ /// Create a new Bitmap from a file.
///
- /// A fully qualified file path./
- ///
- /// ///
- public static Bitmap FromFile(string File)
+ /// A fully qualified file path.
+ ///
+ ///
+ public static AnyBitmap FromFile(string File)
{
- return new Bitmap(File);
+ return new AnyBitmap(File);
}
///
- /// Construct a new Bitmap from a file. (bytes)
+ /// Construct a new Bitmap from a file.
///
/// A fully qualified file path./
- ///
- /// ///
- public Bitmap(string File)
+ ///
+ ///
+ public AnyBitmap(string File)
{
Binary = System.IO.File.ReadAllBytes(File);
}
+#if NETSTANDARD
///
- /// Implicitly casts ImageSharp objects to .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support ImageSharp as well.
+ /// Implicitly casts ImageSharp objects to .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support ImageSharp as well.
///
- /// SixLabors.ImageSharp.Image will automatically be cast to
- public static implicit operator Bitmap(SixLabors.ImageSharp.Image Image)
+ /// SixLabors.ImageSharp.Image will automatically be cast to .
+ public static implicit operator AnyBitmap(SixLabors.ImageSharp.Image Image)
{
using (var memoryStream = new System.IO.MemoryStream())
{
Image.Save(memoryStream, new SixLabors.ImageSharp.Formats.Bmp.BmpEncoder());
- return new Bitmap(memoryStream.ToArray());
+ return new AnyBitmap(memoryStream.ToArray());
}
}
-
///
- /// Implicitly casts ImageSharp objects from .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support ImageSharp as well.
+ /// Implicitly casts ImageSharp objects from .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support ImageSharp as well.
///
- /// is Implicitly cast to an SixLabors.ImageSharp.Image
- static public implicit operator SixLabors.ImageSharp.Image(Bitmap bitmap)
+ /// is implicitly cast to a SixLabors.ImageSharp.Image.
+ static public implicit operator SixLabors.ImageSharp.Image(AnyBitmap bitmap)
{
return SixLabors.ImageSharp.Image.Load(bitmap.Binary);
}
-
+
+#endif
///
- /// Implicitly casts SkiaSharp.SKImage objects to .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support SkiaSharp as well.
+ /// Implicitly casts SkiaSharp.SKImage objects to .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support SkiaSharp as well.
///
- /// SkiaSharp.SKImage will automatically be cast to
- public static implicit operator Bitmap(SkiaSharp.SKImage Image)
+ /// SkiaSharp.SKImage will automatically be cast to .
+ public static implicit operator AnyBitmap(SkiaSharp.SKImage Image)
{
- return new Bitmap(SkiaSharp.SKBitmap.FromImage(Image).Encode(SkiaSharp.SKEncodedImageFormat.Bmp, 100).ToArray());
+#if NETFRAMEWORK
+ return new AnyBitmap(SkiaSharp.SKBitmap.FromImage(Image).Bytes);
+#else
+ return new AnyBitmap(SkiaSharp.SKBitmap.FromImage(Image).Encode(SkiaSharp.SKEncodedImageFormat.Bmp, 100).ToArray());
+#endif
}
///
- /// Implicitly casts SkiaSharp.SKImage objects from .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support SkiaSharp.SKImage as well.
+ /// Implicitly casts SkiaSharp.SKImage objects from .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support SkiaSharp.SKImage as well.
///
- /// is Implicitly cast to an SkiaSharp.SKImage
- static public implicit operator SkiaSharp.SKImage(Bitmap bitmap)
+ /// is implicitly cast to an SkiaSharp.SKImage.
+ static public implicit operator SkiaSharp.SKImage(AnyBitmap bitmap)
{
return SkiaSharp.SKImage.FromBitmap(SkiaSharp.SKBitmap.Decode(bitmap.Binary));
}
-
///
- /// Implicitly casts SkiaSharp.SKBitmap objects to .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support SkiaSharp as well.
+ /// Implicitly casts SkiaSharp.SKBitmap objects to .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support SkiaSharp as well.
///
- /// SkiaSharp.SKBitmap will automatically be cast to
+ /// SkiaSharp.SKBitmap will automatically be cast to .
- public static implicit operator Bitmap(SkiaSharp.SKBitmap Image)
+ public static implicit operator AnyBitmap(SkiaSharp.SKBitmap Image)
{
- return new Bitmap(Image.Encode(SkiaSharp.SKEncodedImageFormat.Bmp, 100).ToArray());
+#if NETFRAMEWORK
+ return new AnyBitmap(Image.Bytes);
+#else
+ return new AnyBitmap(Image.Encode(SkiaSharp.SKEncodedImageFormat.Bmp, 100).ToArray());
+#endif
}
///
- /// Implicitly casts SkiaSharp.SKBitmap objects from .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support SkiaSharp.SKBitmap as well.
+ /// Implicitly casts SkiaSharp.SKBitmap objects from .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support SkiaSharp.SKBitmap as well.
///
- /// is explicitly cast to an SkiaSharp.SKBitmap
- static public implicit operator SkiaSharp.SKBitmap(Bitmap bitmap)
+ /// is explicitly cast to an SkiaSharp.SKBitmap.
+ static public implicit operator SkiaSharp.SKBitmap(AnyBitmap bitmap)
{
return SkiaSharp.SKBitmap.Decode(bitmap.Binary);
}
-
+#if NETSTANDARD
///
- /// Implicitly casts Microsoft.Maui.Graphics.Platform.PlatformImage objects to .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support Microsoft.Maui.Graphics as well.
+ /// Implicitly casts Microsoft.Maui.Graphics.Platform.PlatformImage objects to .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support Microsoft.Maui.Graphics as well.
///
- /// Microsoft.Maui.Graphics.Platform.PlatformImage will automatically be cast to
+ /// Microsoft.Maui.Graphics.Platform.PlatformImage will automatically be cast to .
- public static implicit operator Bitmap(Microsoft.Maui.Graphics.Platform.PlatformImage Image)
+ public static implicit operator AnyBitmap(Microsoft.Maui.Graphics.Platform.PlatformImage Image)
{
using (var memoryStream = new System.IO.MemoryStream())
{
Image.Save(memoryStream);
- return new Bitmap(memoryStream.ToArray());
+ return new AnyBitmap(memoryStream.ToArray());
}
}
///
- /// Implicitly casts Microsoft.Maui.Graphics.Platform.PlatformImage objects from .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support Microsoft.Maui.Graphics as well.
+ /// Implicitly casts Microsoft.Maui.Graphics.Platform.PlatformImage objects from .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support Microsoft.Maui.Graphics as well.
///
- /// is Implicitly cast to an Microsoft.Maui.Graphics.Platform.PlatformImage
+ /// is implicitly cast to an Microsoft.Maui.Graphics.Platform.PlatformImage.
- static public implicit operator Microsoft.Maui.Graphics.Platform.PlatformImage(Bitmap bitmap)
+ static public implicit operator Microsoft.Maui.Graphics.Platform.PlatformImage(AnyBitmap bitmap)
{
return (Microsoft.Maui.Graphics.Platform.PlatformImage)Microsoft.Maui.Graphics.Platform.PlatformImage.FromStream(bitmap.GetStream());
}
-
+#endif
///
- /// Implicitly casts System.Drawing.Bitmap objects to .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support System.Drawing.Common as well.
+ /// Implicitly casts System.Drawing.Bitmap objects to .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support System.Drawing.Common as well.
///
- /// System.Drawing.Bitmap will automatically be cast to
+ /// System.Drawing.Bitmap will automatically be cast to
- public static implicit operator Bitmap(System.Drawing.Bitmap Image)
+ public static implicit operator AnyBitmap(System.Drawing.Bitmap Image)
{
Byte[] data;
@@ -502,30 +536,32 @@ public static implicit operator Bitmap(System.Drawing.Bitmap Image)
Image.Save(memoryStream, System.Drawing.Imaging.ImageFormat.Bmp);
data = memoryStream.ToArray();
- return new Bitmap(data);
+ return new AnyBitmap(data);
}
}
catch (Exception e)
{
if (e is PlatformNotSupportedException || e is TypeInitializationException)
{
+#if NETSTANDARD
if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
{
throw SystemDotDrawingPlatformNotSupported(e);
}
+#endif
}
throw e;
}
}
///
- /// Implicitly casts System.Drawing.Bitmap objects from .
- /// When your .NET Class methods to use as parameters and return types, you now automatically support System.Drawing.Common as well.
+ /// Implicitly casts System.Drawing.Bitmap objects from .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support System.Drawing.Common as well.
///
- /// is implicitly cast to an System.Drawing.Bitmap
+ /// is implicitly cast to an System.Drawing.Bitmap.
- static public implicit operator System.Drawing.Bitmap(Bitmap bitmap)
+ static public implicit operator System.Drawing.Bitmap(AnyBitmap bitmap)
{
try
{
@@ -535,10 +571,12 @@ static public implicit operator System.Drawing.Bitmap(Bitmap bitmap)
{
if (e is PlatformNotSupportedException || e is TypeInitializationException)
{
+#if NETSTANDARD
if (!System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows))
{
throw SystemDotDrawingPlatformNotSupported(e);
}
+#endif
}
throw e;
}
@@ -546,21 +584,21 @@ static public implicit operator System.Drawing.Bitmap(Bitmap bitmap)
private static PlatformNotSupportedException SystemDotDrawingPlatformNotSupported(Exception innerException)
{
- return new PlatformNotSupportedException("Microsoft has chosen to no longer support System.Drawing.Common on Linux or MacOS. To solve this please use another Bitmap type such as {typeof(Bitmap).ToString()}, SkiaSharp or ImageSharp.\n\nhttps://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only", innerException);
+ return new PlatformNotSupportedException("Microsoft has chosen to no longer support System.Drawing.Common on Linux or MacOS. To solve this please use another Bitmap type such as {typeof(Bitmap).ToString()}, SkiaSharp or ImageSharp.\n\nhttps://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/system-drawing-common-windows-only", innerException);
}
private static InvalidCastException ImageCastException(string fullTypeName, Exception innerException)
{
- return new InvalidCastException($"IronSoftware.Drawing does not yet support casting {fullTypeName} to {typeof(Bitmap).FullName}. Try using System.Drawing.Common, SkiaSharp or ImageSharp.", innerException);
+ return new InvalidCastException($"IronSoftware.Drawing does not yet support casting {fullTypeName} to {typeof(AnyBitmap).FullName}. Try using System.Drawing.Common, SkiaSharp or ImageSharp.", innerException);
}
private static InvalidOperationException NoConverterException(ImageFormat Format, Exception innerException)
{
- return new InvalidOperationException($"{typeof(Bitmap)} is unable to convert your image data to {Format.ToString()} because it requires a suitable encoder to be added to your project via Nuget.\nPlease try SkiaSharp, System.Drawing.Common, SixLabors.ImageSharp, Microsoft.Maui.Graphics; or alternatively save using ImageFormat.Default", innerException);
+ return new InvalidOperationException($"{typeof(AnyBitmap)} is unable to convert your image data to {Format.ToString()} because it requires a suitable encoder to be added to your project via Nuget.\nPlease try SkiaSharp, System.Drawing.Common, SixLabors.ImageSharp, Microsoft.Maui.Graphics; or alternatively save using ImageFormat.Default", innerException);
}
///
- /// Popular image formats which can read and export.
+ /// Popular image formats which can read and export.
///
///
///
@@ -581,13 +619,19 @@ public enum ImageFormat
/// The PNG image format.
Png = 4,
- /// The WBMP image format. Will default to BMP if not supported on the runtime platform..
+ /// The WBMP image format. Will default to BMP if not supported on the runtime platform.
Wbmp = 5,
/// The new WebP image format.
Webp = 6,
+ /// The Icon image format.
+ Icon = 7,
+
+ /// The Wmf image format.
+ Wmf = 8,
+
/// The existing raw image format.
Default = -1,
}
diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/Color.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common/Color.cs
new file mode 100644
index 0000000..2ca2934
--- /dev/null
+++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/Color.cs
@@ -0,0 +1,919 @@
+using System;
+using System.Globalization;
+using System.Linq;
+
+namespace IronSoftware.Drawing
+{
+ public partial class Color
+ {
+
+ ///
+ /// Gets the alpha component value of this System.Drawing.Color structure.
+ ///
+ /// The alpha component value of this IronSoftware.Drawing.Color.
+ public byte A { get; internal set; }
+
+ ///
+ /// Gets the green component value of this System.Drawing.Color structure.
+ ///
+ /// The green component value of this IronSoftware.Drawing.Color.
+ public byte G { get; internal set; }
+
+ ///
+ /// Gets the blue component value of this System.Drawing.Color structure.
+ ///
+ /// The blue component value of this IronSoftware.Drawing.Color.
+ public byte B { get; internal set; }
+
+ ///
+ /// Gets the red component value of this System.Drawing.Color structure.
+ ///
+ /// The red component value of this IronSoftware.Drawing.Color.
+ public byte R { get; internal set; }
+
+ internal Color(string colorcode)
+ {
+ colorcode = colorcode.TrimStart('#');
+
+ if (colorcode.Length == 8)
+ {
+ this.A = (byte)int.Parse(colorcode.Substring(0, 2), NumberStyles.HexNumber);
+ this.R = (byte)int.Parse(colorcode.Substring(2, 2), NumberStyles.HexNumber);
+ this.G = (byte)int.Parse(colorcode.Substring(4, 2), NumberStyles.HexNumber);
+ this.B = (byte)int.Parse(colorcode.Substring(6, 2), NumberStyles.HexNumber);
+ }
+ else if (colorcode.Length == 6)
+ {
+ this.A = 255;
+ this.R = (byte)int.Parse(colorcode.Substring(0, 2), NumberStyles.HexNumber);
+ this.G = (byte)int.Parse(colorcode.Substring(2, 2), NumberStyles.HexNumber);
+ this.B = (byte)int.Parse(colorcode.Substring(4, 2), NumberStyles.HexNumber);
+ }
+ else if (colorcode.Length == 3)
+ {
+ this.A = 255;
+ this.R = (byte)int.Parse(string.Join("", Enumerable.Repeat(colorcode.Substring(0, 1), 2)), NumberStyles.HexNumber);
+ this.G = (byte)int.Parse(string.Join("", Enumerable.Repeat(colorcode.Substring(1, 1), 2)), NumberStyles.HexNumber);
+ this.B = (byte)int.Parse(string.Join("", Enumerable.Repeat(colorcode.Substring(2, 1), 2)), NumberStyles.HexNumber);
+ }
+ else
+ {
+ throw NoConverterException(colorcode, null);
+ }
+ }
+
+ internal Color(int alpha, int red, int green, int blue)
+ {
+ this.A = (byte)alpha;
+ this.R = (byte)red;
+ this.G = (byte)green;
+ this.B = (byte)blue;
+ }
+
+ internal Color(int red, int green, int blue)
+ {
+ this.A = 255;
+ this.R = (byte)red;
+ this.G = (byte)green;
+ this.B = (byte)blue;
+ }
+
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F0F8FF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color AliceBlue = new Color("#F0F8FF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FAEBD7.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color AntiqueWhite = new Color("#FAEBD7");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #00FFFF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Aqua = new Color("#00FFFF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #7FFFD4.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Aquamarine = new Color("#7FFFD4");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F0FFFF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Azure = new Color("#F0FFFF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F5F5DC.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Beige = new Color("#F5F5DC");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFE4C4.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Bisque = new Color("#FFE4C4");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #000000.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Black = new Color("#000000");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFEBCD.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color BlanchedAlmond = new Color("#FFEBCD");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #0000FF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Blue = new Color("#0000FF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #8A2BE2.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color BlueViolet = new Color("#8A2BE2");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #A52A2A.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Brown = new Color("#A52A2A");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #DEB887.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color BurlyWood = new Color("#DEB887");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #5F9EA0.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color CadetBlue = new Color("#5F9EA0");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #7FFF00.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Chartreuse = new Color("#7FFF00");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #D2691E.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Chocolate = new Color("#D2691E");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FF7F50.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Coral = new Color("#FF7F50");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #6495ED.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color CornflowerBlue = new Color("#6495ED");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFF8DC.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Cornsilk = new Color("#FFF8DC");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #DC143C.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Crimson = new Color("#DC143C");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #00FFFF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Cyan = new Color("#00FFFF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #00008B.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkBlue = new Color("#00008B");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #008B8B.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkCyan = new Color("#008B8B");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #B8860B.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkGoldenrod = new Color("#B8860B");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #A9A9A9.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkGray = new Color("#A9A9A9");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #006400.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkGreen = new Color("#006400");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #BDB76B.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkKhaki = new Color("#BDB76B");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #8B008B.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkMagenta = new Color("#8B008B");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #556B2F.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkOliveGreen = new Color("#556B2F");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FF8C00.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkOrange = new Color("#FF8C00");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #9932CC.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkOrchid = new Color("#9932CC");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #8B0000.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkRed = new Color("#8B0000");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #E9967A.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkSalmon = new Color("#E9967A");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #8FBC8B.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkSeaGreen = new Color("#8FBC8B");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #483D8B.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkSlateBlue = new Color("#483D8B");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #2F4F4F.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkSlateGray = new Color("#2F4F4F");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #00CED1.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkTurquoise = new Color("#00CED1");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #9400D3.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DarkViolet = new Color("#9400D3");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FF1493.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DeepPink = new Color("#FF1493");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #00BFFF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DeepSkyBlue = new Color("#00BFFF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #696969.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DimGray = new Color("#696969");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #1E90FF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color DodgerBlue = new Color("#1E90FF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #B22222.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Firebrick = new Color("#B22222");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFFAF0.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color FloralWhite = new Color("#FFFAF0");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #228B22.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color ForestGreen = new Color("#228B22");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FF00FF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Fuchsia = new Color("#FF00FF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #DCDCDC.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Gainsboro = new Color("#DCDCDC");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F8F8FF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color GhostWhite = new Color("#F8F8FF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFD700.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Gold = new Color("#FFD700");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #DAA520.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Goldenrod = new Color("#DAA520");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #808080.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Gray = new Color("#808080");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #008000.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Green = new Color("#008000");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #ADFF2F.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color GreenYellow = new Color("#ADFF2F");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F0FFF0.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Honeydew = new Color("#F0FFF0");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FF69B4.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color HotPink = new Color("#FF69B4");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #CD5C5C.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color IndianRed = new Color("#CD5C5C");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #4B0082.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Indigo = new Color("#4B0082");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFFFF0.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Ivory = new Color("#FFFFF0");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F0E68C.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Khaki = new Color("#F0E68C");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #E6E6FA.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Lavender = new Color("#E6E6FA");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFF0F5.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LavenderBlush = new Color("#FFF0F5");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #7CFC00.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LawnGreen = new Color("#7CFC00");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFFACD.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LemonChiffon = new Color("#FFFACD");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #ADD8E6.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightBlue = new Color("#ADD8E6");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F08080.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightCoral = new Color("#F08080");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #E0FFFF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightCyan = new Color("#E0FFFF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FAFAD2.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightGoldenrodYellow = new Color("#FAFAD2");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #D3D3D3.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightGray = new Color("#D3D3D3");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #90EE90.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightGreen = new Color("#90EE90");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFB6C1.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightPink = new Color("#FFB6C1");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFA07A.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightSalmon = new Color("#FFA07A");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #20B2AA.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightSeaGreen = new Color("#20B2AA");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #87CEFA.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightSkyBlue = new Color("#87CEFA");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #778899.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightSlateGray = new Color("#778899");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #B0C4DE.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightSteelBlue = new Color("#B0C4DE");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFFFE0.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LightYellow = new Color("#FFFFE0");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #00FF00.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Lime = new Color("#00FF00");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #32CD32.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color LimeGreen = new Color("#32CD32");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FAF0E6.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Linen = new Color("#FAF0E6");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FF00FF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Magenta = new Color("#FF00FF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #800000.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Maroon = new Color("#800000");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #66CDAA.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MediumAquamarine = new Color("#66CDAA");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #0000CD.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MediumBlue = new Color("#0000CD");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #BA55D3.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MediumOrchid = new Color("#BA55D3");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #9370DB.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MediumPurple = new Color("#9370DB");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #3CB371.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MediumSeaGreen = new Color("#3CB371");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #7B68EE.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MediumSlateBlue = new Color("#7B68EE");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #00FA9A.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MediumSpringGreen = new Color("#00FA9A");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #48D1CC.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MediumTurquoise = new Color("#48D1CC");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #C71585.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MediumVioletRed = new Color("#C71585");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #191970.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MidnightBlue = new Color("#191970");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F5FFFA.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MintCream = new Color("#F5FFFA");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFE4E1.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color MistyRose = new Color("#FFE4E1");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFE4B5.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Moccasin = new Color("#FFE4B5");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFDEAD.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color NavajoWhite = new Color("#FFDEAD");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #000080.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Navy = new Color("#000080");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FDF5E6.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color OldLace = new Color("#FDF5E6");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #808000.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Olive = new Color("#808000");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #6B8E23.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color OliveDrab = new Color("#6B8E23");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFA500.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Orange = new Color("#FFA500");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FF4500.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color OrangeRed = new Color("#FF4500");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #DA70D6.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Orchid = new Color("#DA70D6");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #EEE8AA.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color PaleGoldenrod = new Color("#EEE8AA");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #98FB98.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color PaleGreen = new Color("#98FB98");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #AFEEEE.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color PaleTurquoise = new Color("#AFEEEE");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #DB7093.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color PaleVioletRed = new Color("#DB7093");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFEFD5.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color PapayaWhip = new Color("#FFEFD5");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFDAB9.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color PeachPuff = new Color("#FFDAB9");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #CD853F.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Peru = new Color("#CD853F");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFC0CB.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Pink = new Color("#FFC0CB");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #DDA0DD.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Plum = new Color("#DDA0DD");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #B0E0E6.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color PowderBlue = new Color("#B0E0E6");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #800080.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Purple = new Color("#800080");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #663399.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color RebeccaPurple = new Color("#663399");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FF0000.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Red = new Color("#FF0000");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #BC8F8F.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color RosyBrown = new Color("#BC8F8F");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #4169E1.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color RoyalBlue = new Color("#4169E1");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #8B4513.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color SaddleBrown = new Color("#8B4513");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FA8072.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Salmon = new Color("#FA8072");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F4A460.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color SandyBrown = new Color("#F4A460");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #2E8B57.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color SeaGreen = new Color("#2E8B57");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFF5EE.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color SeaShell = new Color("#FFF5EE");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #A0522D.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Sienna = new Color("#A0522D");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #C0C0C0.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Silver = new Color("#C0C0C0");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #87CEEB.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color SkyBlue = new Color("#87CEEB");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #6A5ACD.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color SlateBlue = new Color("#6A5ACD");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #708090.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color SlateGray = new Color("#708090");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFFAFA.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Snow = new Color("#FFFAFA");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #00FF7F.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color SpringGreen = new Color("#00FF7F");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #4682B4.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color SteelBlue = new Color("#4682B4");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #D2B48C.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Tan = new Color("#D2B48C");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #008080.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Teal = new Color("#008080");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #D2B48C.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Thistle = new Color("#D8BFD8");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FF6347.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Tomato = new Color("#FF6347");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #00FFFFFF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Transparent = new Color("#00FFFFFF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #40E0D0.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Turquoise = new Color("#40E0D0");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #EE82EE.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Violet = new Color("#EE82EE");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F5DEB3.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Wheat = new Color("#F5DEB3");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFFFFF.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color White = new Color("#FFFFFF");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #F5F5F5.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color WhiteSmoke = new Color("#F5F5F5");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #FFFF00.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color Yellow = new Color("#FFFF00");
+ ///
+ /// Gets a system-defined color that has an ARGB value of #9ACD32.
+ ///
+ /// A IronSoftware.Drawing.Color representing a system-defined color.
+ public static Color YellowGreen = new Color("#9ACD32");
+
+ ///
+ /// Creates a IronSoftware.Drawing.Color structure from the specified 8-bit color values
+ /// (red, green, and blue). The alpha value is implicitly 255 (fully opaque). Although
+ /// this method allows a 32-bit value to be passed for each color component, the
+ /// value of each component is limited to 8 bits.
+ ///
+ /// The red component value for the new System.Drawing.Color. Valid values are 0 through 255.
+ /// The green component value for the new System.Drawing.Color. Valid values are 0 through 255.
+ /// The blue component value for the new System.Drawing.Color. Valid values are 0 through 255.
+ ///
+ public static Color FromArgb(int red, int green, int blue)
+ {
+ return new Color(red, green, blue);
+ }
+
+ ///
+ /// Creates a IronSoftware.Drawing.Color structure from the specified 8-bit color values
+ /// (alpha, red, green, and blue). Although this method allows a 32-bit value to be passed for each color component,
+ /// the value of each component is limited to 8 bits.
+ ///
+ /// The alpha value for the new System.Drawing.Color. Valid values are 0 through 255.
+ /// The red component value for the new System.Drawing.Color. Valid values are 0 through 255.
+ /// The green component value for the new System.Drawing.Color. Valid values are 0 through 255.
+ /// The blue component value for the new System.Drawing.Color. Valid values are 0 through 255.
+ ///
+ public static Color FromArgb(int alpha, int red, int green, int blue)
+ {
+ return new Color(alpha, red, green, blue);
+ }
+
+ ///
+ /// Creates a IronSoftware.Drawing.Color structure from a 32-bit ARGB value.
+ ///
+ /// A value specifying the 32-bit ARGB value.
+ /// IronSoftware.Drawing.Color
+ public static Color FromArgb(int argb)
+ {
+ return new Color(argb.ToString("X"));
+ }
+
+ ///
+ /// Luminance is a value from 0 (black) to 100 (white) where 50 is the perceptual "middle grey".
+ /// Luminance = 50 is the equivalent of Y = 18.4, or in other words an 18% grey card, representing the middle of a photographic exposure(Ansel Adams zone V).
+ ///
+ /// Preceived Lightness
+ public double GetLuminance()
+ {
+ int vR = R / 255;
+ int vG = G / 255;
+ int vB = B / 255;
+
+ double Y = (0.2126 * SRGBtoLin(vR) + 0.7152 * SRGBtoLin(vG) + 0.0722 * SRGBtoLin(vB));
+
+ if (Y <= (216 / 24389))
+ { // The CIE standard states 0.008856 but 216/24389 is the intent for 0.008856451679036
+ return Y * (24389 / 27); // The CIE standard states 903.3, but 24389/27 is the intent, making 903.296296296296296
+ }
+ else
+ {
+ return Math.Pow(Y, (1 / 3)) * 116 - 16;
+ }
+ }
+
+ ///
+ /// Implicitly casts System.Drawing.Color objects to .
+ /// When your .NET Class methods to use as parameters and return types, you now automatically support Color as well.
+ ///
+ /// System.Drawing.Color will automatically be cast to
+ public static implicit operator Color(System.Drawing.Color Color)
+ {
+ return new Color(Color.A, Color.R, Color.G, Color.B);
+ }
+
+ ///
+ /// Implicitly casts System.Drawing.Color objects from .
+ /// When your .NET Class methods to use as parameters and return types, you now automatically support SKColor as well.
+ ///
+ /// is explicitly cast to an System.Drawing.Rectangle
+ static public implicit operator System.Drawing.Color(Color Color)
+ {
+ return System.Drawing.Color.FromArgb(Color.A, Color.R, Color.G, Color.B);
+ }
+
+ ///
+ /// Implicitly casts SkiaSharp.SKColor objects to .
+ /// When your .NET Class methods to use as parameters and return types, you now automatically support SKColor as well.
+ ///
+ /// System.Drawing.Color will automatically be cast to
+ public static implicit operator Color(SkiaSharp.SKColor Color)
+ {
+ return new Color(Color.Alpha, Color.Red, Color.Green, Color.Blue);
+ }
+
+ ///
+ /// Implicitly casts SkiaSharp.SKColor objects from .
+ /// When your .NET Class methods to use as parameters and return types, you now automatically support SKColor as well.
+ ///
+ /// is explicitly cast to an SkiaSharp.SKColor
+ static public implicit operator SkiaSharp.SKColor(Color Color)
+ {
+ return new SkiaSharp.SKColor(Color.A, Color.R, Color.G, Color.B);
+ }
+
+ #region Private Method
+
+ private static InvalidOperationException NoConverterException(string color, Exception innerException)
+ {
+ return new InvalidOperationException($"{color} is unable to convert to {typeof(Color)} because it requires a suitable length of string.", innerException);
+ }
+
+ private static double SRGBtoLin(int colorChannel)
+ {
+ // Send this function a decimal sRGB gamma encoded color value
+ // between 0.0 and 1.0, and it returns a linearized value.
+
+ if (colorChannel <= 0.04045)
+ {
+ return colorChannel / 12.92;
+ }
+ else
+ {
+ return Math.Pow(((colorChannel + 0.055) / 1.055), 2.4);
+ }
+ }
+
+ #endregion
+ }
+}
diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/CropRectangle.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common/CropRectangle.cs
new file mode 100644
index 0000000..19222c1
--- /dev/null
+++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/CropRectangle.cs
@@ -0,0 +1,95 @@
+namespace IronSoftware.Drawing
+{
+ public partial class CropRectangle
+ {
+ public CropRectangle() { }
+
+ public CropRectangle(int x, int y, int width, int height)
+ {
+ this.X = x;
+ this.Y = y;
+ this.Width = width;
+ this.Height = height;
+ }
+
+ ///
+ /// The x-coordinate of the upper-left corner of this Rectangle. The default is 0.
+ ///
+ public int X { get; set; }
+ ///
+ /// The y-coordinate of the upper-left corner of this Rectangle. The default is 0.
+ ///
+ public int Y { get; set; }
+ ///
+ /// The width of this Rectangle. The default is 0.
+ ///
+ public int Width { get; set; }
+ ///
+ /// The height of this Rectangle. The default is 0.
+ ///
+ public int Height { get; set; }
+
+ ///
+ /// Implicitly casts System.Drawing.Rectangle objects to .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support Rectangle as well.
+ ///
+ /// System.Drawing.Rectangle will automatically be cast to .
+
+ public static implicit operator CropRectangle(System.Drawing.Rectangle Rectangle)
+ {
+ return new CropRectangle(Rectangle.X, Rectangle.Y, Rectangle.Width, Rectangle.Height);
+ }
+
+ ///
+ /// Implicitly casts System.Drawing.Rectangle objects from .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support Rectangle as well.
+ ///
+ /// is explicitly cast to an System.Drawing.Rectangle.
+ static public implicit operator System.Drawing.Rectangle(CropRectangle CropRectangle)
+ {
+ return new System.Drawing.Rectangle(CropRectangle.X, CropRectangle.Y, CropRectangle.Width, CropRectangle.Height);
+ }
+
+ ///
+ /// Implicitly casts SkiaSharp.SKRect objects to .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support SkiaSharp.SKRect as well.
+ ///
+ /// SkiaSharp.SKRect will automatically be cast to .
+
+ public static implicit operator CropRectangle(SkiaSharp.SKRect SKRect)
+ {
+ return new CropRectangle((int)SKRect.Left, (int)SKRect.Bottom, (int)SKRect.Width, (int)SKRect.Height);
+ }
+
+ ///
+ /// Implicitly casts SkiaSharp.SKRect objects from .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support SkiaSharp.SKRect as well.
+ ///
+ /// is explicitly cast to an SkiaSharp.SKRect.
+ static public implicit operator SkiaSharp.SKRect(CropRectangle CropRectangle)
+ {
+ return SkiaSharp.SKRect.Create(CropRectangle.X, CropRectangle.Y, CropRectangle.Width, CropRectangle.Height);
+ }
+
+ ///
+ /// Implicitly casts SkiaSharp.SKRectI objects to .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support SkiaSharp.SKRectI as well.
+ ///
+ /// SkiaSharp.SKRectI will automatically be cast to .
+
+ public static implicit operator CropRectangle(SkiaSharp.SKRectI SKRectI)
+ {
+ return new CropRectangle((int)SKRectI.Left, (int)SKRectI.Bottom, (int)SKRectI.Width, (int)SKRectI.Height);
+ }
+
+ ///
+ /// Implicitly casts SkiaSharp.SKRectI objects from .
+ /// When your .NET Class methods use as parameters and return types, you now automatically support SkiaSharp.SKRectI as well.
+ ///
+ /// is explicitly cast to a SkiaSharp.SKRectI.
+ static public implicit operator SkiaSharp.SKRectI(CropRectangle CropRectangle)
+ {
+ return SkiaSharp.SKRectI.Create(CropRectangle.X, CropRectangle.Y, CropRectangle.Width, CropRectangle.Height);
+ }
+ }
+}
diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronBitmap.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronBitmap.cs
new file mode 100644
index 0000000..125f857
--- /dev/null
+++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronBitmap.cs
@@ -0,0 +1,307 @@
+using SkiaSharp;
+using System;
+
+namespace IronSoftware.Drawing
+{
+ public static class IronBitmap
+ {
+ ///
+ /// Resize an image with scaling.
+ ///
+ /// Original bitmap to resize.
+ /// Scale of new image 0 - 1.
+ /// IronSoftware.Drawing.AnyBitmap.
+ public static AnyBitmap Resize(this AnyBitmap bitmap, float scale)
+ {
+ SKBitmap originalBitmap = bitmap;
+ SKBitmap toBitmap = new SKBitmap((int)(originalBitmap.Width * scale), (int)(originalBitmap.Height * scale), originalBitmap.ColorType, originalBitmap.AlphaType);
+
+ using (SKCanvas canvas = new SKCanvas(toBitmap))
+ {
+ // Draw a bitmap rescaled
+#if NETFRAMEWORK
+ canvas.SetMatrix(SKMatrix.MakeScale(scale, scale));
+#else
+ canvas.SetMatrix(SKMatrix.CreateScale(scale, scale));
+#endif
+ canvas.DrawBitmap(originalBitmap, 0, 0);
+ canvas.ResetMatrix();
+ canvas.Flush();
+ }
+
+ return toBitmap;
+ }
+
+ ///
+ /// Resize an image with width and height.
+ ///
+ /// Original bitmap to resize.
+ /// Width of the new resized image.
+ /// Height of the new resized image.
+ /// IronSoftware.Drawing.AnyBitmap.
+ public static AnyBitmap Resize(this AnyBitmap bitmap, int width, int height)
+ {
+ SKBitmap originalBitmap = bitmap;
+ SKBitmap toBitmap = new SKBitmap(width, height, originalBitmap.ColorType, originalBitmap.AlphaType);
+ originalBitmap.ExtractSubset(toBitmap, new CropRectangle(0, 0, width, height));
+
+ return toBitmap;
+ }
+
+ ///
+ /// Resize an image with width and height.
+ ///
+ /// Original bitmap to resize.
+ /// Width of the new resized image.
+ /// Height of the new resized image.
+ /// Scale of new image 0 - 1.
+ /// IronSoftware.Drawing.AnyBitmap.
+ public static AnyBitmap Resize(this AnyBitmap bitmap, int width, int height, float scale)
+ {
+ SKBitmap originalBitmap = bitmap;
+ SKBitmap toBitmap = new SKBitmap(width, height, originalBitmap.ColorType, originalBitmap.AlphaType);
+
+ using (SKCanvas canvas = new SKCanvas(toBitmap))
+ {
+ // Draw a bitmap rescaled
+#if NETFRAMEWORK
+ canvas.SetMatrix(SKMatrix.MakeScale(scale, scale));
+#else
+ canvas.SetMatrix(SKMatrix.CreateScale(scale, scale));
+#endif
+ canvas.DrawBitmap(originalBitmap, 0, 0);
+ canvas.ResetMatrix();
+ canvas.Flush();
+ }
+
+ return toBitmap;
+ }
+
+ ///
+ /// Resize an image with width and height.
+ ///
+ /// Original bitmap to resize.
+ /// CropArea to crop an image.
+ /// IronSoftware.Drawing.AnyBitmap.
+ public static AnyBitmap CropImage(this AnyBitmap bitmap, CropRectangle cropRect)
+ {
+ if (cropRect != null)
+ {
+ CropRectangle dest = ValidateCropArea(bitmap, cropRect);
+ SKBitmap croppedBitmap = new SKBitmap((int)dest.Width, (int)dest.Height);
+ try
+ {
+ using (SKCanvas canvas = new SKCanvas(croppedBitmap))
+ {
+ canvas.DrawBitmap(bitmap, cropRect, dest);
+ canvas.Flush();
+ }
+
+ return croppedBitmap;
+ }
+ catch (OutOfMemoryException)
+ {
+ try { croppedBitmap.Dispose(); } catch { }
+ throw new Exception("Crop Rectangle is larger than the input image.");
+ }
+ }
+ else
+ {
+ return bitmap;
+ }
+ }
+
+ ///
+ /// Rotate an image.
+ ///
+ /// Original bitmap to resize.
+ /// Angle for rotate image. Default (null): Will try to determine the image's rotation angle.
+ /// IronSoftware.Drawing.AnyBitmap.
+ public static AnyBitmap RotateImage(this AnyBitmap bitmap, double? angle = null)
+ {
+ double skewAngle = angle ?? SkewImageLib.GetSkewAngle(bitmap);
+ double radians = Math.PI * skewAngle / 180;
+ float sine = (float)Math.Abs(Math.Sin(radians));
+ float cosine = (float)Math.Abs(Math.Cos(radians));
+
+ int originalWidth = ((SKBitmap)bitmap).Width;
+ int originalHeight = ((SKBitmap)bitmap).Height;
+ int rotatedWidth = (int)(cosine * originalWidth + sine * originalHeight);
+ int rotatedHeight = (int)(cosine * originalHeight + sine * originalWidth);
+
+ SKBitmap rotatedBitmap = new SKBitmap(rotatedWidth, rotatedHeight);
+
+ using (SKCanvas canvas = new SKCanvas(rotatedBitmap))
+ {
+ canvas.Clear(SKColors.LightPink);
+ canvas.Translate(rotatedWidth / 2, rotatedHeight / 2);
+ canvas.RotateDegrees((float)angle);
+ canvas.Translate(-originalWidth / 2, -originalHeight / 2);
+ canvas.DrawBitmap(bitmap, new SKPoint());
+ }
+
+ return rotatedBitmap;
+ }
+
+ ///
+ /// Determine the image's skew angle.
+ ///
+ /// Original bitmap to get skew angle from.
+ /// Image's angle of skew.
+ public static double GetSkewAngle(this AnyBitmap bitmap)
+ {
+ return SkewImageLib.GetSkewAngle(bitmap);
+ }
+
+ ///
+ /// Trim white space of the image.
+ ///
+ /// Original bitmap to trim.
+ /// IronSoftware.Drawing.AnyBitmap.
+ public static SKBitmap Trim(this AnyBitmap bitmap)
+ {
+
+ try
+ {
+ SKBitmap originalBitmap = bitmap;
+ int[] rgbValues = new int[originalBitmap.Height * originalBitmap.Width];
+
+ // Determine Left
+ int newLeft = -1;
+ for (int x = 0; x < originalBitmap.Width; x++)
+ {
+ for (int y = 0; y < originalBitmap.Height; y++)
+ {
+ SKColor color = originalBitmap.GetPixel(x, y);
+ if (color != SKColors.White)
+ {
+ newLeft = x;
+ break;
+ }
+ }
+ if (newLeft != -1)
+ break;
+ }
+ // Determine Right
+ int newRight = -1;
+ for (int x = originalBitmap.Width - 1; x >= 0; x--)
+ {
+ for (int y = 0; y < originalBitmap.Height; y++)
+ {
+ SKColor color = originalBitmap.GetPixel(x, y);
+ if (color != SKColors.White)
+ {
+ newRight = x;
+ break;
+ }
+ }
+ if (newRight != -1)
+ break;
+ }
+ // Determine Bottom
+ int newBottom = -1;
+ for (int y = 0; y < originalBitmap.Height; y++)
+ {
+ for (int x = 0; x < originalBitmap.Width; x++)
+ {
+ SKColor color = originalBitmap.GetPixel(x, y);
+ if (color != SKColors.White)
+ {
+ newBottom = x;
+ break;
+ }
+ }
+ if (newBottom != -1)
+ break;
+ }
+ // Determine Top
+ int newTop = -1;
+ for (int y = originalBitmap.Height - 1; y >= 0; y--)
+ {
+ for (int x = 0; x < originalBitmap.Width; x++)
+ {
+ SKColor color = originalBitmap.GetPixel(x, y);
+ if (color != SKColors.White)
+ {
+ newTop = x;
+ break;
+ }
+ }
+ if (newTop != -1)
+ break;
+ }
+
+ return CropImage(bitmap, new SKRect(newLeft, newTop, newRight, newBottom));
+ }
+ catch
+ {
+ return bitmap.Clone();
+ }
+ }
+
+ ///
+ /// Add a colored border around the image.
+ ///
+ /// Original bitmap to add a border to.
+ /// Color of the border.
+ /// Width of the border in pixel.
+ /// IronSoftware.Drawing.AnyBitmap.
+ public static AnyBitmap AddBorder(this AnyBitmap bitmap, IronSoftware.Drawing.Color color, int width)
+ {
+ SKBitmap originalBitmap = bitmap;
+ int maxWidth = originalBitmap.Width + width * 2;
+ int maxHeight = originalBitmap.Height + width * 2;
+ SKBitmap toBitmap = new SKBitmap(maxWidth, maxHeight);
+
+ var ratioX = (double)maxWidth / originalBitmap.Width;
+ var ratioY = (double)maxHeight / originalBitmap.Height;
+ var scale = (float)Math.Min(ratioX, ratioY);
+
+ using (SKCanvas canvas = new SKCanvas(toBitmap))
+ {
+#if NETFRAMEWORK
+ canvas.SetMatrix(SKMatrix.MakeScale(scale, scale));
+#else
+ canvas.SetMatrix(SKMatrix.CreateScale(scale, scale));
+#endif
+ canvas.Clear(color);
+ int x = (toBitmap.Width - originalBitmap.Width) / 2;
+ int y = (toBitmap.Height - originalBitmap.Height) / 2;
+ canvas.DrawBitmap(bitmap, x, y);
+ canvas.ResetMatrix();
+ canvas.Flush();
+ }
+
+ return toBitmap;
+ }
+
+#region Private Method
+
+ private static CropRectangle ValidateCropArea(SKBitmap img, CropRectangle CropArea)
+ {
+ int maxWidth = img.Width;
+ int maxHeight = img.Height;
+
+ int cropAreaX = CropArea.X > 0 ? CropArea.X : 0;
+ int cropAreaY = CropArea.Y > 0 ? CropArea.Y : 0;
+ int cropAreaWidth = CropArea.Width > 0 ? CropArea.Width : img.Width;
+ int cropAreaHeight = CropArea.Height > 0 ? CropArea.Height : img.Height;
+
+ int croppedWidth = cropAreaX + cropAreaWidth;
+ int croppedHeight = cropAreaY + cropAreaHeight;
+
+ int newWidth = cropAreaWidth;
+ int newHeight = cropAreaHeight;
+ if (croppedWidth > maxWidth)
+ {
+ newWidth = maxWidth - cropAreaX;
+ }
+ if (croppedHeight > maxHeight)
+ {
+ newHeight = maxHeight - cropAreaY;
+ }
+ return new CropRectangle(cropAreaX, cropAreaY, newWidth, newHeight);
+ }
+#endregion
+ }
+}
diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronSoftware.Drawing.Common.csproj b/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronSoftware.Drawing.Common.csproj
index d69ef66..7144590 100644
--- a/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronSoftware.Drawing.Common.csproj
+++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronSoftware.Drawing.Common.csproj
@@ -1,16 +1,24 @@
-
- netstandard2.0
- 8
- True
-
+
+ net45;netstandard2.0
+ 8
+ True
+ 2022.6.2
+ 2022.6.2
+ 2022.6.2
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/SkewImageLib.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common/SkewImageLib.cs
new file mode 100644
index 0000000..54badb5
--- /dev/null
+++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/SkewImageLib.cs
@@ -0,0 +1,181 @@
+using SkiaSharp;
+using System;
+
+namespace IronSoftware.Drawing
+{
+ internal class SkewImageLib
+ {
+ // Representation of a line in the image.
+ private class HougLine
+ {
+ // Count of points in the line.
+ public int Count;
+ // Index in Matrix.
+ public int Index;
+ // The line is represented as all x,y that solve y*cos(alpha)-x*sin(alpha)=d
+ public double Alpha;
+ }
+
+
+ // The Bitmap
+ private static SKBitmap _internalBmp;
+
+ // The range of angles to search for lines
+ const double ALPHA_START = -20;
+ const double ALPHA_STEP = 0.2;
+ const int STEPS = 40 * 5;
+ const double STEP = 1;
+
+ // Precalculation of sin and cos.
+ private static double[] _sinA;
+ private static double[] _cosA;
+
+ // Range of d
+ private static double _min;
+
+
+ private static int _count;
+ // Count of points that fit in a line.
+ private static int[] _hMatrix;
+
+ // Calculate the skew angle of the image cBmp.
+ internal static double GetSkewAngle(SKBitmap bitmap)
+ {
+ _internalBmp = bitmap;
+
+ // Hough Transformation
+ Calc();
+
+ // Top 20 of the detected lines in the image.
+ HougLine[] hl = GetTop(20);
+
+ // Average angle of the lines
+ double sum = 0;
+ int count = 0;
+ for (int i = 0; i <= 19; i++)
+ {
+ sum += hl[i].Alpha;
+ count += 1;
+ }
+ return sum / count;
+ }
+
+ // Calculate the Count lines in the image with most points.
+ private static HougLine[] GetTop(int count)
+ {
+ HougLine[] hl = new HougLine[count];
+
+ for (int i = 0; i <= count - 1; i++)
+ {
+ hl[i] = new HougLine();
+ }
+ for (int i = 0; i <= _hMatrix.Length - 1; i++)
+ {
+ if (_hMatrix[i] > hl[count - 1].Count)
+ {
+ hl[count - 1].Count = _hMatrix[i];
+ hl[count - 1].Index = i;
+ int j = count - 1;
+ while (j > 0 && hl[j].Count > hl[j - 1].Count)
+ {
+ HougLine tmp = hl[j];
+ hl[j] = hl[j - 1];
+ hl[j - 1] = tmp;
+ j -= 1;
+ }
+ }
+ }
+
+ for (int i = 0; i <= count - 1; i++)
+ {
+ int dIndex = hl[i].Index / STEPS;
+ int alphaIndex = hl[i].Index - dIndex * STEPS;
+ hl[i].Alpha = GetAlpha(alphaIndex);
+ //hl[i].D = dIndex + _min;
+ }
+
+ return hl;
+ }
+
+
+ // Hough Transforamtion:
+ private static void Calc()
+ {
+ int hMin = _internalBmp.Height / 4;
+ int hMax = _internalBmp.Height * 3 / 4;
+
+ Init();
+ for (int y = hMin; y <= hMax; y++)
+ {
+ for (int x = 1; x <= _internalBmp.Width - 2; x++)
+ {
+ // Only lower edges are considered.
+ if (IsBlack(x, y))
+ {
+ if (!IsBlack(x, y + 1))
+ {
+ Calc(x, y);
+ }
+ }
+ }
+ }
+ }
+
+ // Calculate all lines through the point (x,y).
+ private static void Calc(int x, int y)
+ {
+ int alpha;
+
+ for (alpha = 0; alpha <= STEPS - 1; alpha++)
+ {
+ double d = y * _cosA[alpha] - x * _sinA[alpha];
+ int calculatedIndex = (int)CalcDIndex(d);
+ int index = calculatedIndex * STEPS + alpha;
+ try
+ {
+ _hMatrix[index] += 1;
+ }
+ catch (Exception ex)
+ {
+ System.Diagnostics.Debug.WriteLine(ex.ToString());
+ }
+ }
+ }
+ private static double CalcDIndex(double d)
+ {
+ return Convert.ToInt32(d - _min);
+ }
+ private static bool IsBlack(int x, int y)
+ {
+ SKColor c = _internalBmp.GetPixel(x, y);
+ double luminance = (c.Red * 0.299) + (c.Green * 0.587) + (c.Blue * 0.114);
+ return luminance < 140;
+ }
+
+ private static void Init()
+ {
+ // Precalculation of sin and cos.
+ _cosA = new double[STEPS];
+ _sinA = new double[STEPS];
+
+ for (int i = 0; i < STEPS; i++)
+ {
+ double angle = GetAlpha(i) * Math.PI / 180.0;
+ _sinA[i] = Math.Sin(angle);
+ _cosA[i] = Math.Cos(angle);
+ }
+
+ // Range of d:
+ _min = -_internalBmp.Width;
+ _count = (int)(2 * (_internalBmp.Width + _internalBmp.Height) / STEP);
+ _hMatrix = new int[_count * STEPS];
+
+
+ }
+
+ private static double GetAlpha(int index)
+ {
+ return ALPHA_START + index * ALPHA_STEP;
+ }
+ }
+}