From a8bd09ddac5f03a05d130c9489fcf8fec99424ec Mon Sep 17 00:00:00 2001 From: James Jackson-South Date: Wed, 7 Oct 2015 12:26:40 +1100 Subject: [PATCH] Cleanup implicit operators Former-commit-id: 32778027aa323d13eb7889099e7a9f3c81e830a9 Former-commit-id: de756ae4ea95b20120cea8e91300b0026684c5ba Former-commit-id: 4509569039b8c45479b9f7cd99f2bba9583d0901 --- src/ImageProcessor/Colors/Bgra.cs | 102 +++++++++++++++++- src/ImageProcessor/Colors/Hsv.cs | 72 ------------- src/ImageProcessor/Colors/YCbCr.cs | 29 +---- src/ImageProcessor/Filters/Contrast.cs | 6 +- .../Formats/Gif/Quantizer/OctreeQuantizer.cs | 10 +- 5 files changed, 112 insertions(+), 107 deletions(-) diff --git a/src/ImageProcessor/Colors/Bgra.cs b/src/ImageProcessor/Colors/Bgra.cs index ecf275a86..db814cf6b 100644 --- a/src/ImageProcessor/Colors/Bgra.cs +++ b/src/ImageProcessor/Colors/Bgra.cs @@ -18,7 +18,7 @@ namespace ImageProcessor /// /// Represents a that has B, G, R, and A values set to zero. /// - public static readonly Bgra Empty; + public static readonly Bgra Empty = default(Bgra); /// /// Represents a transparent that has B, G, R, and A values set to 255, 255, 255, 0. @@ -65,6 +65,11 @@ namespace ImageProcessor [FieldOffset(0)] public readonly int BGRA; + /// + /// The epsilon for comparing floating point numbers. + /// + private const float Epsilon = 0.0001f; + /// /// Initializes a new instance of the struct. /// @@ -173,6 +178,101 @@ namespace ImageProcessor [EditorBrowsable(EditorBrowsableState.Never)] public bool IsEmpty => this.B == 0 && this.G == 0 && this.R == 0 && this.A == 0; + /// + /// Allows the implicit conversion of an instance of to a + /// . + /// + /// + /// The instance of to convert. + /// + /// + /// An instance of . + /// + public static implicit operator Bgra(Hsv color) + { + float s = color.S / 100; + float v = color.V / 100; + + if (Math.Abs(s) < Epsilon) + { + byte component = (byte)(v * 255); + return new Bgra(component, component, component, 255); + } + + float h = (Math.Abs(color.H - 360) < Epsilon) ? 0 : color.H / 60; + int i = (int)Math.Truncate(h); + float f = h - i; + + float p = v * (1.0f - s); + float q = v * (1.0f - (s * f)); + float t = v * (1.0f - (s * (1.0f - f))); + + float r, g, b; + switch (i) + { + case 0: + r = v; + g = t; + b = p; + break; + + case 1: + r = q; + g = v; + b = p; + break; + + case 2: + r = p; + g = v; + b = t; + break; + + case 3: + r = p; + g = q; + b = v; + break; + + case 4: + r = t; + g = p; + b = v; + break; + + default: + r = v; + g = p; + b = q; + break; + } + + return new Bgra((byte)Math.Round(b * 255), (byte)Math.Round(g * 255), (byte)Math.Round(r * 255)); + } + + /// + /// Allows the implicit conversion of an instance of to a + /// . + /// + /// + /// The instance of to convert. + /// + /// + /// An instance of . + /// + public static implicit operator Bgra(YCbCr color) + { + float y = color.Y; + float cb = color.Cb - 128; + float cr = color.Cr - 128; + + byte b = (y + (1.772 * cb)).ToByte(); + byte g = (y - (0.34414 * cb) - (0.71414 * cr)).ToByte(); + byte r = (y + (1.402 * cr)).ToByte(); + + return new Bgra(b, g, r, 255); + } + /// /// Compares two objects. The result specifies whether the values /// of the , , , and diff --git a/src/ImageProcessor/Colors/Hsv.cs b/src/ImageProcessor/Colors/Hsv.cs index cd14f6fa4..352556fae 100644 --- a/src/ImageProcessor/Colors/Hsv.cs +++ b/src/ImageProcessor/Colors/Hsv.cs @@ -118,78 +118,6 @@ namespace ImageProcessor return new Hsv(h, s * 100, v * 100); } - /// - /// Allows the implicit conversion of an instance of to a - /// . - /// - /// - /// The instance of to convert. - /// - /// - /// An instance of . - /// - public static implicit operator Bgra(Hsv color) - { - float s = color.S / 100; - float v = color.V / 100; - - if (Math.Abs(s) < Epsilon) - { - byte component = (byte)(v * 255); - return new Bgra(component, component, component, 255); - } - - float h = (Math.Abs(color.H - 360) < Epsilon) ? 0 : color.H / 60; - int i = (int)Math.Truncate(h); - float f = h - i; - - float p = v * (1.0f - s); - float q = v * (1.0f - (s * f)); - float t = v * (1.0f - (s * (1.0f - f))); - - float r, g, b; - switch (i) - { - case 0: - r = v; - g = t; - b = p; - break; - - case 1: - r = q; - g = v; - b = p; - break; - - case 2: - r = p; - g = v; - b = t; - break; - - case 3: - r = p; - g = q; - b = v; - break; - - case 4: - r = t; - g = p; - b = v; - break; - - default: - r = v; - g = p; - b = q; - break; - } - - return new Bgra((byte)Math.Round(b * 255), (byte)Math.Round(g * 255), (byte)Math.Round(r * 255)); - } - /// /// Compares two objects. The result specifies whether the values /// of the , , and diff --git a/src/ImageProcessor/Colors/YCbCr.cs b/src/ImageProcessor/Colors/YCbCr.cs index 01a041df4..e16400ec2 100644 --- a/src/ImageProcessor/Colors/YCbCr.cs +++ b/src/ImageProcessor/Colors/YCbCr.cs @@ -51,9 +51,9 @@ namespace ImageProcessor /// The cr chroma component. public YCbCr(float y, float cb, float cr) { - this.Y = y.Clamp(0, 255); - this.Cb = cb.Clamp(0, 255); - this.Cr = cr.Clamp(0, 255); + this.Y = y.ToByte(); + this.Cb = cb.ToByte(); + this.Cr = cr.ToByte(); } /// @@ -87,29 +87,6 @@ namespace ImageProcessor return new YCbCr(y, cb, cr); } - /// - /// Allows the implicit conversion of an instance of to a - /// . - /// - /// - /// The instance of to convert. - /// - /// - /// An instance of . - /// - public static implicit operator Bgra(YCbCr color) - { - float y = color.Y; - float cb = color.Cb - 128; - float cr = color.Cr - 128; - - byte b = Convert.ToByte((y + (1.772 * cb)).Clamp(0, 255)); - byte g = Convert.ToByte((y - (0.34414 * cb) - (0.71414 * cr)).Clamp(0, 255)); - byte r = Convert.ToByte((y + (1.402 * cr)).Clamp(0, 255)); - - return new Bgra(b, g, r, 255); - } - /// /// Compares two objects. The result specifies whether the values /// of the , , and diff --git a/src/ImageProcessor/Filters/Contrast.cs b/src/ImageProcessor/Filters/Contrast.cs index 076f0dfa5..291b1c6d2 100644 --- a/src/ImageProcessor/Filters/Contrast.cs +++ b/src/ImageProcessor/Filters/Contrast.cs @@ -51,21 +51,21 @@ namespace ImageProcessor.Filters r *= contrast; r += 0.5; r *= 255; - r = r.Clamp(0, 255); + r = r.ToByte(); double g = color.G / 255.0; g -= 0.5; g *= contrast; g += 0.5; g *= 255; - g = g.Clamp(0, 255); + g = g.ToByte(); double b = color.B / 255.0; b -= 0.5; b *= contrast; b += 0.5; b *= 255; - b = b.Clamp(0, 255); + b = b.ToByte(); target[x, y] = new Bgra((byte)b, (byte)g, (byte)r, color.A); } diff --git a/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs b/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs index bdf9cf767..e4cf98a37 100644 --- a/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs +++ b/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs @@ -40,7 +40,7 @@ namespace ImageProcessor.Formats } /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The Octree quantizer is a two pass algorithm. The initial pass sets up the Octree, @@ -157,7 +157,7 @@ namespace ImageProcessor.Formats private int previousColor; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// /// /// The maximum number of significant bits in the image @@ -465,9 +465,9 @@ namespace ImageProcessor.Formats // Consume the next palette index this.paletteIndex = index++; - byte r = (byte)(this.red / this.pixelCount).Clamp(0, 255); - byte g = (byte)(this.green / this.pixelCount).Clamp(0, 255); - byte b = (byte)(this.blue / this.pixelCount).Clamp(0, 255); + byte r = (this.red / this.pixelCount).ToByte(); + byte g = (this.green / this.pixelCount).ToByte(); + byte b = (this.blue / this.pixelCount).ToByte(); // And set the color of the palette entry palette.Add(new Bgra(b, g, r));