From a3cc5c034ba8b6691636cc87b8c35884785c2a80 Mon Sep 17 00:00:00 2001 From: Meee Date: Wed, 15 Jun 2022 15:43:16 +0700 Subject: [PATCH 1/3] Add IronSoftware.Drawing.Color --- .../IronSoftware.Drawing.Common/Color.cs | 915 ++++++++++++++++++ 1 file changed, 915 insertions(+) create mode 100644 IronSoftware.Drawing/IronSoftware.Drawing.Common/Color.cs diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/Color.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common/Color.cs new file mode 100644 index 0000000..a37e413 --- /dev/null +++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/Color.cs @@ -0,0 +1,915 @@ +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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #FFF0F8FF. + /// + /// 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 #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 System.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 System.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 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")); + } + + /// + /// L* is a value from 0 (black) to 100 (white) where 50 is the perceptual "middle grey". + /// L* = 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 + } +} From ef89f664047f65ac76041af3fa42ceda1347089c Mon Sep 17 00:00:00 2001 From: Meee Date: Wed, 15 Jun 2022 15:43:29 +0700 Subject: [PATCH 2/3] Add Width and Height for AnyBitmap --- .../IronSoftware.Drawing.Common/AnyBitmap.cs | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs index 05ad7a1..0f82370 100644 --- a/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs +++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/AnyBitmap.cs @@ -14,6 +14,30 @@ 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 /// From c7f52a33bf6cc320e1aaae02ed28384aea58d75f Mon Sep 17 00:00:00 2001 From: Meee Date: Wed, 15 Jun 2022 15:44:42 +0700 Subject: [PATCH 3/3] Add image processing functions --- .../IronSoftware.Drawing.Common/IronBitmap.cs | 295 ++++++++++++++++++ .../SkewImageLib.cs | 181 +++++++++++ 2 files changed, 476 insertions(+) create mode 100644 IronSoftware.Drawing/IronSoftware.Drawing.Common/IronBitmap.cs create mode 100644 IronSoftware.Drawing/IronSoftware.Drawing.Common/SkewImageLib.cs diff --git a/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronBitmap.cs b/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronBitmap.cs new file mode 100644 index 0000000..27b556e --- /dev/null +++ b/IronSoftware.Drawing/IronSoftware.Drawing.Common/IronBitmap.cs @@ -0,0 +1,295 @@ +using SkiaSharp; +using System; + +namespace IronSoftware.Drawing +{ + public static class IronBitmap + { + /// + /// Resize an image with scale. + /// + /// 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 + canvas.SetMatrix(SKMatrix.MakeScale(scale, scale)); + canvas.DrawBitmap(originalBitmap, 0, 0); + canvas.ResetMatrix(); + canvas.Flush(); + } + + return toBitmap; + } + + /// + /// Resize an image with width and height. + /// + /// Original bitmap to resize. + /// Width ot the new resized image. + /// Height ot 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 ot the new resized image. + /// Height ot the new resized image. + /// Ratio of new image 0 - 1. + /// IronSoftware.Drawing.AnyBitmap. + public static AnyBitmap Resize(this AnyBitmap bitmap, int width, int height, float ratio) + { + SKBitmap originalBitmap = bitmap; + SKBitmap toBitmap = new SKBitmap(width, height, originalBitmap.ColorType, originalBitmap.AlphaType); + + using (SKCanvas canvas = new SKCanvas(toBitmap)) + { + // Draw a bitmap rescaled + canvas.SetMatrix(SKMatrix.MakeScale(ratio, ratio)); + 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): Try to find the image 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; + } + + /// + /// Find angle of the image. + /// + /// Original bitmap to resize. + /// Angle of the image in double. + 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 border to the image. + /// + /// Original bitmap to trim. + /// Background color of the border. + /// Size of the border in pixel. + /// IronSoftware.Drawing.AnyBitmap. + public static AnyBitmap AddBorder(this AnyBitmap bitmap, IronSoftware.Drawing.Color color, int size) + { + SKBitmap originalBitmap = bitmap; + int maxWidth = originalBitmap.Width + size * 2; + int maxHeight = originalBitmap.Height + size * 2; + SKBitmap toBitmap = new SKBitmap(maxWidth, maxHeight); + + var ratioX = (double)maxWidth / originalBitmap.Width; + var ratioY = (double)maxHeight / originalBitmap.Height; + var ratio = (float)Math.Min(ratioX, ratioY); + + using (SKCanvas canvas = new SKCanvas(toBitmap)) + { + canvas.SetMatrix(SKMatrix.MakeScale(ratio, ratio)); + 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/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; + } + } +}