diff --git a/src/ImageProcessor/Colors/Color.cs b/src/ImageProcessor/Colors/Color.cs
index 482d2f9ac..abd3e8620 100644
--- a/src/ImageProcessor/Colors/Color.cs
+++ b/src/ImageProcessor/Colors/Color.cs
@@ -211,17 +211,7 @@ namespace ImageProcessor
///
/// Gets this color with the component values clamped from 0 to 1.
///
- public Color Limited
- {
- get
- {
- float r = this.R.Clamp(0, 1);
- float g = this.G.Clamp(0, 1);
- float b = this.B.Clamp(0, 1);
- float a = this.A.Clamp(0, 1);
- return new Color(r, g, b, a);
- }
- }
+ public Color Limited => new Color(Vector4.Clamp(this.backingVector, Vector4.Zero, Vector4.One));
///
/// Computes the product of multiplying a color by a given factor.
@@ -402,7 +392,7 @@ namespace ImageProcessor
public static Color FromNonPremultiplied(Color color)
{
float a = color.A;
- return new Color(color.R * a, color.G * a, color.B * a, a);
+ return new Color(color.backingVector * new Vector4(a, a, a, 1));
}
///
@@ -416,10 +406,10 @@ namespace ImageProcessor
float a = color.A;
if (Math.Abs(a) < Epsilon)
{
- return new Color(color.R, color.G, color.B, a);
+ return new Color(color.backingVector);
}
- return new Color(color.R / a, color.G / a, color.B / a, a);
+ return new Color(color.backingVector / new Vector4(a, a, a, 1));
}
///
diff --git a/src/ImageProcessor/Filters/Alpha.cs b/src/ImageProcessor/Filters/Alpha.cs
index e3f051b9a..9607fcbb0 100644
--- a/src/ImageProcessor/Filters/Alpha.cs
+++ b/src/ImageProcessor/Filters/Alpha.cs
@@ -6,6 +6,7 @@
namespace ImageProcessor.Filters
{
using System;
+ using System.Numerics;
using System.Threading.Tasks;
///
@@ -39,6 +40,7 @@ namespace ImageProcessor.Filters
int sourceBottom = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
+ Vector4 alphaVector = new Vector4(1, 1, 1, alpha);
Parallel.For(
startY,
@@ -49,10 +51,9 @@ namespace ImageProcessor.Filters
{
for (int x = startX; x < endX; x++)
{
- Color color = Color.ToNonPremultiplied(source[x, y]);
- color.A = color.A * alpha;
- color = Color.FromNonPremultiplied(color);
- target[x, y] = color;
+ Vector4 color = Color.ToNonPremultiplied(source[x, y]).ToVector4();
+ color *= alphaVector;
+ target[x, y] = Color.FromNonPremultiplied(new Color(color));
}
}
});
diff --git a/src/ImageProcessor/Filters/BackgroundColor.cs b/src/ImageProcessor/Filters/BackgroundColor.cs
index cfb9a66d6..f089cc2a6 100644
--- a/src/ImageProcessor/Filters/BackgroundColor.cs
+++ b/src/ImageProcessor/Filters/BackgroundColor.cs
@@ -51,13 +51,14 @@ namespace ImageProcessor.Filters
for (int x = startX; x < endX; x++)
{
Color color = source[x, y];
+ float a = color.A;
- if (color.A < 1 && color.A > 0)
+ if (a < 1 && a > 0)
{
color = Color.Lerp(color, backgroundColor, .5f);
}
- if (Math.Abs(color.A) < Epsilon)
+ if (Math.Abs(a) < Epsilon)
{
color = backgroundColor;
}
diff --git a/src/ImageProcessor/Filters/Binarization/Threshold.cs b/src/ImageProcessor/Filters/Binarization/Threshold.cs
index 7e394f775..a48ca5aa0 100644
--- a/src/ImageProcessor/Filters/Binarization/Threshold.cs
+++ b/src/ImageProcessor/Filters/Binarization/Threshold.cs
@@ -6,6 +6,7 @@
namespace ImageProcessor.Filters
{
using System;
+ using System.Numerics;
using System.Threading.Tasks;
///
diff --git a/src/ImageProcessor/Filters/Contrast.cs b/src/ImageProcessor/Filters/Contrast.cs
index 4a45e2c48..da55507ff 100644
--- a/src/ImageProcessor/Filters/Contrast.cs
+++ b/src/ImageProcessor/Filters/Contrast.cs
@@ -6,6 +6,7 @@
namespace ImageProcessor.Filters
{
using System;
+ using System.Numerics;
using System.Threading.Tasks;
///
@@ -39,7 +40,8 @@ namespace ImageProcessor.Filters
int sourceBottom = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
-
+ Vector4 contrastVector = new Vector4(contrast, contrast, contrast, 1);
+ Vector4 shiftVector = new Vector4(.5f, .5f, .5f, 1);
Parallel.For(
startY,
endY,
@@ -49,22 +51,11 @@ namespace ImageProcessor.Filters
{
for (int x = startX; x < endX; x++)
{
- Color color = Color.Expand(source[x, y]);
-
- // Seems to be faster than Vector3.
- color.R -= 0.5f;
- color.R *= contrast;
- color.R += 0.5f;
-
- color.G -= 0.5f;
- color.G *= contrast;
- color.G += 0.5f;
-
- color.B -= 0.5f;
- color.B *= contrast;
- color.B += 0.5f;
-
- target[x, y] = Color.Compress(color);
+ Vector4 color = Color.Expand(source[x, y]).ToVector4();
+ color -= shiftVector;
+ color *= contrastVector;
+ color += shiftVector;
+ target[x, y] = Color.Compress(new Color(color));
}
}
});
diff --git a/src/ImageProcessor/Filters/Invert.cs b/src/ImageProcessor/Filters/Invert.cs
index 3363c12a9..ab6c827b3 100644
--- a/src/ImageProcessor/Filters/Invert.cs
+++ b/src/ImageProcessor/Filters/Invert.cs
@@ -5,6 +5,7 @@
namespace ImageProcessor.Filters
{
+ using System.Numerics;
using System.Threading.Tasks;
///
@@ -19,6 +20,7 @@ namespace ImageProcessor.Filters
int sourceBottom = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
+ Vector3 inverseVector = Vector3.One;
Parallel.For(
startY,
@@ -30,10 +32,8 @@ namespace ImageProcessor.Filters
for (int x = startX; x < endX; x++)
{
Color color = source[x, y];
- color.R = 1 - color.R;
- color.G = 1 - color.G;
- color.B = 1 - color.B;
- target[x, y] = color;
+ Vector3 vector = inverseVector - color.ToVector3();
+ target[x, y] = new Color(vector, color.A);
}
}
});
diff --git a/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs b/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs
index 79eaf26c2..86f229da8 100644
--- a/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs
+++ b/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs
@@ -60,6 +60,11 @@ namespace ImageProcessor.Formats
this.maxColors = maxColors;
}
+ ///
+ /// Gets or sets the transparency threshold.
+ ///
+ public byte Threshold { get; set; } = 128;
+
///
/// Process the pixel in the first pass of the algorithm
///
@@ -91,7 +96,7 @@ namespace ImageProcessor.Formats
byte paletteIndex = (byte)this.maxColors;
// Get the palette index if it's transparency meets criterea.
- if (pixel.A > 0)
+ if (pixel.A > this.Threshold)
{
paletteIndex = (byte)this.octree.GetPaletteIndex(pixel);
}
diff --git a/src/ImageProcessor/Samplers/Resampler.cs b/src/ImageProcessor/Samplers/Resampler.cs
index b490a8203..5b67e76cf 100644
--- a/src/ImageProcessor/Samplers/Resampler.cs
+++ b/src/ImageProcessor/Samplers/Resampler.cs
@@ -9,6 +9,8 @@ namespace ImageProcessor.Samplers
using System.Collections.Generic;
using System.Threading.Tasks;
+ using ImageProcessor.Filters;
+
///
/// Provides methods that allow the resampling of images using various algorithms.
///
@@ -81,6 +83,8 @@ namespace ImageProcessor.Samplers
this.horizontalWeights = this.PrecomputeWeights(targetRectangle.Width, sourceRectangle.Width);
this.verticalWeights = this.PrecomputeWeights(targetRectangle.Height, sourceRectangle.Height);
}
+
+ new BackgroundColor(Color.Transparent).Apply(source, source, sourceRectangle);
}
///
@@ -189,10 +193,6 @@ namespace ImageProcessor.Samplers
}
destination = Color.Compress(destination);
-
- // Round alpha values in an attempt to prevent bleed.
- destination.A = (float)Math.Round(destination.A, 2);
-
target[x, y] = destination;
}
}
@@ -304,9 +304,6 @@ namespace ImageProcessor.Samplers
}
destination = Color.Compress(destination);
-
- // Round alpha values in an attempt to prevent bleed.
- destination.A = (float)Math.Round(destination.A, 2);
target[x, y] = destination;
}
}