diff --git a/src/ImageProcessor/Colors/Color.cs b/src/ImageProcessor/Colors/Color.cs
index f7c60860c..340151126 100644
--- a/src/ImageProcessor/Colors/Color.cs
+++ b/src/ImageProcessor/Colors/Color.cs
@@ -350,9 +350,13 @@ namespace ImageProcessor
{
amount = amount.Clamp(0f, 1f);
+ if (Math.Abs(from.A - 1) < Epsilon || Math.Abs(from.A) < Epsilon)
+ {
+ return from + (to - from) * amount;
+ }
+
// Premultiplied.
- return from + (to - from) * amount;
- //return (from * (1 - amount)) + to;
+ return from * (1 - amount) + to;
}
///
diff --git a/src/ImageProcessor/Filters/BackgroundColor.cs b/src/ImageProcessor/Filters/BackgroundColor.cs
index 4b159b888..cfb9a66d6 100644
--- a/src/ImageProcessor/Filters/BackgroundColor.cs
+++ b/src/ImageProcessor/Filters/BackgroundColor.cs
@@ -5,6 +5,7 @@
namespace ImageProcessor.Filters
{
+ using System;
using System.Threading.Tasks;
///
@@ -12,6 +13,11 @@ namespace ImageProcessor.Filters
///
public class BackgroundColor : ParallelImageProcessor
{
+ ///
+ /// The epsilon for comparing floating point numbers.
+ ///
+ private const float Epsilon = 0.001f;
+
///
/// Initializes a new instance of the class.
///
@@ -46,11 +52,16 @@ namespace ImageProcessor.Filters
{
Color color = source[x, y];
- if (color.A < 1)
+ if (color.A < 1 && color.A > 0)
{
color = Color.Lerp(color, backgroundColor, .5f);
}
+ if (Math.Abs(color.A) < Epsilon)
+ {
+ color = backgroundColor;
+ }
+
target[x, y] = color;
}
}
diff --git a/src/ImageProcessor/Filters/ColorMatrix/Polaroid.cs b/src/ImageProcessor/Filters/ColorMatrix/Polaroid.cs
index d6c91ffda..26231b386 100644
--- a/src/ImageProcessor/Filters/ColorMatrix/Polaroid.cs
+++ b/src/ImageProcessor/Filters/ColorMatrix/Polaroid.cs
@@ -33,7 +33,7 @@ namespace ImageProcessor.Filters
protected override void AfterApply(ImageBase source, ImageBase target, Rectangle targetRectangle, Rectangle sourceRectangle)
{
new Vignette { Color = new Color(102 / 255f, 34 / 255f, 0) }.Apply(target, target, targetRectangle);
- new Glow { Color = new Color(1, 153 / 255f, 102 / 255f) }.Apply(target, target, targetRectangle);
+ new Glow { Color = new Color(1, 153 / 255f, 102 / 255f, .7f) }.Apply(target, target, targetRectangle);
}
}
}
diff --git a/src/ImageProcessor/Filters/Glow.cs b/src/ImageProcessor/Filters/Glow.cs
index afc8b392a..43ab28356 100644
--- a/src/ImageProcessor/Filters/Glow.cs
+++ b/src/ImageProcessor/Filters/Glow.cs
@@ -34,7 +34,7 @@ namespace ImageProcessor.Filters
{
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
- Color color = this.Color;
+ Color glowColor = this.Color;
Vector2 centre = Rectangle.Center(targetRectangle).ToVector2();
float rX = this.RadiusX > 0 ? this.RadiusX : targetRectangle.Width / 2f;
float rY = this.RadiusY > 0 ? this.RadiusY : targetRectangle.Height / 2f;
@@ -49,7 +49,7 @@ namespace ImageProcessor.Filters
{
float distance = Vector2.Distance(centre, new Vector2(x, y));
Color sourceColor = target[x, y];
- target[x, y] = Color.Lerp(color, sourceColor, 4f * distance / maxDistance);
+ target[x, y] = Color.Lerp(sourceColor, glowColor, .334f * (1 - distance / maxDistance));
}
});
}
diff --git a/src/ImageProcessor/Filters/Vignette.cs b/src/ImageProcessor/Filters/Vignette.cs
index c4cf02685..bae28f565 100644
--- a/src/ImageProcessor/Filters/Vignette.cs
+++ b/src/ImageProcessor/Filters/Vignette.cs
@@ -17,7 +17,7 @@ namespace ImageProcessor.Filters
///
/// Gets or sets the vignette color to apply.
///
- public Color Color { get; set; } = Color.Black;
+ public Color Color { get; set; } = new Color(0, 0, 0, 1);
///
/// Gets or sets the the x-radius.
@@ -34,7 +34,7 @@ namespace ImageProcessor.Filters
{
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
- Color color = this.Color;
+ Color vignetteColor = this.Color;
Vector2 centre = Rectangle.Center(targetRectangle).ToVector2();
float rX = this.RadiusX > 0 ? this.RadiusX : targetRectangle.Width / 2f;
float rY = this.RadiusY > 0 ? this.RadiusY : targetRectangle.Height / 2f;
@@ -49,7 +49,14 @@ namespace ImageProcessor.Filters
{
float distance = Vector2.Distance(centre, new Vector2(x, y));
Color sourceColor = target[x, y];
- target[x, y] = Color.Lerp(sourceColor, color, .9f * distance / maxDistance);
+ //if (sourceColor.A > 0)
+ //{
+ target[x, y] = Color.Lerp(sourceColor, vignetteColor, .9f * distance / maxDistance);
+ //}
+ //else
+ //{
+ // target[x, y] = Color.Lerp(sourceColor, color, distance / maxDistance);
+ //}
}
});
}
diff --git a/src/ImageProcessor/Formats/Bmp/BmpEncoder.cs b/src/ImageProcessor/Formats/Bmp/BmpEncoder.cs
index 04bf02dd0..ad80bbc76 100644
--- a/src/ImageProcessor/Formats/Bmp/BmpEncoder.cs
+++ b/src/ImageProcessor/Formats/Bmp/BmpEncoder.cs
@@ -14,11 +14,6 @@ namespace ImageProcessor.Formats
/// The encoder can currently only write 24-bit rgb images to streams.
public class BmpEncoder : IImageEncoder
{
- ///
- /// The the transparency threshold.
- ///
- private int threshold = 128;
-
///
/// Gets or sets the quality of output for images.
///
@@ -31,15 +26,6 @@ namespace ImageProcessor.Formats
///
public string Extension => "bmp";
- ///
- /// Gets or sets the transparency threshold.
- ///
- public int Threshold
- {
- get { return this.threshold; }
- set { this.threshold = value.Clamp(0, 255); }
- }
-
///
public bool IsSupportedFileExtension(string extension)
{
@@ -132,11 +118,6 @@ namespace ImageProcessor.Formats
Bgra32 color = Color.ToNonPremultiplied(new Color(r, g, b, a));
- if (color.A < this.Threshold)
- {
- color = new Bgra32(0, 0, 0, 0);
- }
-
writer.Write(color.B);
writer.Write(color.G);
writer.Write(color.R);
diff --git a/src/ImageProcessor/Formats/Gif/GifEncoder.cs b/src/ImageProcessor/Formats/Gif/GifEncoder.cs
index 81735f55b..2d1654700 100644
--- a/src/ImageProcessor/Formats/Gif/GifEncoder.cs
+++ b/src/ImageProcessor/Formats/Gif/GifEncoder.cs
@@ -15,11 +15,6 @@ namespace ImageProcessor.Formats
///
public class GifEncoder : IImageEncoder
{
- ///
- /// The the transparency threshold.
- ///
- private int threshold = 128;
-
///
/// Gets or sets the quality of output for images.
///
@@ -32,15 +27,6 @@ namespace ImageProcessor.Formats
///
public string MimeType => "image/gif";
- ///
- /// Gets or sets the transparency threshold.
- ///
- public int Threshold
- {
- get { return this.threshold; }
- set { this.threshold = value.Clamp(0, 255); }
- }
-
///
public bool IsSupportedFileExtension(string extension)
{
@@ -138,7 +124,7 @@ namespace ImageProcessor.Formats
private QuantizedImage WriteColorTable(ImageBase image, Stream stream, int quality, int bitDepth)
{
// Quantize the image returning a pallete.
- IQuantizer quantizer = new OctreeQuantizer(quality.Clamp(1, 255), bitDepth) { Threshold = this.threshold };
+ IQuantizer quantizer = new OctreeQuantizer(quality.Clamp(1, 255), bitDepth);
QuantizedImage quantizedImage = quantizer.Quantize(image);
// Grab the pallete and write it to the stream.
diff --git a/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs b/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs
index 7954e1af7..79eaf26c2 100644
--- a/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs
+++ b/src/ImageProcessor/Formats/Gif/Quantizer/OctreeQuantizer.cs
@@ -24,11 +24,6 @@ namespace ImageProcessor.Formats
///
private readonly int maxColors;
- ///
- /// The the transparency threshold.
- ///
- private int threshold = 128;
-
///
/// Initializes a new instance of the class.
///
@@ -65,15 +60,6 @@ namespace ImageProcessor.Formats
this.maxColors = maxColors;
}
- ///
- /// Gets or sets the transparency threshold.
- ///
- public int Threshold
- {
- get { return this.threshold; }
- set { this.threshold = value.Clamp(0, 255); }
- }
-
///
/// Process the pixel in the first pass of the algorithm
///
@@ -105,7 +91,7 @@ namespace ImageProcessor.Formats
byte paletteIndex = (byte)this.maxColors;
// Get the palette index if it's transparency meets criterea.
- if (pixel.A >= this.Threshold)
+ if (pixel.A > 0)
{
paletteIndex = (byte)this.octree.GetPaletteIndex(pixel);
}
diff --git a/src/ImageProcessor/Formats/IImageEncoder.cs b/src/ImageProcessor/Formats/IImageEncoder.cs
index eb0df5561..bda8dbb42 100644
--- a/src/ImageProcessor/Formats/IImageEncoder.cs
+++ b/src/ImageProcessor/Formats/IImageEncoder.cs
@@ -22,11 +22,6 @@ namespace ImageProcessor.Formats
///
int Quality { get; set; }
- ///
- /// Gets or sets the transparency threshold.
- ///
- int Threshold { get; set; }
-
///
/// Gets the standard identifier used on the Internet to indicate the type of data that a file contains.
///
diff --git a/src/ImageProcessor/Formats/Jpg/JpegEncoder.cs b/src/ImageProcessor/Formats/Jpg/JpegEncoder.cs
index d794c9d6e..0517b422c 100644
--- a/src/ImageProcessor/Formats/Jpg/JpegEncoder.cs
+++ b/src/ImageProcessor/Formats/Jpg/JpegEncoder.cs
@@ -21,11 +21,6 @@ namespace ImageProcessor.Formats
///
private int quality = 100;
- ///
- /// The the transparency threshold.
- ///
- private int threshold = 128;
-
///
/// Gets or sets the quality, that will be used to encode the image. Quality
/// index must be between 0 and 100 (compression from max to min).
@@ -37,15 +32,6 @@ namespace ImageProcessor.Formats
set { this.quality = value.Clamp(1, 100); }
}
- ///
- /// Gets or sets the transparency threshold.
- ///
- public int Threshold
- {
- get { return this.threshold; }
- set { this.threshold = value.Clamp(0, 255); }
- }
-
///
public string MimeType => "image/jpeg";
@@ -127,11 +113,6 @@ namespace ImageProcessor.Formats
Bgra32 color = Color.ToNonPremultiplied(new Color(r, g, b, a));
- if (color.A < this.Threshold)
- {
- color = new Bgra32(0, 0, 0, 0);
- }
-
samples[start] = color.R;
samples[start + 1] = color.G;
samples[start + 2] = color.B;
diff --git a/src/ImageProcessor/Formats/Png/PngEncoder.cs b/src/ImageProcessor/Formats/Png/PngEncoder.cs
index 64e3ff7c9..e4501a956 100644
--- a/src/ImageProcessor/Formats/Png/PngEncoder.cs
+++ b/src/ImageProcessor/Formats/Png/PngEncoder.cs
@@ -18,11 +18,6 @@ namespace ImageProcessor.Formats
///
private const int MaxBlockSize = 0xFFFF;
- ///
- /// The the transparency threshold.
- ///
- private int threshold;
-
///
/// Initializes a new instance of the class.
///
@@ -37,15 +32,6 @@ namespace ImageProcessor.Formats
/// Png is a lossless format so this is not used in this encoder.
public int Quality { get; set; }
- ///
- /// Gets or sets the transparency threshold.
- ///
- public int Threshold
- {
- get { return this.threshold; }
- set { this.threshold = value.Clamp(0, 255); }
- }
-
///
public string MimeType => "image/png";
@@ -342,11 +328,6 @@ namespace ImageProcessor.Formats
Bgra32 color = Color.ToNonPremultiplied(new Color(r, g, b, a));
- if (color.A < this.Threshold)
- {
- color = new Bgra32(0, 0, 0, 0);
- }
-
data[dataOffset] = color.R;
data[dataOffset + 1] = color.G;
data[dataOffset + 2] = color.B;
diff --git a/src/ImageProcessor/Samplers/ImageSampleExtensions.cs b/src/ImageProcessor/Samplers/ImageSampleExtensions.cs
index 88ed3ef68..43f7e7dc8 100644
--- a/src/ImageProcessor/Samplers/ImageSampleExtensions.cs
+++ b/src/ImageProcessor/Samplers/ImageSampleExtensions.cs
@@ -121,7 +121,7 @@ namespace ImageProcessor.Samplers
/// The
public static Image Rotate(this Image source, float degrees)
{
- return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, new Resampler(new RobidouxResampler()) { Angle = degrees });
+ return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, new Resampler(new BicubicResampler()) { Angle = degrees });
}
///
diff --git a/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs b/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
index 72a0cae15..e4fe0704c 100644
--- a/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
+++ b/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
@@ -13,39 +13,39 @@ namespace ImageProcessor.Tests
{
public static readonly TheoryData Filters = new TheoryData
{
- { "Brightness-50", new Brightness(50) },
- { "Brightness--50", new Brightness(-50) },
- { "Contrast-50", new Contrast(50) },
- { "Contrast--50", new Contrast(-50) },
- { "BackgroundColor", new BackgroundColor(new Color(243 / 255f, 87 / 255f, 161 / 255f))},
- { "Blend", new Blend(new Image(File.OpenRead("TestImages/Formats/Bmp/Car.bmp")),50)},
- { "Saturation-50", new Saturation(50) },
- { "Saturation--50", new Saturation(-50) },
+ //{ "Brightness-50", new Brightness(50) },
+ //{ "Brightness--50", new Brightness(-50) },
+ //{ "Contrast-50", new Contrast(50) },
+ //{ "Contrast--50", new Contrast(-50) },
+ //{ "BackgroundColor", new BackgroundColor(new Color(243 / 255f, 87 / 255f, 161 / 255f,.5f))},
+ //{ "Blend", new Blend(new Image(File.OpenRead("TestImages/Formats/Bmp/Car.bmp")),50)},
+ //{ "Saturation-50", new Saturation(50) },
+ //{ "Saturation--50", new Saturation(-50) },
{ "Alpha--50", new Alpha(50) },
- { "Invert", new Invert() },
- { "Sepia", new Sepia() },
- { "BlackWhite", new BlackWhite() },
- { "Lomograph", new Lomograph() },
+ //{ "Invert", new Invert() },
+ //{ "Sepia", new Sepia() },
+ //{ "BlackWhite", new BlackWhite() },
+ //{ "Lomograph", new Lomograph() },
{ "Polaroid", new Polaroid() },
- { "Kodachrome", new Kodachrome() },
- { "GreyscaleBt709", new GreyscaleBt709() },
- { "GreyscaleBt601", new GreyscaleBt601() },
- { "Kayyali", new Kayyali() },
- { "Kirsch", new Kirsch() },
- { "Laplacian3X3", new Laplacian3X3() },
- { "Laplacian5X5", new Laplacian5X5() },
- { "LaplacianOfGaussian", new LaplacianOfGaussian() },
- { "Prewitt", new Prewitt() },
- { "RobertsCross", new RobertsCross() },
- { "Scharr", new Scharr() },
- { "Sobel", new Sobel {Greyscale = true} },
- { "Pixelate", new Pixelate(8) },
- { "GuassianBlur", new GuassianBlur(10) },
- { "GuassianSharpen", new GuassianSharpen(10) },
- { "Hue-180", new Hue(180) },
- { "Hue--180", new Hue(-180) },
- { "BoxBlur", new BoxBlur(10) },
- {"Vignette", new Vignette()}
+ //{ "Kodachrome", new Kodachrome() },
+ //{ "GreyscaleBt709", new GreyscaleBt709() },
+ //{ "GreyscaleBt601", new GreyscaleBt601() },
+ //{ "Kayyali", new Kayyali() },
+ //{ "Kirsch", new Kirsch() },
+ //{ "Laplacian3X3", new Laplacian3X3() },
+ //{ "Laplacian5X5", new Laplacian5X5() },
+ //{ "LaplacianOfGaussian", new LaplacianOfGaussian() },
+ //{ "Prewitt", new Prewitt() },
+ //{ "RobertsCross", new RobertsCross() },
+ //{ "Scharr", new Scharr() },
+ //{ "Sobel", new Sobel {Greyscale = true} },
+ //{ "Pixelate", new Pixelate(8) },
+ //{ "GuassianBlur", new GuassianBlur(10) },
+ //{ "GuassianSharpen", new GuassianSharpen(10) },
+ //{ "Hue-180", new Hue(180) },
+ //{ "Hue--180", new Hue(-180) },
+ //{ "BoxBlur", new BoxBlur(10) },
+ //{"Vignette", new Vignette()}
};
[Theory]
diff --git a/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs b/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
index 8b045629d..dfc26728d 100644
--- a/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
+++ b/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
@@ -13,20 +13,20 @@
public static readonly TheoryData Samplers =
new TheoryData
{
- //{ "Bicubic", new BicubicResampler() },
- //{ "Triangle", new TriangleResampler() },
- //{ "Box", new BoxResampler() },
- //{ "Lanczos3", new Lanczos3Resampler() },
- //{ "Lanczos5", new Lanczos5Resampler() },
- //{ "Lanczos8", new Lanczos8Resampler() },
- //{ "MitchellNetravali", new MitchellNetravaliResampler() },
+ { "Bicubic", new BicubicResampler() },
+ { "Triangle", new TriangleResampler() },
+ { "Box", new BoxResampler() },
+ { "Lanczos3", new Lanczos3Resampler() },
+ { "Lanczos5", new Lanczos5Resampler() },
+ { "Lanczos8", new Lanczos8Resampler() },
+ { "MitchellNetravali", new MitchellNetravaliResampler() },
{ "NearestNeighbor", new NearestNeighborResampler() },
- //{ "Hermite", new HermiteResampler() },
- //{ "Spline", new SplineResampler() },
- //{ "Robidoux", new RobidouxResampler() },
- //{ "RobidouxSharp", new RobidouxSharpResampler() },
- //{ "RobidouxSoft", new RobidouxSoftResampler() },
- //{ "Welch", new WelchResampler() }
+ { "Hermite", new HermiteResampler() },
+ { "Spline", new SplineResampler() },
+ { "Robidoux", new RobidouxResampler() },
+ { "RobidouxSharp", new RobidouxSharpResampler() },
+ { "RobidouxSoft", new RobidouxSoftResampler() },
+ { "Welch", new WelchResampler() }
};
public static readonly TheoryData RotateFlips = new TheoryData
@@ -167,6 +167,7 @@
using (FileStream output = File.OpenWrite($"TestOutput/Rotate/{filename}"))
{
image.Rotate(45, sampler)
+ .BackgroundColor(Color.Aqua)
.Save(output);
}