diff --git a/src/ImageProcessorCore/Colors/Color.cs b/src/ImageProcessorCore/Colors/Color.cs index fc5c0a210..3a21c2130 100644 --- a/src/ImageProcessorCore/Colors/Color.cs +++ b/src/ImageProcessorCore/Colors/Color.cs @@ -160,7 +160,7 @@ namespace ImageProcessorCore public Color(float r, float g, float b, float a = 1) : this() { - Pack(ref r, ref g, ref b, ref a); + this.packedValue = Pack(r, g, b, a); } /// @@ -172,8 +172,7 @@ namespace ImageProcessorCore public Color(Vector3 vector) : this() { - float a = 1; - Pack(ref vector.X, ref vector.Y, ref vector.Z, ref a); + this.packedValue = Pack(ref vector); } /// @@ -282,25 +281,39 @@ namespace ImageProcessorCore } /// - /// Packs a vector into a uint. + /// Packs a into a uint. /// /// The vector containing the values to pack. /// The ulong containing the packed values. private static uint Pack(ref Vector4 vector) { - // TODO: Maybe use Vector4.Clamp() instead. - return (uint)((byte)Math.Round(vector.X * Max).Clamp(Min, Max) - | ((byte)Math.Round(vector.Y * Max).Clamp(Min, Max) << 8) - | (byte)Math.Round(vector.Z * Max).Clamp(Min, Max) << 16 - | (byte)Math.Round(vector.W * Max).Clamp(Min, Max) << 24); + return Pack(vector.X, vector.Y, vector.Z, vector.W); + } + + /// + /// Packs a into a uint. + /// + /// The vector containing the values to pack. + /// The ulong containing the packed values. + private static uint Pack(ref Vector3 vector) + { + return Pack(vector.X, vector.Y, vector.Z, 1); } - private static uint Pack(ref float x, ref float y, ref float z, ref float w) + /// + /// Packs the four floats into a uint. + /// + /// The x-component + /// The y-component + /// The z-component + /// The w-component + /// The + private static uint Pack(float x, float y, float z, float w) { - return (uint)((byte)Math.Round(x * Max).Clamp(Min, Max) - | ((byte)Math.Round(y * Max).Clamp(Min, Max) << 8) - | (byte)Math.Round(z * Max).Clamp(Min, Max) << 16 - | (byte)Math.Round(w * Max).Clamp(Min, Max) << 24); + return (uint)((byte)Math.Round(x.Clamp(0, 1) * Max) + | ((byte)Math.Round(y.Clamp(0, 1) * Max) << 8) + | (byte)Math.Round(z.Clamp(0, 1) * Max) << 16 + | (byte)Math.Round(w.Clamp(0, 1) * Max) << 24); } /// diff --git a/src/ImageProcessorCore/Colors/PackedVector/IPackedVector.cs b/src/ImageProcessorCore/Colors/PackedVector/IPackedVector.cs index 3ccf473f5..a0d71e4e2 100644 --- a/src/ImageProcessorCore/Colors/PackedVector/IPackedVector.cs +++ b/src/ImageProcessorCore/Colors/PackedVector/IPackedVector.cs @@ -16,22 +16,6 @@ namespace ImageProcessorCore where TPacked : struct { TPacked PackedValue { get; set; } - - ///// - ///// Directly gets the packed representation of the packed vector. - ///// Typically packed in least to greatest significance order. - ///// - ///// - ///// The . - ///// - //TPacked GetPackedValue(); - - ///// - ///// Directly sets the packed representation of the packed vector. - ///// Typically packed in least to greatest significance order. - ///// - ///// The packed value. - //void SetPackedValue(TPacked value); } /// @@ -45,14 +29,14 @@ namespace ImageProcessorCore /// The vector to create the packed representation from. void PackFromVector4(Vector4 vector); - /// - /// Sets the packed representation from a . - /// - /// The x-component to create the packed representation from. - /// The y-component to create the packed representation from. - /// The z-component to create the packed representation from. - /// The w-component to create the packed representation from. - void PackFromBytes(byte x, byte y, byte z, byte w); + ///// + ///// Sets the packed representation from a . + ///// + ///// The x-component to create the packed representation from. + ///// The y-component to create the packed representation from. + ///// The z-component to create the packed representation from. + ///// The w-component to create the packed representation from. + //void PackFromBytes(byte x, byte y, byte z, byte w); /// /// Expands the packed representation into a . @@ -61,12 +45,12 @@ namespace ImageProcessorCore /// The . Vector4 ToVector4(); - /// - /// Expands the packed representation into a . - /// The bytes are typically expanded in least to greatest significance order. - /// Red -> Green -> Blue -> Alpha - /// - /// The . - byte[] ToBytes(); + ///// + ///// Expands the packed representation into a . + ///// The bytes are typically expanded in least to greatest significance order. + ///// Red -> Green -> Blue -> Alpha + ///// + ///// The . + //byte[] ToBytes(); } } diff --git a/src/ImageProcessorCore/Common/Helpers/ImageMaths.cs b/src/ImageProcessorCore/Common/Helpers/ImageMaths.cs index f35684139..19da0af18 100644 --- a/src/ImageProcessorCore/Common/Helpers/ImageMaths.cs +++ b/src/ImageProcessorCore/Common/Helpers/ImageMaths.cs @@ -180,19 +180,19 @@ namespace ImageProcessorCore switch (channel) { case RgbaComponent.R: - delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToBytes()[0] - b) > Epsilon; + delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToVector4().X - b) > Epsilon; break; case RgbaComponent.G: - delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToBytes()[1] - b) > Epsilon; + delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToVector4().Y - b) > Epsilon; break; case RgbaComponent.B: - delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToBytes()[2] - b) > Epsilon; + delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToVector4().Z - b) > Epsilon; break; default: - delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToBytes()[3] - b) > Epsilon; + delegateFunc = (pixels, x, y, b) => Math.Abs(pixels[x, y].ToVector4().W - b) > Epsilon; break; } diff --git a/src/ImageProcessorCore/Filters/DetectEdges.cs b/src/ImageProcessorCore/Filters/DetectEdges.cs index 9e906fcf7..d306badbb 100644 --- a/src/ImageProcessorCore/Filters/DetectEdges.cs +++ b/src/ImageProcessorCore/Filters/DetectEdges.cs @@ -118,7 +118,7 @@ namespace ImageProcessorCore break; default: - processor = new ScharrProcessor { Grayscale = grayscale }; + processor = new SobelProcessor { Grayscale = grayscale }; break; } diff --git a/src/ImageProcessorCore/Filters/Processors/ColorMatrix/LomographProcessor.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/LomographProcessor.cs index 10de7109c..ba2cee964 100644 --- a/src/ImageProcessorCore/Filters/Processors/ColorMatrix/LomographProcessor.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/LomographProcessor.cs @@ -31,7 +31,7 @@ namespace ImageProcessorCore.Processors protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) { TColor packed = default(TColor); - packed.PackFromBytes(0, 10, 0, 255); // Very dark (mostly black) lime green. + packed.PackFromVector4(new Color(0, 10, 0).ToVector4()); // Very dark (mostly black) lime green. new VignetteProcessor { VignetteColor = packed }.Apply(target, target, sourceRectangle); } } diff --git a/src/ImageProcessorCore/Filters/Processors/ColorMatrix/PolaroidProcessor.cs b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/PolaroidProcessor.cs index 956896c64..b28838637 100644 --- a/src/ImageProcessorCore/Filters/Processors/ColorMatrix/PolaroidProcessor.cs +++ b/src/ImageProcessorCore/Filters/Processors/ColorMatrix/PolaroidProcessor.cs @@ -37,11 +37,11 @@ namespace ImageProcessorCore.Processors protected override void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle) { TColor packedV = default(TColor); - packedV.PackFromBytes(102, 34, 0, 255); // Very dark orange [Brown tone] + packedV.PackFromVector4(new Color(102, 34, 0).ToVector4()); // Very dark orange [Brown tone] new VignetteProcessor { VignetteColor = packedV }.Apply(target, target, sourceRectangle); TColor packedG = default(TColor); - packedG.PackFromBytes(255, 153, 102, 178); // Light orange + packedG.PackFromVector4(new Color(255, 153, 102, 178).ToVector4()); // Light orange new GlowProcessor { GlowColor = packedG, Radius = target.Width / 4F }.Apply(target, target, sourceRectangle); } } diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs b/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs index 82d7823f4..cd3e0e56e 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs @@ -243,7 +243,7 @@ namespace ImageProcessorCore.Formats // Stored in b-> g-> r order. TColor packed = default(TColor); - packed.PackFromBytes(colors[colorIndex + 2], colors[colorIndex + 1], colors[colorIndex], 255); + packed.PackFromVector4(new Color(colors[colorIndex + 2], colors[colorIndex + 1], colors[colorIndex]).ToVector4()); imageData[arrayOffset] = packed; } } @@ -295,7 +295,7 @@ namespace ImageProcessorCore.Formats // Stored in b-> g-> r order. TColor packed = default(TColor); - packed.PackFromBytes(r, g, b, 255); + packed.PackFromVector4(new Color(r, g, b).ToVector4()); imageData[arrayOffset] = packed; } }); @@ -333,10 +333,9 @@ namespace ImageProcessorCore.Formats int offset = rowOffset + (x * 3); int arrayOffset = ((row * width) + x); - // We divide by 255 as we will store the colors in our floating point format. // Stored in b-> g-> r-> a order. TColor packed = default(TColor); - packed.PackFromBytes(data[offset + 2], data[offset + 1], data[offset], 255); + packed.PackFromVector4(new Color(data[offset + 2], data[offset + 1], data[offset]).ToVector4()); imageData[arrayOffset] = packed; } }); @@ -376,7 +375,7 @@ namespace ImageProcessorCore.Formats // Stored in b-> g-> r-> a order. TColor packed = default(TColor); - packed.PackFromBytes(data[offset + 2], data[offset + 1], data[offset], data[offset + 3]); + packed.PackFromVector4(new Color(data[offset + 2], data[offset + 1], data[offset], data[offset + 3]).ToVector4()); imageData[arrayOffset] = packed; } }); diff --git a/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs index 5b959d844..441ffc4a3 100644 --- a/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs +++ b/src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs @@ -160,8 +160,8 @@ namespace ImageProcessorCore.Formats for (int x = 0; x < pixels.Width; x++) { // Convert back to b-> g-> r-> a order. - byte[] bytes = pixels[x, y].ToBytes(); - writer.Write(new[] { bytes[2], bytes[1], bytes[0], bytes[3] }); + Color color = new Color(pixels[x, y].ToVector4()); + writer.Write(new[] { color.B, color.G, color.R, color.A }); } // Pad @@ -177,7 +177,7 @@ namespace ImageProcessorCore.Formats /// /// The pixel format. /// The packed format. uint, long, float./// The containing the stream to write to. - /// The containing pixel data. + /// The containing pixel data. private void Write24Bit(EndianBinaryWriter writer, PixelAccessor pixels) where TColor : IPackedVector where TPacked : struct @@ -187,8 +187,8 @@ namespace ImageProcessorCore.Formats for (int x = 0; x < pixels.Width; x++) { // Convert back to b-> g-> r order. - byte[] bytes = pixels[x, y].ToBytes(); - writer.Write(new[] { bytes[2], bytes[1], bytes[0] }); + Color color = new Color(pixels[x, y].ToVector4()); + writer.Write(new[] { color.B, color.G, color.R }); } // Pad diff --git a/src/ImageProcessorCore/Formats/Gif/GifDecoderCore.cs b/src/ImageProcessorCore/Formats/Gif/GifDecoderCore.cs index d37bca929..fbd421ccf 100644 --- a/src/ImageProcessorCore/Formats/Gif/GifDecoderCore.cs +++ b/src/ImageProcessorCore/Formats/Gif/GifDecoderCore.cs @@ -358,9 +358,8 @@ namespace ImageProcessorCore.Formats { // Stored in r-> g-> b-> a order. int indexOffset = index * 3; - TColor pixel = default(TColor); - pixel.PackFromBytes(colorTable[indexOffset], colorTable[indexOffset + 1], colorTable[indexOffset + 2], 255); + pixel.PackFromVector4(new Color(colorTable[indexOffset], colorTable[indexOffset + 1], colorTable[indexOffset + 2]).ToVector4()); this.currentFrame[offset] = pixel; } diff --git a/src/ImageProcessorCore/Formats/Gif/GifEncoderCore.cs b/src/ImageProcessorCore/Formats/Gif/GifEncoderCore.cs index cf4d39a89..b73a5bab5 100644 --- a/src/ImageProcessorCore/Formats/Gif/GifEncoderCore.cs +++ b/src/ImageProcessorCore/Formats/Gif/GifEncoderCore.cs @@ -281,11 +281,11 @@ namespace ImageProcessorCore.Formats i => { int offset = i * 3; - byte[] color = palette[i].ToBytes(); + Color color = new Color(palette[i].ToVector4()); - colorTable[offset] = color[0]; - colorTable[offset + 1] = color[1]; - colorTable[offset + 2] = color[2]; + colorTable[offset] = color.R; + colorTable[offset + 1] = color.G; + colorTable[offset + 2] = color.B; }); writer.Write(colorTable, 0, colorTableLength); diff --git a/src/ImageProcessorCore/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id b/src/ImageProcessorCore/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id index bd65b8702..45afa1afc 100644 --- a/src/ImageProcessorCore/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id +++ b/src/ImageProcessorCore/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id @@ -1 +1 @@ -d6ce5dd6236ac6ef9ba570fb4e57e81c06bbb854 \ No newline at end of file +508fcf1910c42f4e080fcfd9c9f22ba724c1990c \ No newline at end of file diff --git a/src/ImageProcessorCore/Formats/Jpg/JpegEncoderCore.cs b/src/ImageProcessorCore/Formats/Jpg/JpegEncoderCore.cs index 783406a28..baab490cf 100644 --- a/src/ImageProcessorCore/Formats/Jpg/JpegEncoderCore.cs +++ b/src/ImageProcessorCore/Formats/Jpg/JpegEncoderCore.cs @@ -2,6 +2,9 @@ // Copyright (c) James Jackson-South and contributors. // Licensed under the Apache License, Version 2.0. // + +using System.Numerics; + namespace ImageProcessorCore.Formats { using System; @@ -349,10 +352,7 @@ namespace ImageProcessorCore.Formats { for (int i = 0; i < 8; i++) { - // Bytes are expected in r->g->b->a oder. - byte[] pixel = pixels[Math.Min(x + i, xmax), Math.Min(y + j, ymax)].ToBytes(); - - YCbCr color = new Color(pixel[0], pixel[1], pixel[2], pixel[3]); + YCbCr color = new Color(pixels[Math.Min(x + i, xmax), Math.Min(y + j, ymax)].ToVector4()); int index = (8 * j) + i; yBlock[index] = (int)color.Y; cbBlock[index] = (int)color.Cb; diff --git a/src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs b/src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs index 3cf8be40e..f9cc691cb 100644 --- a/src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs +++ b/src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs @@ -3,6 +3,8 @@ // Licensed under the Apache License, Version 2.0. // +using System.Numerics; + namespace ImageProcessorCore.Formats { using System; @@ -339,7 +341,7 @@ namespace ImageProcessorCore.Formats byte intensity = defilteredScanline[offset]; TColor color = default(TColor); - color.PackFromBytes(intensity, intensity, intensity, 255); + color.PackFromVector4(new Vector4(intensity, intensity, intensity, 255) / 255F); pixels[(row * this.header.Width) + x] = color; } @@ -355,7 +357,7 @@ namespace ImageProcessorCore.Formats byte alpha = defilteredScanline[offset + bytesPerSample]; TColor color = default(TColor); - color.PackFromBytes(intensity, intensity, intensity, alpha); + color.PackFromVector4(new Vector4(intensity, intensity, intensity, alpha) / 255F); pixels[(row * this.header.Width) + x] = color; } @@ -382,7 +384,7 @@ namespace ImageProcessorCore.Formats byte r = this.palette[pixelOffset]; byte g = this.palette[pixelOffset + 1]; byte b = this.palette[pixelOffset + 2]; - color.PackFromBytes(r, g, b, a); + color.PackFromVector4(new Vector4(r, g, b, a) / 255F); } pixels[offset] = color; @@ -401,7 +403,7 @@ namespace ImageProcessorCore.Formats byte b = this.palette[pixelOffset + 2]; TColor color = default(TColor); - color.PackFromBytes(r, g, b, 255); + color.PackFromVector4(new Vector4(r, g, b, 255) / 255F); pixels[offset] = color; } } @@ -419,7 +421,7 @@ namespace ImageProcessorCore.Formats byte b = defilteredScanline[offset + 2 * bytesPerSample]; TColor color = default(TColor); - color.PackFromBytes(r, g, b, 255); + color.PackFromVector4(new Vector4(r, g, b, 255) / 255F); pixels[(row * this.header.Width) + x] = color; } @@ -437,7 +439,7 @@ namespace ImageProcessorCore.Formats byte a = defilteredScanline[offset + 3 * bytesPerSample]; TColor color = default(TColor); - color.PackFromBytes(r, g, b, a); + color.PackFromVector4(new Vector4(r, g, b, a) / 255F); pixels[(row * this.header.Width) + x] = color; } diff --git a/src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs b/src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs index f666f0f0e..0613c26ad 100644 --- a/src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs +++ b/src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs @@ -264,15 +264,17 @@ namespace ImageProcessorCore.Formats Bootstrapper.Instance.ParallelOptions, y => { - // Color data is stored in r -> g -> b -> a order for (int x = 0; x < this.width; x++) { int dataOffset = (y * stride) + (x * this.bytesPerPixel); - byte[] source = pixels[x, y].ToBytes(); + Color source = new Color(pixels[x, y].ToVector4()); - for (int i = 0; i < this.bytesPerPixel; i++) + this.pixelData[dataOffset] = source.R; + this.pixelData[dataOffset + 1] = source.G; + this.pixelData[dataOffset + 2] = source.B; + if (this.bytesPerPixel == 4) { - this.pixelData[dataOffset + i] = source[i]; + this.pixelData[dataOffset + 3] = source.A; } } }); @@ -511,12 +513,10 @@ namespace ImageProcessorCore.Formats i => { int offset = i * 3; - byte[] color = palette[i].ToBytes(); - - // Expected format r->g->b - colorTable[offset] = color[0]; - colorTable[offset + 1] = color[1]; - colorTable[offset + 2] = color[2]; + Color color = new Color(palette[i].ToVector4()); + colorTable[offset] = color.R; + colorTable[offset + 1] = color.G; + colorTable[offset + 2] = color.B; }); this.WriteChunk(stream, PngChunkTypes.Palette, colorTable); diff --git a/src/ImageProcessorCore/Quantizers/Octree/OctreeQuantizer.cs b/src/ImageProcessorCore/Quantizers/Octree/OctreeQuantizer.cs index 42de023b0..ac5c142f9 100644 --- a/src/ImageProcessorCore/Quantizers/Octree/OctreeQuantizer.cs +++ b/src/ImageProcessorCore/Quantizers/Octree/OctreeQuantizer.cs @@ -86,7 +86,7 @@ namespace ImageProcessorCore.Quantizers byte paletteIndex = (byte)this.colors; // Get the palette index if it's transparency meets criterea. - if (pixel.ToBytes()[3] > this.Threshold) + if (new Color(pixel.ToVector4()).A > this.Threshold) { paletteIndex = (byte)this.octree.GetPaletteIndex(pixel); } @@ -397,10 +397,10 @@ namespace ImageProcessorCore.Quantizers { // Go to the next level down in the tree int shift = 7 - level; - byte[] components = pixel.ToBytes(); - int index = ((components[2] & Mask[level]) >> (shift - 2)) | - ((components[1] & Mask[level]) >> (shift - 1)) | - ((components[0] & Mask[level]) >> shift); + Color color = new Color(pixel.ToVector4()); + int index = ((color.B & Mask[level]) >> (shift - 2)) | + ((color.G & Mask[level]) >> (shift - 1)) | + ((color.R & Mask[level]) >> shift); OctreeNode child = this.children[index]; @@ -468,7 +468,7 @@ namespace ImageProcessorCore.Quantizers // And set the color of the palette entry TColor pixel = default(TColor); - pixel.PackFromBytes(r, g, b, 255); + pixel.PackFromVector4(new Color(r, g, b).ToVector4()); palette.Add(pixel); } else @@ -487,12 +487,8 @@ namespace ImageProcessorCore.Quantizers /// /// Return the palette index for the passed color /// - /// - /// The representing the pixel. - /// - /// - /// The level. - /// + /// The representing the pixel. + /// The level. /// /// The representing the index of the pixel in the palette. /// @@ -503,10 +499,10 @@ namespace ImageProcessorCore.Quantizers if (!this.leaf) { int shift = 7 - level; - byte[] components = pixel.ToBytes(); - int pixelIndex = ((components[2] & Mask[level]) >> (shift - 2)) | - ((components[1] & Mask[level]) >> (shift - 1)) | - ((components[0] & Mask[level]) >> shift); + Color color = new Color(pixel.ToVector4()); + int pixelIndex = ((color.B & Mask[level]) >> (shift - 2)) | + ((color.G & Mask[level]) >> (shift - 1)) | + ((color.R & Mask[level]) >> shift); if (this.children[pixelIndex] != null) { @@ -530,10 +526,10 @@ namespace ImageProcessorCore.Quantizers public void Increment(TColor pixel) { this.pixelCount++; - byte[] components = pixel.ToBytes(); - this.red += components[0]; - this.green += components[1]; - this.blue += components[2]; + Color color = new Color(pixel.ToVector4()); + this.red += color.R; + this.green += color.G; + this.blue += color.B; } } } diff --git a/src/ImageProcessorCore/Quantizers/Palette/PaletteQuantizer.cs b/src/ImageProcessorCore/Quantizers/Palette/PaletteQuantizer.cs index a07570535..0a3f12ba8 100644 --- a/src/ImageProcessorCore/Quantizers/Palette/PaletteQuantizer.cs +++ b/src/ImageProcessorCore/Quantizers/Palette/PaletteQuantizer.cs @@ -81,13 +81,13 @@ namespace ImageProcessorCore.Quantizers { // Not found - loop through the palette and find the nearest match. // Firstly check the alpha value - if less than the threshold, lookup the transparent color - byte[] bytes = pixel.ToBytes(); - if (!(bytes[3] > this.Threshold)) + Color color =new Color(pixel.ToVector4()); + if (!(color.A > this.Threshold)) { // Transparent. Lookup the first color with an alpha value of 0 for (int index = 0; index < this.colors.Length; index++) { - if (this.colors[index].ToBytes()[3] == 0) + if (new Color(this.colors[index].ToVector4()).A == 0) { colorIndex = (byte)index; this.TransparentIndex = colorIndex; @@ -99,17 +99,17 @@ namespace ImageProcessorCore.Quantizers { // Not transparent... int leastDistance = int.MaxValue; - int red = bytes[0]; - int green = bytes[1]; - int blue = bytes[2]; + int red = color.R; + int green = color.G; + int blue = color.B; // Loop through the entire palette, looking for the closest color match for (int index = 0; index < this.colors.Length; index++) { - byte[] paletteColor = this.colors[index].ToBytes(); - int redDistance = paletteColor[0] - red; - int greenDistance = paletteColor[1] - green; - int blueDistance = paletteColor[2] - blue; + Color paletteColor = new Color(this.colors[index].ToVector4()); + int redDistance = paletteColor.R - red; + int greenDistance = paletteColor.G - green; + int blueDistance = paletteColor.B - blue; int distance = (redDistance * redDistance) + (greenDistance * greenDistance) + diff --git a/src/ImageProcessorCore/Quantizers/Wu/WuQuantizer.cs b/src/ImageProcessorCore/Quantizers/Wu/WuQuantizer.cs index a1f6b8f3c..2ee802a5d 100644 --- a/src/ImageProcessorCore/Quantizers/Wu/WuQuantizer.cs +++ b/src/ImageProcessorCore/Quantizers/Wu/WuQuantizer.cs @@ -3,6 +3,8 @@ // Licensed under the Apache License, Version 2.0. // +using System.Numerics; + namespace ImageProcessorCore.Quantizers { using System; @@ -332,12 +334,12 @@ namespace ImageProcessorCore.Quantizers for (int x = 0; x < pixels.Width; x++) { // Colors are expected in r->g->b->a format - byte[] color = pixels[x, y].ToBytes(); + Color color = new Color(pixels[x, y].ToVector4()); - byte r = color[0]; - byte g = color[1]; - byte b = color[2]; - byte a = color[3]; + byte r = color.R; + byte g = color.G; + byte b = color.B; + byte a = color.A; int inr = r >> (8 - IndexBits); int ing = g >> (8 - IndexBits); @@ -745,7 +747,7 @@ namespace ImageProcessorCore.Quantizers byte a = (byte)(Volume(cube[k], this.vma) / weight); TColor color = default(TColor); - color.PackFromBytes(r, g, b, a); + color.PackFromVector4(new Vector4(r, g, b, a) / 255F); if (color.Equals(default(TColor))) { @@ -770,13 +772,13 @@ namespace ImageProcessorCore.Quantizers for (int x = 0; x < width; x++) { // Expected order r->g->b->a - byte[] color = imagePixels[x, y].ToBytes(); - int r = color[0] >> (8 - IndexBits); - int g = color[1] >> (8 - IndexBits); - int b = color[2] >> (8 - IndexBits); - int a = color[3] >> (8 - IndexAlphaBits); + Color color = new Color(imagePixels[x, y].ToVector4()); + int r = color.R >> (8 - IndexBits); + int g = color.G >> (8 - IndexBits); + int b = color.B >> (8 - IndexBits); + int a = color.A >> (8 - IndexAlphaBits); - if (transparentIndex > -1 && color[3] <= this.Threshold) + if (transparentIndex > -1 && color.A <= this.Threshold) { pixels[(y * width) + x] = (byte)transparentIndex; continue;