diff --git a/src/ImageProcessor/Filters/Alpha.cs b/src/ImageProcessor/Filters/Alpha.cs
new file mode 100644
index 000000000..672e5263a
--- /dev/null
+++ b/src/ImageProcessor/Filters/Alpha.cs
@@ -0,0 +1,56 @@
+//
+// Copyright © James South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessor.Filters
+{
+ using System;
+
+ ///
+ /// An to change the Alpha of an .
+ ///
+ public class Alpha : ParallelImageProcessor
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The percentage to adjust the opacity of the image. Must be between 0 and 100.
+ ///
+ /// is less than 0 or is greater than 100.
+ ///
+ public Alpha(int percent)
+ {
+ Guard.MustBeBetweenOrEqualTo(percent, 0, 100, nameof(percent));
+ this.Value = percent;
+ }
+
+ ///
+ /// Gets the alpha value.
+ ///
+ public int Value { get; }
+
+ ///
+ protected override void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
+ {
+ double alpha = this.Value / 100.0;
+ int sourceY = sourceRectangle.Y;
+ int sourceBottom = sourceRectangle.Bottom;
+ int startX = sourceRectangle.X;
+ int endX = sourceRectangle.Right;
+
+ for (int y = startY; y < endY; y++)
+ {
+ if (y >= sourceY && y < sourceBottom)
+ {
+ for (int x = startX; x < endX; x++)
+ {
+ Bgra color = source[x, y];
+ double a = color.A * alpha;
+ target[x, y] = new Bgra(color.B, color.G, color.R, a.ToByte());
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/ImageProcessor/Filters/Contrast.cs b/src/ImageProcessor/Filters/Contrast.cs
index 6c3336fca..d08bcfcc2 100644
--- a/src/ImageProcessor/Filters/Contrast.cs
+++ b/src/ImageProcessor/Filters/Contrast.cs
@@ -17,7 +17,7 @@ namespace ImageProcessor.Filters
///
/// The new contrast of the image. Must be between -100 and 100.
///
- /// is less than -100 is greater than 100.
+ /// is less than -100 or is greater than 100.
///
public Contrast(int contrast)
{
@@ -34,35 +34,45 @@ 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;
+ int sourceY = sourceRectangle.Y;
+ int sourceBottom = sourceRectangle.Bottom;
+ int startX = sourceRectangle.X;
+ int endX = sourceRectangle.Right;
for (int y = startY; y < endY; y++)
{
- for (int x = sourceRectangle.X; x < sourceRectangle.Right; x++)
+ if (y >= sourceY && y < sourceBottom)
{
- Bgra color = source[x, y];
+ for (int x = startX; x < endX; x++)
+ {
+ Bgra sourceColor = source[x, y];
+ sourceColor = PixelOperations.ToLinear(sourceColor);
- double r = color.R / 255.0;
- r -= 0.5;
- r *= contrast;
- r += 0.5;
- r *= 255;
- r = r.ToByte();
+ double r = sourceColor.R / 255.0;
+ r -= 0.5;
+ r *= contrast;
+ r += 0.5;
+ r *= 255;
+ r = r.ToByte();
- double g = color.G / 255.0;
- g -= 0.5;
- g *= contrast;
- g += 0.5;
- g *= 255;
- g = g.ToByte();
+ double g = sourceColor.G / 255.0;
+ g -= 0.5;
+ g *= contrast;
+ g += 0.5;
+ g *= 255;
+ g = g.ToByte();
- double b = color.B / 255.0;
- b -= 0.5;
- b *= contrast;
- b += 0.5;
- b *= 255;
- b = b.ToByte();
+ double b = sourceColor.B / 255.0;
+ b -= 0.5;
+ b *= contrast;
+ b += 0.5;
+ b *= 255;
+ b = b.ToByte();
- target[x, y] = new Bgra((byte)b, (byte)g, (byte)r, color.A);
+ Bgra destinationColor = new Bgra(b.ToByte(), g.ToByte(), r.ToByte(), sourceColor.A);
+ destinationColor = PixelOperations.ToSrgb(destinationColor);
+ target[x, y] = destinationColor;
+ }
}
}
}
diff --git a/src/ImageProcessor/Filters/ImageFilterExtensions.cs b/src/ImageProcessor/Filters/ImageFilterExtensions.cs
index 674f4f0e4..351a1921e 100644
--- a/src/ImageProcessor/Filters/ImageFilterExtensions.cs
+++ b/src/ImageProcessor/Filters/ImageFilterExtensions.cs
@@ -6,7 +6,7 @@
namespace ImageProcessor.Filters
{
///
- /// Exstensions methods for to apply filters to the image.
+ /// Extensions methods for to apply filters to the image.
///
public static class ImageFilterExtensions
{
@@ -16,6 +16,48 @@ namespace ImageProcessor.Filters
/// The image this method extends.
/// The new contrast of the image. Must be between -100 and 100.
/// The .
- public static Image Contrast(this Image source, int amount) => source.Process(new Contrast(amount));
+ public static Image Contrast(this Image source, int amount)
+ {
+ return Contrast(source, amount, source.Bounds);
+ }
+
+ ///
+ /// Alters the contrast component of the image.
+ ///
+ /// The image this method extends.
+ /// The new contrast of the image. Must be between -100 and 100.
+ ///
+ /// The structure that specifies the portion of the image object to draw.
+ ///
+ /// The .
+ public static Image Contrast(this Image source, int amount, Rectangle sourceRectangle)
+ {
+ return source.Process(sourceRectangle, new Contrast(amount));
+ }
+
+ ///
+ /// Alters the alpha component of the image.
+ ///
+ /// The image this method extends.
+ /// The new opacity of the image. Must be between 0 and 100.
+ /// The .
+ public static Image Alpha(this Image source, int percent)
+ {
+ return Alpha(source, percent, source.Bounds);
+ }
+
+ ///
+ /// Alters the alpha component of the image.
+ ///
+ /// The image this method extends.
+ /// The new opacity of the image. Must be between 0 and 100.
+ ///
+ /// The structure that specifies the portion of the image object to draw.
+ ///
+ /// The .
+ public static Image Alpha(this Image source, int percent, Rectangle sourceRectangle)
+ {
+ return source.Process(sourceRectangle, new Alpha(percent));
+ }
}
}
diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj
index a7ec6d89a..53b0946a9 100644
--- a/src/ImageProcessor/ImageProcessor.csproj
+++ b/src/ImageProcessor/ImageProcessor.csproj
@@ -43,6 +43,7 @@
+
@@ -181,6 +182,7 @@
+
diff --git a/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs b/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
index dac009328..4d6cb78a5 100644
--- a/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
+++ b/tests/ImageProcessor.Tests/Processors/Filters/FilterTests.cs
@@ -1,12 +1,10 @@
namespace ImageProcessor.Tests
{
- using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using ImageProcessor.Filters;
- using ImageProcessor.Samplers;
using Xunit;
@@ -16,6 +14,7 @@ namespace ImageProcessor.Tests
{
{ "Contrast-50", new Contrast(50) },
{ "Contrast--50", new Contrast(-50) },
+ { "Alpha--50", new Alpha(50) },
};
[Theory]
@@ -43,30 +42,5 @@ namespace ImageProcessor.Tests
}
}
}
-
- [Fact]
- public void ResizeImage()
- {
- if (!Directory.Exists("Resized"))
- {
- Directory.CreateDirectory("Resized");
- }
-
- foreach (string file in Files)
- {
- using (FileStream stream = File.OpenRead(file))
- {
- Stopwatch watch = Stopwatch.StartNew();
- Image image = new Image(stream);
- string filename = Path.GetFileName(file);
- using (FileStream output = File.OpenWrite($"Resized/{ Path.GetFileName(filename) }"))
- {
- image.Resize(400, 400).Save(output);
- }
-
- Trace.WriteLine($"{ filename }: { watch.ElapsedMilliseconds}ms");
- }
- }
- }
}
}
diff --git a/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs b/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
index ffa4c5d54..c35ff951e 100644
--- a/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
+++ b/tests/ImageProcessor.Tests/Processors/Samplers/SamplerTests.cs
@@ -46,7 +46,8 @@ namespace ImageProcessor.Tests
string filename = Path.GetFileNameWithoutExtension(file) + "-" + name + Path.GetExtension(file);
using (FileStream output = File.OpenWrite($"Resized/{filename}"))
{
- image.Resize(image.Width / 2, image.Height / 2, sampler).Save(output);
+ //image.Resize(image.Width / 2, image.Height / 2, sampler).Save(output);
+ image.Resize(500, 500, sampler, new Rectangle(0, 0, 100, 100), new Rectangle(0, 0, 500, 500)).Save(output);
}
Trace.WriteLine($"{name}: {watch.ElapsedMilliseconds}ms");