diff --git a/src/ImageProcessor/Colors/Color.cs b/src/ImageProcessor/Colors/Color.cs
index 1ffda3c46..d85464471 100644
--- a/src/ImageProcessor/Colors/Color.cs
+++ b/src/ImageProcessor/Colors/Color.cs
@@ -111,11 +111,34 @@ namespace ImageProcessor
///
/// The vector.
///
- private Color(Vector4 vector)
+ public Color(Vector4 vector)
{
this.backingVector = vector;
}
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The vector representing the red, green, and blue componenets.
+ ///
+ public Color(Vector3 vector)
+ {
+ this.backingVector = new Vector4(vector.X, vector.Y, vector.Z, 1);
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The vector representing the red, green, and blue componenets.
+ ///
+ /// The alpha component.
+ public Color(Vector3 vector, float alpha)
+ {
+ this.backingVector = new Vector4(vector.X, vector.Y, vector.Z, alpha);
+ }
+
///
/// Gets or sets the red component of the color.
///
@@ -450,6 +473,24 @@ namespace ImageProcessor
return (from * (1 - amount)) + (to * amount);
}
+ ///
+ /// Gets a representation for this .
+ ///
+ /// A representation for this object.
+ public Vector4 ToVector4()
+ {
+ return new Vector4(this.R, this.G, this.B, this.A);
+ }
+
+ ///
+ /// Gets a representation for this .
+ ///
+ /// A representation for this object.
+ public Vector3 ToVector3()
+ {
+ return new Vector3(this.R, this.G, this.B);
+ }
+
///
public override bool Equals(object obj)
{
diff --git a/src/ImageProcessor/Filters/Alpha.cs b/src/ImageProcessor/Filters/Alpha.cs
index 02c7ff364..4f2e01f70 100644
--- a/src/ImageProcessor/Filters/Alpha.cs
+++ b/src/ImageProcessor/Filters/Alpha.cs
@@ -34,7 +34,7 @@ namespace ImageProcessor.Filters
///
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
- double alpha = this.Value / 100.0;
+ float alpha = this.Value / 100f;
int sourceY = sourceRectangle.Y;
int sourceBottom = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
@@ -49,9 +49,9 @@ namespace ImageProcessor.Filters
{
for (int x = startX; x < endX; x++)
{
- Bgra32 color = source[x, y];
- double a = color.A * alpha;
- target[x, y] = new Bgra32(color.B, color.G, color.R, a.ToByte());
+ Color color = source[x, y];
+ color.A = color.A * alpha;
+ target[x, y] = color;
}
}
});
diff --git a/src/ImageProcessor/Filters/ColorMatrix/ColorMatrixFilter.cs b/src/ImageProcessor/Filters/ColorMatrix/ColorMatrixFilter.cs
index 68f929be6..17a49b8fb 100644
--- a/src/ImageProcessor/Filters/ColorMatrix/ColorMatrixFilter.cs
+++ b/src/ImageProcessor/Filters/ColorMatrix/ColorMatrixFilter.cs
@@ -36,13 +36,12 @@ namespace ImageProcessor.Filters
///
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
+ bool gamma = this.GammaAdjust;
int sourceY = sourceRectangle.Y;
int sourceBottom = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
ColorMatrix matrix = this.Value;
- Bgra32 previousColor = source[0, 0];
- Bgra32 pixelValue = this.ApplyMatrix(previousColor, matrix);
Parallel.For(
startY,
@@ -53,20 +52,7 @@ namespace ImageProcessor.Filters
{
for (int x = startX; x < endX; x++)
{
- Bgra32 sourceColor = source[x, y];
-
- // Check if this is the same as the last pixel. If so use that value
- // rather than calculating it again. This is an inexpensive optimization.
- if (sourceColor != previousColor)
- {
- // Perform the operation on the pixel.
- pixelValue = this.ApplyMatrix(sourceColor, matrix);
-
- // And setup the previous pointer
- previousColor = sourceColor;
- }
-
- target[x, y] = pixelValue;
+ target[x, y] = ApplyMatrix(source[x, y], matrix, gamma);
}
}
});
@@ -75,33 +61,31 @@ namespace ImageProcessor.Filters
///
/// Applies the color matrix against the given color.
///
- /// The source color.
+ /// The source color.
/// The matrix.
+ /// Whether to perform gamma adjustments.
///
- /// The .
+ /// The .
///
- private Bgra32 ApplyMatrix(Bgra32 sourceColor, ColorMatrix matrix)
+ private static Color ApplyMatrix(Color color, ColorMatrix matrix, bool gamma)
{
- bool gamma = this.GammaAdjust;
-
if (gamma)
{
- sourceColor = PixelOperations.ToLinear(sourceColor);
+ color = PixelOperations.ToLinear(color);
}
- int sr = sourceColor.R;
- int sg = sourceColor.G;
- int sb = sourceColor.B;
- int sa = sourceColor.A;
+ float sr = color.R;
+ float sg = color.G;
+ float sb = color.B;
+ float sa = color.A;
// TODO: Investigate RGBAW
- byte r = ((sr * matrix.Matrix00) + (sg * matrix.Matrix10) + (sb * matrix.Matrix20) + (sa * matrix.Matrix30) + (255f * matrix.Matrix40)).ToByte();
- byte g = ((sr * matrix.Matrix01) + (sg * matrix.Matrix11) + (sb * matrix.Matrix21) + (sa * matrix.Matrix31) + (255f * matrix.Matrix41)).ToByte();
- byte b = ((sr * matrix.Matrix02) + (sg * matrix.Matrix12) + (sb * matrix.Matrix22) + (sa * matrix.Matrix32) + (255f * matrix.Matrix42)).ToByte();
- byte a = ((sr * matrix.Matrix03) + (sg * matrix.Matrix13) + (sb * matrix.Matrix23) + (sa * matrix.Matrix33) + (255f * matrix.Matrix43)).ToByte();
+ color.R = (sr * matrix.Matrix00) + (sg * matrix.Matrix10) + (sb * matrix.Matrix20) + (sa * matrix.Matrix30) + matrix.Matrix40;
+ color.G = (sr * matrix.Matrix01) + (sg * matrix.Matrix11) + (sb * matrix.Matrix21) + (sa * matrix.Matrix31) + matrix.Matrix41;
+ color.B = (sr * matrix.Matrix02) + (sg * matrix.Matrix12) + (sb * matrix.Matrix22) + (sa * matrix.Matrix32) + matrix.Matrix42;
+ color.A = (sr * matrix.Matrix03) + (sg * matrix.Matrix13) + (sb * matrix.Matrix23) + (sa * matrix.Matrix33) + matrix.Matrix43;
- // TODO: Fix this.
- return gamma ? (Bgra32)PixelOperations.ToSrgb(new Bgra32(b, g, r, a)) : new Bgra32(b, g, r, a);
+ return gamma ? PixelOperations.ToSrgb(color) : color;
}
}
}
diff --git a/src/ImageProcessor/Filters/ColorMatrix/Invert.cs b/src/ImageProcessor/Filters/ColorMatrix/Invert.cs
deleted file mode 100644
index 24c8f52a0..000000000
--- a/src/ImageProcessor/Filters/ColorMatrix/Invert.cs
+++ /dev/null
@@ -1,35 +0,0 @@
-//
-// Copyright © James South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessor.Filters
-{
- ///
- /// Inverts the colors of the image.
- ///
- public class Invert : ColorMatrixFilter
- {
- ///
- /// The inversion matrix.
- /// TODO: With gamma adjustment enabled this leaves the image too bright.
- ///
- private static readonly ColorMatrix Matrix = new ColorMatrix(
- new[]
- {
- new float[] { -1, 0, 0, 0, 0 },
- new float[] { 0, -1, 0, 0, 0 },
- new float[] { 0, 0, -1, 0, 0 },
- new float[] { 0, 0, 0, 1, 0 },
- new float[] { 1, 1, 1, 0, 1 }
- });
-
- ///
- /// Initializes a new instance of the class.
- ///
- public Invert()
- : base(Matrix, false)
- {
- }
- }
-}
diff --git a/src/ImageProcessor/Filters/Contrast.cs b/src/ImageProcessor/Filters/Contrast.cs
index 2644b8f72..0986dc3d0 100644
--- a/src/ImageProcessor/Filters/Contrast.cs
+++ b/src/ImageProcessor/Filters/Contrast.cs
@@ -34,7 +34,7 @@ namespace ImageProcessor.Filters
///
protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
- double contrast = (100.0 + this.Value) / 100.0;
+ float contrast = (100f + this.Value) / 100f;
int sourceY = sourceRectangle.Y;
int sourceBottom = sourceRectangle.Bottom;
int startX = sourceRectangle.X;
@@ -49,36 +49,37 @@ namespace ImageProcessor.Filters
{
for (int x = startX; x < endX; x++)
{
- Bgra32 sourceColor = source[x, y];
- sourceColor = PixelOperations.ToLinear(sourceColor);
+ target[x, y] = AdjustContrast(source[x, y], contrast);
+ }
+ }
+ });
+ }
- double r = sourceColor.R / 255.0;
- r -= 0.5;
- r *= contrast;
- r += 0.5;
- r *= 255;
- r = r.ToByte();
+ ///
+ /// Returns a with the contrast adjusted.
+ ///
+ /// The source color.
+ /// The contrast adjustment factor.
+ ///
+ /// The .
+ ///
+ private static Color AdjustContrast(Color color, float contrast)
+ {
+ color = PixelOperations.ToLinear(color);
- double g = sourceColor.G / 255.0;
- g -= 0.5;
- g *= contrast;
- g += 0.5;
- g *= 255;
- g = g.ToByte();
+ color.R -= 0.5f;
+ color.R *= contrast;
+ color.R += 0.5f;
- double b = sourceColor.B / 255.0;
- b -= 0.5;
- b *= contrast;
- b += 0.5;
- b *= 255;
- b = b.ToByte();
+ color.G -= 0.5f;
+ color.G *= contrast;
+ color.G += 0.5f;
- Bgra32 destinationColor = new Bgra32(b.ToByte(), g.ToByte(), r.ToByte(), sourceColor.A);
- destinationColor = PixelOperations.ToSrgb(destinationColor);
- target[x, y] = destinationColor;
- }
- }
- });
+ color.B -= 0.5f;
+ color.B *= contrast;
+ color.B += 0.5f;
+
+ return PixelOperations.ToSrgb(color);
}
}
}
diff --git a/src/ImageProcessor/Filters/Invert.cs b/src/ImageProcessor/Filters/Invert.cs
index ade3c6829..d2fa9445a 100644
--- a/src/ImageProcessor/Filters/Invert.cs
+++ b/src/ImageProcessor/Filters/Invert.cs
@@ -30,9 +30,11 @@ namespace ImageProcessor.Filters
for (int x = startX; x < endX; x++)
{
// TODO: This doesn't work for gamma test images.
- Bgra32 color = source[x, y];
- Bgra32 targetColor = new Bgra32((255 - color.B).ToByte(), (255 - color.G).ToByte(), (255 - color.R).ToByte(), color.A);
- target[x, y] = targetColor;
+ Color color = source[x, y];
+ color.R = 1 - color.R;
+ color.G = 1 - color.G;
+ color.B = 1 - color.B;
+ target[x, y] = color;
}
}
});
diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj
index 3e506f65e..48294d14f 100644
--- a/src/ImageProcessor/ImageProcessor.csproj
+++ b/src/ImageProcessor/ImageProcessor.csproj
@@ -40,6 +40,7 @@
prompt
4
bin\Release\ImageProcessor.XML
+ true
diff --git a/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs b/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
index f364dd3f0..e1fe80d01 100644
--- a/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
+++ b/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
@@ -15,13 +15,13 @@ namespace ImageProcessor.Tests
//{ "Contrast-50", new Contrast(50) },
//{ "Contrast--50", new Contrast(-50) },
//{ "Alpha--50", new Alpha(50) },
- //{ "Invert", new Invert() },
- //{ "Sepia", new Sepia() },
- //{ "BlackWhite", new BlackWhite() },
- //{ "Lomograph", new Lomograph() },
- //{ "Polaroid", new Polaroid() },
+ { "Invert", new Invert() },
+ { "Sepia", new Sepia() },
+ { "BlackWhite", new BlackWhite() },
+ { "Lomograph", new Lomograph() },
+ { "Polaroid", new Polaroid() },
{ "GreyscaleBt709", new GreyscaleBt709() },
- //{ "GreyscaleBt601", new GreyscaleBt601() },
+ { "GreyscaleBt601", new GreyscaleBt601() },
};
[Theory]
diff --git a/tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs b/tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs
index 7f9e8ccc6..9ece3b02b 100644
--- a/tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs
+++ b/tests/ImageProcessor.Tests/Processors/ProcessorTestBase.cs
@@ -29,8 +29,8 @@ namespace ImageProcessor.Tests
"../../TestImages/Formats/Png/splash.png",
"../../TestImages/Formats/Gif/leaf.gif",
"../../TestImages/Formats/Gif/rings.gif",
- "../../TestImages/Formats/Gif/ani2.gif",
- "../../TestImages/Formats/Gif/giphy.gif"
+ //"../../TestImages/Formats/Gif/ani2.gif",
+ //"../../TestImages/Formats/Gif/giphy.gif"
};
}
}