diff --git a/src/ImageProcessor.sln.DotSettings b/src/ImageProcessor.sln.DotSettings
index 824137ce2..0395ee1ba 100644
--- a/src/ImageProcessor.sln.DotSettings
+++ b/src/ImageProcessor.sln.DotSettings
@@ -4,6 +4,8 @@
DT
FPX
FR
+ HSL
+ HSLA
ICC
ISO
JPEG
@@ -14,5 +16,7 @@
MD
OECF
REF
+ RGB
+ RGBA
SRGB
SS
\ No newline at end of file
diff --git a/src/ImageProcessor/ImageFactory.cs b/src/ImageProcessor/ImageFactory.cs
index 6b87c0ca9..6d7612871 100644
--- a/src/ImageProcessor/ImageFactory.cs
+++ b/src/ImageProcessor/ImageFactory.cs
@@ -596,6 +596,33 @@ namespace ImageProcessor
return this;
}
+ ///
+ /// Changes the hue of the current image.
+ ///
+ ///
+ /// The angle by which to alter the images hue.
+ /// Any integer between 0 and 359.
+ ///
+ ///
+ /// The current instance of the class.
+ ///
+ public ImageFactory Hue(int degrees)
+ {
+ // Sanitize the input.
+ if (degrees > 360 || degrees < 0)
+ {
+ degrees = 0;
+ }
+
+ if (this.ShouldProcess)
+ {
+ Hue hue = new Hue { DynamicParameter = degrees };
+ this.CurrentImageFormat.ApplyProcessor(hue.ProcessImage, this);
+ }
+
+ return this;
+ }
+
///
/// Alters the output quality of the current image.
///
diff --git a/src/ImageProcessor/ImageProcessor.csproj b/src/ImageProcessor/ImageProcessor.csproj
index bdaeb9ba9..f1fb72c47 100644
--- a/src/ImageProcessor/ImageProcessor.csproj
+++ b/src/ImageProcessor/ImageProcessor.csproj
@@ -70,6 +70,9 @@
+
+
+
@@ -118,6 +121,7 @@
+
diff --git a/src/ImageProcessor/Imaging/Colors/HSLAColor.cs b/src/ImageProcessor/Imaging/Colors/HSLAColor.cs
new file mode 100644
index 000000000..874abcd7a
--- /dev/null
+++ b/src/ImageProcessor/Imaging/Colors/HSLAColor.cs
@@ -0,0 +1,359 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Imaging.Colors
+{
+ using System;
+ using System.Drawing;
+
+ ///
+ /// Represents an HSLA (hue, saturation, luminosity, alpha) color.
+ ///
+ public struct HSLAColor
+ {
+ // Private data members below are on scale 0-1
+ // They are scaled for use externally based on scale
+
+ ///
+ /// The hue component.
+ ///
+ private double hue;
+
+ ///
+ /// The luminosity component.
+ ///
+ private double luminosity;
+
+ ///
+ /// The saturation component.
+ ///
+ private double saturation;
+
+ ///
+ /// The alpha component.
+ ///
+ private double a;
+
+ #region Constructors and Destructors
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The color.
+ ///
+ public HSLAColor(Color color)
+ : this()
+ {
+ this.SetRGBA(color.R, color.G, color.B, color.A);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The red.
+ ///
+ ///
+ /// The green.
+ ///
+ ///
+ /// The blue.
+ ///
+ public HSLAColor(int red, int green, int blue, int alpha)
+ : this()
+ {
+ this.SetRGBA(red, green, blue, alpha);
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The hue.
+ ///
+ ///
+ /// The saturation.
+ ///
+ ///
+ /// The luminosity.
+ ///
+ public HSLAColor(double hue, double saturation, double luminosity)
+ : this()
+ {
+ this.Hue = hue;
+ this.Saturation = saturation;
+ this.Luminosity = luminosity;
+ }
+
+ #endregion
+
+ #region Public Properties
+
+ ///
+ /// Gets or sets the hue.
+ ///
+ public double Hue
+ {
+ get
+ {
+ return this.hue;
+ }
+
+ set
+ {
+ this.hue = this.CheckRange(value);
+ }
+ }
+
+ ///
+ /// Gets or sets the luminosity.
+ ///
+ public double Luminosity
+ {
+ get
+ {
+ return this.luminosity;
+ }
+
+ set
+ {
+ this.luminosity = this.CheckRange(value);
+ }
+ }
+
+ ///
+ /// Gets or sets the saturation.
+ ///
+ public double Saturation
+ {
+ get
+ {
+ return this.saturation;
+ }
+
+ set
+ {
+ this.saturation = this.CheckRange(value);
+ }
+ }
+
+ #endregion
+
+ #region Public Methods and Operators
+
+ ///
+ /// The op_ implicit.
+ ///
+ ///
+ /// The hsl color.
+ ///
+ ///
+ ///
+ public static implicit operator Color(HSLAColor hslColor)
+ {
+ double r = 0, g = 0, b = 0;
+ if (Math.Abs(hslColor.luminosity - 0) > .0001)
+ {
+ if (Math.Abs(hslColor.saturation - 0) <= .0001)
+ {
+ r = g = b = hslColor.luminosity;
+ }
+ else
+ {
+ double temp2 = GetTemp2(hslColor);
+ double temp1 = (2.0 * hslColor.luminosity) - temp2;
+
+ r = GetColorComponent(temp1, temp2, hslColor.hue + (1.0 / 3.0));
+ g = GetColorComponent(temp1, temp2, hslColor.hue);
+ b = GetColorComponent(temp1, temp2, hslColor.hue - (1.0 / 3.0));
+ }
+ }
+
+ return Color.FromArgb((int)(255 * r), (int)(255 * g), (int)(255 * b));
+ }
+
+ ///
+ /// The op_ implicit.
+ ///
+ ///
+ /// The color.
+ ///
+ ///
+ ///
+ public static implicit operator HSLAColor(Color color)
+ {
+ HSLAColor hslColor = new HSLAColor
+ {
+ hue = color.GetHue() / 360.0,
+ luminosity = color.GetBrightness(),
+ saturation = color.GetSaturation()
+ };
+
+ return hslColor;
+ }
+
+ ///
+ /// The set rgb components.
+ ///
+ ///
+ /// The red.
+ ///
+ ///
+ /// The green component.
+ ///
+ ///
+ /// The blue component.
+ ///
+ ///
+ /// The alpha component.
+ ///
+ public void SetRGBA(int red, int green, int blue, int alpha)
+ {
+ HSLAColor hslColor = Color.FromArgb(alpha, red, green, blue);
+ this.hue = hslColor.hue;
+ this.saturation = hslColor.saturation;
+ this.luminosity = hslColor.luminosity;
+ this.a = hslColor.a;
+ }
+
+ ///
+ /// The to rgb string.
+ ///
+ ///
+ /// The .
+ ///
+ public string ToRGBString()
+ {
+ Color color = this;
+ return string.Format("R: {0:#0.##} G: {1:#0.##} B: {2:#0.##}", color.R, color.G, color.B);
+ }
+
+ ///
+ /// The to string.
+ ///
+ ///
+ /// The .
+ ///
+ public override string ToString()
+ {
+ return string.Format("H: {0:#0.##} S: {1:#0.##} L: {2:#0.##}", this.Hue, this.Saturation, this.Luminosity);
+ }
+
+ #endregion
+
+ #region Methods
+
+ ///
+ /// The get color component.
+ ///
+ ///
+ /// The temp 1.
+ ///
+ ///
+ /// The temp 2.
+ ///
+ ///
+ /// The temp 3.
+ ///
+ ///
+ /// The .
+ ///
+ private static double GetColorComponent(double temp1, double temp2, double temp3)
+ {
+ temp3 = MoveIntoRange(temp3);
+ if (temp3 < 1.0 / 6.0)
+ {
+ return temp1 + ((temp2 - temp1) * 6.0 * temp3);
+ }
+
+ if (temp3 < 0.5)
+ {
+ return temp2;
+ }
+
+ if (temp3 < 2.0 / 3.0)
+ {
+ return temp1 + ((temp2 - temp1) * ((2.0 / 3.0) - temp3) * 6.0);
+ }
+
+ return temp1;
+ }
+
+ ///
+ /// The get temp 2.
+ ///
+ ///
+ /// The hsl color.
+ ///
+ ///
+ /// The .
+ ///
+ private static double GetTemp2(HSLAColor hslColor)
+ {
+ double temp2;
+ if (hslColor.luminosity <= 0.5)
+ {
+ temp2 = hslColor.luminosity * (1.0 + hslColor.saturation);
+ }
+ else
+ {
+ temp2 = hslColor.luminosity + hslColor.saturation - (hslColor.luminosity * hslColor.saturation);
+ }
+
+ return temp2;
+ }
+
+ ///
+ /// The move into range.
+ ///
+ ///
+ /// The temp 3.
+ ///
+ ///
+ /// The .
+ ///
+ private static double MoveIntoRange(double temp3)
+ {
+ if (temp3 < 0.0)
+ {
+ temp3 += 1.0;
+ }
+ else if (temp3 > 1.0)
+ {
+ temp3 -= 1.0;
+ }
+
+ return temp3;
+ }
+
+ ///
+ /// The check range.
+ ///
+ ///
+ /// The value.
+ ///
+ ///
+ /// The .
+ ///
+ private double CheckRange(double value)
+ {
+ if (value < 0.0)
+ {
+ value = 0.0;
+ }
+ else if (value > 1.0)
+ {
+ value = 1.0;
+ }
+
+ return value;
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/ImageProcessor/Imaging/Colors/RGBAColor.cs b/src/ImageProcessor/Imaging/Colors/RGBAColor.cs
new file mode 100644
index 000000000..97b9048c1
--- /dev/null
+++ b/src/ImageProcessor/Imaging/Colors/RGBAColor.cs
@@ -0,0 +1,109 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Imaging.Colors
+{
+ using System.Drawing;
+
+ ///
+ /// Represents an RGBA (red, green, blue, alpha) color.
+ ///
+ public struct RGBAColor
+ {
+ ///
+ /// The alpha component.
+ ///
+ public byte A;
+
+ ///
+ /// The blue component.
+ ///
+ public byte B;
+
+ ///
+ /// The green component.
+ ///
+ public byte G;
+
+ ///
+ /// The red component.
+ ///
+ public byte R;
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The red component.
+ ///
+ ///
+ /// The green component.
+ ///
+ ///
+ /// The blue component.
+ ///
+ public RGBAColor(byte red, byte green, byte blue)
+ {
+ this.R = red;
+ this.G = green;
+ this.B = blue;
+ this.A = 255;
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The red component.
+ ///
+ ///
+ /// The green component.
+ ///
+ ///
+ /// The blue component.
+ ///
+ ///
+ /// The alpha component.
+ ///
+ public RGBAColor(byte red, byte green, byte blue, byte alpha)
+ {
+ this.R = red;
+ this.G = green;
+ this.B = blue;
+ this.A = alpha;
+ }
+
+ ///
+ /// Initializes a new instance of the struct.
+ ///
+ ///
+ /// The color.
+ ///
+ public RGBAColor(Color color)
+ {
+ this.R = color.R;
+ this.G = color.G;
+ this.B = color.B;
+ this.A = color.A;
+ }
+
+ ///
+ /// Allows the implicit conversion of an instance of to a
+ /// .
+ ///
+ ///
+ /// The instance of to convert.
+ ///
+ ///
+ /// An instance of .
+ ///
+ public static implicit operator Color(RGBAColor rgba)
+ {
+ return System.Drawing.Color.FromArgb(rgba.A, rgba.R, rgba.G, rgba.B);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageProcessor/Imaging/FastBitmap.cs b/src/ImageProcessor/Imaging/FastBitmap.cs
new file mode 100644
index 000000000..1ab929c10
--- /dev/null
+++ b/src/ImageProcessor/Imaging/FastBitmap.cs
@@ -0,0 +1,256 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Allows fast access to 's pixel data.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Imaging
+{
+ using System;
+ using System.Drawing;
+ using System.Drawing.Imaging;
+ using System.Runtime.InteropServices;
+
+ ///
+ /// Allows fast access to 's pixel data.
+ ///
+ public class FastBitmap : IDisposable
+ {
+ ///
+ /// The bitmap.
+ ///
+ private readonly Bitmap bitmap;
+
+ ///
+ /// The width of the bitmap.
+ ///
+ private readonly int width;
+
+ ///
+ /// The height of the bitmap.
+ ///
+ private readonly int height;
+
+ ///
+ /// The stride width of the bitmap.
+ ///
+ private int stride;
+
+ ///
+ /// The bitmap data.
+ ///
+ private BitmapData bitmapData;
+
+ ///
+ /// The pixel buffer for holding pixel data.
+ ///
+ private byte[] pixelBuffer;
+
+ ///
+ /// The buffer length.
+ ///
+ private int bufferLength;
+
+ ///
+ /// A value indicating whether this instance of the given entity has been disposed.
+ ///
+ /// if this instance has been disposed; otherwise, .
+ ///
+ /// If the entity is disposed, it must not be disposed a second
+ /// time. The isDisposed field is set the first time the entity
+ /// is disposed. If the isDisposed field is true, then the Dispose()
+ /// method will not dispose again. This help not to prolong the entity's
+ /// life in the Garbage Collector.
+ ///
+ private bool isDisposed;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The input bitmap.
+ public FastBitmap(Bitmap bitmap)
+ {
+ this.bitmap = bitmap;
+ this.width = this.bitmap.Width;
+ this.height = this.bitmap.Height;
+ this.LockBitmap();
+ }
+
+ ///
+ /// Gets the width, in pixels of the .
+ ///
+ public int Width
+ {
+ get
+ {
+ return this.width;
+ }
+ }
+
+ ///
+ /// Gets the height, in pixels of the .
+ ///
+ public int Height
+ {
+ get
+ {
+ return this.height;
+ }
+ }
+
+ ///
+ /// Allows the implicit conversion of an instance of to a
+ /// .
+ ///
+ ///
+ /// The instance of to convert.
+ ///
+ ///
+ /// An instance of .
+ ///
+ public static implicit operator Image(FastBitmap fastBitmap)
+ {
+ return fastBitmap.bitmap;
+ }
+
+ ///
+ /// Allows the implicit conversion of an instance of to a
+ /// .
+ ///
+ ///
+ /// The instance of to convert.
+ ///
+ ///
+ /// An instance of .
+ ///
+ public static implicit operator Bitmap(FastBitmap fastBitmap)
+ {
+ return fastBitmap.bitmap;
+ }
+
+ ///
+ /// Gets the color at the specified pixel of the .
+ ///
+ /// The x-coordinate of the pixel to retrieve.
+ /// The y-coordinate of the pixel to retrieve.
+ /// The at the given pixel.
+ public Color GetPixel(int x, int y)
+ {
+ if ((x < 0) || (x >= this.width))
+ {
+ throw new ArgumentOutOfRangeException("x", "Value cannot be less than zero or greater than the bitmap width.");
+ }
+
+ if ((y < 0) || (y >= this.height))
+ {
+ throw new ArgumentOutOfRangeException("y", "Value cannot be less than zero or greater than the bitmap height.");
+ }
+
+ int position = (x * 4) + (y * this.stride);
+ byte blue = this.pixelBuffer[position];
+ byte green = this.pixelBuffer[position + 1];
+ byte red = this.pixelBuffer[position + 2];
+ byte alpha = this.pixelBuffer[position + 3];
+ return Color.FromArgb(alpha, red, green, blue);
+ }
+
+ ///
+ /// Sets the color of the specified pixel of the .
+ ///
+ /// The x-coordinate of the pixel to set.
+ /// The y-coordinate of the pixel to set.
+ ///
+ /// A color structure that represents the
+ /// color to set the specified pixel.
+ ///
+ public void SetPixel(int x, int y, Color color)
+ {
+ if ((x < 0) || (x >= this.width))
+ {
+ throw new ArgumentOutOfRangeException("x", "Value cannot be less than zero or greater than the bitmap width.");
+ }
+
+ if ((y < 0) || (y >= this.height))
+ {
+ throw new ArgumentOutOfRangeException("y", "Value cannot be less than zero or greater than the bitmap height.");
+ }
+
+ int position = (x * 4) + (y * this.stride);
+ this.pixelBuffer[position] = color.B;
+ this.pixelBuffer[position + 1] = color.G;
+ this.pixelBuffer[position + 2] = color.R;
+ this.pixelBuffer[position + 3] = color.A;
+ }
+
+ ///
+ /// Disposes the object and frees resources for the Garbage Collector.
+ ///
+ public void Dispose()
+ {
+ this.Dispose(true);
+
+ // This object will be cleaned up by the Dispose method.
+ // Therefore, you should call GC.SupressFinalize to
+ // take this object off the finalization queue
+ // and prevent finalization code for this object
+ // from executing a second time.
+ GC.SuppressFinalize(this);
+ }
+
+ ///
+ /// Disposes the object and frees resources for the Garbage Collector.
+ ///
+ /// If true, the object gets disposed.
+ protected virtual void Dispose(bool disposing)
+ {
+ if (this.isDisposed)
+ {
+ return;
+ }
+
+ if (disposing)
+ {
+ // Dispose of any managed resources here.
+ this.UnlockBitmap();
+ }
+
+ // Call the appropriate methods to clean up
+ // unmanaged resources here.
+ // Note disposing is done.
+ this.isDisposed = true;
+ }
+
+ ///
+ /// Locks the bitmap into system memory.
+ ///
+ private void LockBitmap()
+ {
+ Rectangle bounds = new Rectangle(Point.Empty, this.bitmap.Size);
+
+ // Lock the bitmap
+ this.bitmapData = this.bitmap.LockBits(bounds, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
+
+ // Copy the bitmap data across to the array for manipulation.
+ this.stride = this.bitmapData.Stride;
+ this.bufferLength = this.stride * this.bitmapData.Height;
+ this.pixelBuffer = new byte[this.bufferLength];
+ Marshal.Copy(this.bitmapData.Scan0, this.pixelBuffer, 0, this.pixelBuffer.Length);
+ }
+
+ ///
+ /// Unlocks the bitmap from system memory.
+ ///
+ private void UnlockBitmap()
+ {
+ // Copy the RGB values back to the bitmap and unlock the bitmap.
+ Marshal.Copy(this.pixelBuffer, 0, this.bitmapData.Scan0, this.bufferLength);
+ this.bitmap.UnlockBits(this.bitmapData);
+ this.bitmapData = null;
+ this.pixelBuffer = null;
+ }
+ }
+}
diff --git a/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs b/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs
index 7d90d0bf9..18895b4a0 100644
--- a/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs
+++ b/src/ImageProcessor/Imaging/Filters/ComicMatrixFilter.cs
@@ -12,7 +12,6 @@ namespace ImageProcessor.Imaging.Filters
{
#region Using
using System;
- using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
@@ -27,23 +26,6 @@ namespace ImageProcessor.Imaging.Filters
///
internal class ComicMatrixFilter : MatrixFilterBase
{
- ///
- /// Enumerates Argb color channels.
- ///
- [SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
- private enum ChannelArgb
- {
- ///
- /// The blue channel
- ///
- Blue = 0,
-
- ///
- /// The alpha channel
- ///
- Alpha = 3
- }
-
///
/// Gets the for this filter instance.
///
@@ -127,7 +109,7 @@ namespace ImageProcessor.Imaging.Filters
}
// Transfer the alpha channel from the mask to the high saturation image.
- TransferOneArgbChannelFromOneBitmapToAnother(patternBitmap, lowBitmap, ChannelArgb.Blue, ChannelArgb.Alpha);
+ ApplyMask(patternBitmap, lowBitmap);
using (Graphics graphics = Graphics.FromImage(newImage))
{
@@ -511,7 +493,7 @@ namespace ImageProcessor.Imaging.Filters
}
///
- /// Transfers a single ARGB channel from one image to another.
+ /// Applies a mask .
///
///
/// The source.
@@ -519,65 +501,38 @@ namespace ImageProcessor.Imaging.Filters
///
/// The destination.
///
- ///
- /// The source channel.
- ///
- ///
- /// The destination channel.
- ///
- private static void TransferOneArgbChannelFromOneBitmapToAnother(Bitmap source, Bitmap destination, ChannelArgb sourceChannel, ChannelArgb destinationChannel)
+ ///
+ /// Thrown if the two images are of different size.
+ ///
+ private static void ApplyMask(Bitmap source, Bitmap destination)
{
if (source.Size != destination.Size)
{
throw new ArgumentException();
}
- Rectangle rectangle = new Rectangle(Point.Empty, source.Size);
-
- // Lock the source.
- BitmapData bitmapDataSource = source.LockBits(rectangle, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
-
- // Declare an array to hold the bytes of the bitmap.
- int bytes = bitmapDataSource.Stride * bitmapDataSource.Height;
-
- // Allocate a buffer for the source image
- byte[] sourceRgbValues = new byte[bytes];
-
- // Copy the RGB values into the array.
- Marshal.Copy(bitmapDataSource.Scan0, sourceRgbValues, 0, bytes);
-
- // Unlock the source.
- source.UnlockBits(bitmapDataSource);
-
- // Lock the destination.
- BitmapData bitmapDataDestination = destination.LockBits(rectangle, ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
-
- // Allocate a buffer for image
- byte[] destinationRgbValues = new byte[bytes];
-
- // Copy the RGB values into the array.
- Marshal.Copy(bitmapDataDestination.Scan0, destinationRgbValues, 0, bytes);
-
- int s = (int)sourceChannel;
- int d = (int)destinationChannel;
-
- for (int i = rectangle.Height * rectangle.Width; i > 0; i--)
+ using (FastBitmap sourceBitmap = new FastBitmap(source))
{
- // Copy the alpha values across.
- if (destinationRgbValues[d] != 0)
+ using (FastBitmap destinationBitmap = new FastBitmap(destination))
{
- destinationRgbValues[d] = sourceRgbValues[s];
- }
+ int width = source.Width;
+ int height = source.Height;
- d += 4;
- s += 4;
- }
-
- // Copy the RGB values back to the bitmap
- Marshal.Copy(destinationRgbValues, 0, bitmapDataDestination.Scan0, bytes);
+ for (int i = 0; i < width; i++)
+ {
+ for (int j = 0; j < height; j++)
+ {
+ Color sourceColor = sourceBitmap.GetPixel(i, j);
+ Color destinationColor = destinationBitmap.GetPixel(i, j);
- // Unlock bits the destination.
- destination.UnlockBits(bitmapDataDestination);
+ if (destinationColor.A != 0)
+ {
+ destinationBitmap.SetPixel(i, j, Color.FromArgb(sourceColor.B, destinationColor.R, destinationColor.G, destinationColor.B));
+ }
+ }
+ }
+ }
+ }
}
}
}
\ No newline at end of file
diff --git a/src/ImageProcessor/Processors/Alpha.cs b/src/ImageProcessor/Processors/Alpha.cs
index a27e5f6f9..85254ce71 100644
--- a/src/ImageProcessor/Processors/Alpha.cs
+++ b/src/ImageProcessor/Processors/Alpha.cs
@@ -31,7 +31,7 @@ namespace ImageProcessor.Processors
}
///
- /// Gets or sets DynamicParameter.
+ /// Gets or sets the dynamic parameter.
///
public dynamic DynamicParameter
{
diff --git a/src/ImageProcessor/Processors/Hue.cs b/src/ImageProcessor/Processors/Hue.cs
new file mode 100644
index 000000000..1dbe820f0
--- /dev/null
+++ b/src/ImageProcessor/Processors/Hue.cs
@@ -0,0 +1,96 @@
+// --------------------------------------------------------------------------------------------------------------------
+//
+// Copyright (c) James South.
+// Licensed under the Apache License, Version 2.0.
+//
+//
+// Encapsulates methods to rotate the hue component of an image.
+//
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace ImageProcessor.Processors
+{
+ using System;
+ using System.Collections.Generic;
+ using System.Drawing;
+ using ImageProcessor.Common.Exceptions;
+ using ImageProcessor.Imaging;
+ using ImageProcessor.Imaging.Colors;
+
+ ///
+ /// Encapsulates methods to rotate the hue component of an image.
+ ///
+ public class Hue : IGraphicsProcessor
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Hue()
+ {
+ this.Settings = new Dictionary();
+ }
+
+ ///
+ /// Gets or sets the dynamic parameter.
+ ///
+ public dynamic DynamicParameter { get; set; }
+
+ ///
+ /// Gets or sets any additional settings required by the processor.
+ ///
+ public Dictionary Settings { get; set; }
+
+ ///
+ /// Processes the image.
+ ///
+ ///
+ /// The current instance of the class containing
+ /// the image to process.
+ ///
+ ///
+ /// The processed image from the current instance of the class.
+ ///
+ public Image ProcessImage(ImageFactory factory)
+ {
+ Bitmap newImage = null;
+ Image image = factory.Image;
+
+ try
+ {
+ int degrees = this.DynamicParameter;
+ int width = image.Width;
+ int height = image.Height;
+
+ newImage = new Bitmap(image);
+
+ using (FastBitmap fastBitmap = new FastBitmap(newImage))
+ {
+ for (int i = 0; i < width; i++)
+ {
+ for (int j = 0; j < height; j++)
+ {
+ HSLAColor hsl = new HSLAColor(fastBitmap.GetPixel(i, j));
+ hsl.Hue = (hsl.Hue + (degrees / 360f)) % 1;
+ //hsl.Hue = (degrees / 360f);
+ fastBitmap.SetPixel(i, j, hsl);
+ }
+ }
+ }
+
+ image.Dispose();
+ image = newImage;
+ }
+ catch (Exception ex)
+ {
+ if (newImage != null)
+ {
+ newImage.Dispose();
+ }
+
+ throw new ImageProcessingException("Error processing image with " + this.GetType().Name, ex);
+ }
+
+ return image;
+ }
+ }
+}
diff --git a/src/ImageProcessorConsole/Program.cs b/src/ImageProcessorConsole/Program.cs
index f7658b7d1..ff9b50176 100644
--- a/src/ImageProcessorConsole/Program.cs
+++ b/src/ImageProcessorConsole/Program.cs
@@ -17,6 +17,7 @@ namespace ImageProcessorConsole
using System.IO;
using System.Linq;
using ImageProcessor;
+ using ImageProcessor.Imaging;
using ImageProcessor.Plugins.Cair;
using ImageProcessor.Plugins.Cair.Imaging;
@@ -50,7 +51,15 @@ namespace ImageProcessorConsole
{
byte[] photoBytes = File.ReadAllBytes(fileInfo.FullName);
- Console.WriteLine("Processing: " + fileInfo.Name);
+ //Color color = Color.Green;
+ //HSLAColor hslaColor = HSLAColor.FromRGBA(color);
+ //Console.WriteLine("H:" + hslaColor.H + " S:" + hslaColor.S + " L:" + hslaColor.L);
+
+ //Color color2 = HSLAColor.ToRGBA(hslaColor);
+
+ //Console.WriteLine("Color Out: " + "R:" + color2.R + " G:" + color2.G + " B:" + color2.B + " A:" + color2.A);
+ //Console.WriteLine(color2 == Color.Green);
+ //Console.WriteLine("Processing: " + fileInfo.Name);
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
@@ -60,19 +69,20 @@ namespace ImageProcessorConsole
{
using (ImageFactory imageFactory = new ImageFactory(true))
{
- Size size = new Size(800, 0);
+ Size size = new Size(448, 0);
- ContentAwareResizeLayer layer = new ContentAwareResizeLayer(size)
- {
- ConvolutionType = ConvolutionType.Sobel
- };
+ //ContentAwareResizeLayer layer = new ContentAwareResizeLayer(size)
+ //{
+ // ConvolutionType = ConvolutionType.Sobel
+ //};
// Load, resize, set the format and quality and save an image.
imageFactory.Load(inStream)
//.BackgroundColor(Color.White)
//.Resize(new Size((int)(size.Width * 1.1), 0))
- .ContentAwareResize(layer)
- //.Constrain(size)
+ //.ContentAwareResize(layer)
+ .Constrain(size)
+ .Hue(180)
.Save(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path), @"..\..\images\output", fileInfo.Name)));
stopwatch.Stop();
@@ -81,6 +91,8 @@ namespace ImageProcessorConsole
Console.WriteLine("Processed: " + fileInfo.Name + " in " + stopwatch.ElapsedMilliseconds + "ms");
}
+
+ Console.ReadLine();
}
public static IEnumerable GetFilesByExtensions(DirectoryInfo dir, params string[] extensions)
diff --git a/src/ImageProcessorConsole/images/input/Image with gaps.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/input/1aaa.jpg.REMOVED.git-id
similarity index 100%
rename from src/ImageProcessorConsole/images/input/Image with gaps.jpg.REMOVED.git-id
rename to src/ImageProcessorConsole/images/input/1aaa.jpg.REMOVED.git-id
diff --git a/src/ImageProcessorConsole/images/input/IC580196.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/input/IC580196.jpg.REMOVED.git-id
new file mode 100644
index 000000000..9309d677c
--- /dev/null
+++ b/src/ImageProcessorConsole/images/input/IC580196.jpg.REMOVED.git-id
@@ -0,0 +1 @@
+9ab3fa52dd238ee4caffb47c82929f4079dc38d3
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/input/Turtle.jpg b/src/ImageProcessorConsole/images/input/Turtle.jpg
new file mode 100644
index 000000000..0e9319495
Binary files /dev/null and b/src/ImageProcessorConsole/images/input/Turtle.jpg differ
diff --git a/src/ImageProcessorConsole/images/input/sample1.jpg b/src/ImageProcessorConsole/images/input/sample1.jpg
new file mode 100644
index 000000000..909fa4fc5
Binary files /dev/null and b/src/ImageProcessorConsole/images/input/sample1.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/120430.gif.REMOVED.git-id b/src/ImageProcessorConsole/images/output/120430.gif.REMOVED.git-id
deleted file mode 100644
index 7c7807f6d..000000000
--- a/src/ImageProcessorConsole/images/output/120430.gif.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-e41022eb5fe724ba5fe2b7aeda29a1f4b6878484
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/1aaa.jpg b/src/ImageProcessorConsole/images/output/1aaa.jpg
new file mode 100644
index 000000000..a1e293443
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/1aaa.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/2006-citybus.jpg b/src/ImageProcessorConsole/images/output/2006-citybus.jpg
new file mode 100644
index 000000000..505463e44
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/2006-citybus.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/2006-citybus.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/2006-citybus.jpg.REMOVED.git-id
deleted file mode 100644
index 233b2595f..000000000
--- a/src/ImageProcessorConsole/images/output/2006-citybus.jpg.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-c6cb11afaf9fdb9181772246e5c873d8f7d1b99c
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/2008.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/2008.jpg.REMOVED.git-id
index 01ba57354..be943537b 100644
--- a/src/ImageProcessorConsole/images/output/2008.jpg.REMOVED.git-id
+++ b/src/ImageProcessorConsole/images/output/2008.jpg.REMOVED.git-id
@@ -1 +1 @@
-10b48cac44776a023df7585ba2c68c3f51b0f803
\ No newline at end of file
+73753ca19a0818ee4a88b6e9e0eb85ca17624269
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/2012-citybus.jpg b/src/ImageProcessorConsole/images/output/2012-citybus.jpg
new file mode 100644
index 000000000..fe960faf1
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/2012-citybus.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/2012-citybus.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/2012-citybus.jpg.REMOVED.git-id
deleted file mode 100644
index 731a81b1a..000000000
--- a/src/ImageProcessorConsole/images/output/2012-citybus.jpg.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-e631eb3491496bb83f99cd41a752f79c9d7f6830
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/4.sm.webp b/src/ImageProcessorConsole/images/output/4.sm.webp
deleted file mode 100644
index 90a630864..000000000
Binary files a/src/ImageProcessorConsole/images/output/4.sm.webp and /dev/null differ
diff --git a/src/ImageProcessorConsole/images/output/Arc-de-Triomphe-France.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/Arc-de-Triomphe-France.jpg.REMOVED.git-id
index 437ecbc46..488b8b110 100644
--- a/src/ImageProcessorConsole/images/output/Arc-de-Triomphe-France.jpg.REMOVED.git-id
+++ b/src/ImageProcessorConsole/images/output/Arc-de-Triomphe-France.jpg.REMOVED.git-id
@@ -1 +1 @@
-782056919992bb7e453eeee5d9c0034e03b57506
\ No newline at end of file
+dff097307936637d1c43f82ca28f4582c9810de7
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/IC580196.jpg b/src/ImageProcessorConsole/images/output/IC580196.jpg
new file mode 100644
index 000000000..ce638c384
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/IC580196.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/Image with gaps.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/Image with gaps.jpg.REMOVED.git-id
deleted file mode 100644
index 99c38fa2f..000000000
--- a/src/ImageProcessorConsole/images/output/Image with gaps.jpg.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-1d9ded0201edcd248140b4ec02f69ccdb4b539e5
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/Tl4Yb.gif.REMOVED.git-id b/src/ImageProcessorConsole/images/output/Tl4Yb.gif.REMOVED.git-id
deleted file mode 100644
index 60a69fbf6..000000000
--- a/src/ImageProcessorConsole/images/output/Tl4Yb.gif.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-f5681324d193a42492647f4952057c2b72026096
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/Turtle.jpg b/src/ImageProcessorConsole/images/output/Turtle.jpg
new file mode 100644
index 000000000..eff244f04
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/Turtle.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/arc_de_triomphe_paris_france.jpg b/src/ImageProcessorConsole/images/output/arc_de_triomphe_paris_france.jpg
new file mode 100644
index 000000000..e0718165d
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/arc_de_triomphe_paris_france.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/arc_de_triomphe_paris_france.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/arc_de_triomphe_paris_france.jpg.REMOVED.git-id
deleted file mode 100644
index b55932abb..000000000
--- a/src/ImageProcessorConsole/images/output/arc_de_triomphe_paris_france.jpg.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-2880457cc09cd2897b5f9f377807ec22f8f83013
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/circle.png b/src/ImageProcessorConsole/images/output/circle.png
deleted file mode 100644
index 893ca4021..000000000
Binary files a/src/ImageProcessorConsole/images/output/circle.png and /dev/null differ
diff --git a/src/ImageProcessorConsole/images/output/monster.png.REMOVED.git-id b/src/ImageProcessorConsole/images/output/monster.png.REMOVED.git-id
deleted file mode 100644
index 11e46ba6d..000000000
--- a/src/ImageProcessorConsole/images/output/monster.png.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-d8d3354b684cad79d9a46f92ed3a58747a808ad1
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/mountain.jpg b/src/ImageProcessorConsole/images/output/mountain.jpg
new file mode 100644
index 000000000..3d19463a2
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/mountain.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/mountain.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/mountain.jpg.REMOVED.git-id
deleted file mode 100644
index aba0ec52f..000000000
--- a/src/ImageProcessorConsole/images/output/mountain.jpg.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-34dcced6c7c3e4dd6fae239eba8eddef6234028d
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/nLpfllv.gif.REMOVED.git-id b/src/ImageProcessorConsole/images/output/nLpfllv.gif.REMOVED.git-id
deleted file mode 100644
index f187b0ed5..000000000
--- a/src/ImageProcessorConsole/images/output/nLpfllv.gif.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-b65d9e937cad7ddd02ff0d01a3be2f09c55e63e8
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/night-bridge.jpg b/src/ImageProcessorConsole/images/output/night-bridge.jpg
deleted file mode 100644
index 8ca2a95c7..000000000
Binary files a/src/ImageProcessorConsole/images/output/night-bridge.jpg and /dev/null differ
diff --git a/src/ImageProcessorConsole/images/output/rotate.jpg b/src/ImageProcessorConsole/images/output/rotate.jpg
new file mode 100644
index 000000000..aa68c6cab
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/rotate.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/rotate.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/rotate.jpg.REMOVED.git-id
deleted file mode 100644
index ec3d83b76..000000000
--- a/src/ImageProcessorConsole/images/output/rotate.jpg.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-de6754762f7705f9109ea364f42ca128e454e853
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/sample1.jpg b/src/ImageProcessorConsole/images/output/sample1.jpg
new file mode 100644
index 000000000..add729e24
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/sample1.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/shutterstock_19173982_Arc_de_triomphe-square1.jpg b/src/ImageProcessorConsole/images/output/shutterstock_19173982_Arc_de_triomphe-square1.jpg
new file mode 100644
index 000000000..09bbbf3a0
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/shutterstock_19173982_Arc_de_triomphe-square1.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/shutterstock_19173982_Arc_de_triomphe-square1.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/shutterstock_19173982_Arc_de_triomphe-square1.jpg.REMOVED.git-id
deleted file mode 100644
index 481fa6aaa..000000000
--- a/src/ImageProcessorConsole/images/output/shutterstock_19173982_Arc_de_triomphe-square1.jpg.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-24db72130626e81b9a4262c891dd28e6d97e5a96
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/test.jpg b/src/ImageProcessorConsole/images/output/test.jpg
new file mode 100644
index 000000000..3c0bc5a16
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/test.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/test.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/test.jpg.REMOVED.git-id
deleted file mode 100644
index 65ec37fb7..000000000
--- a/src/ImageProcessorConsole/images/output/test.jpg.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-4885438f0b97e3aae59d6e214b5ec455358ae225
\ No newline at end of file
diff --git a/src/ImageProcessorConsole/images/output/test.webp b/src/ImageProcessorConsole/images/output/test.webp
deleted file mode 100644
index 549fb9c6b..000000000
Binary files a/src/ImageProcessorConsole/images/output/test.webp and /dev/null differ
diff --git a/src/ImageProcessorConsole/images/output/tower.jpg b/src/ImageProcessorConsole/images/output/tower.jpg
new file mode 100644
index 000000000..a5644d65d
Binary files /dev/null and b/src/ImageProcessorConsole/images/output/tower.jpg differ
diff --git a/src/ImageProcessorConsole/images/output/tower.jpg.REMOVED.git-id b/src/ImageProcessorConsole/images/output/tower.jpg.REMOVED.git-id
deleted file mode 100644
index 83258a103..000000000
--- a/src/ImageProcessorConsole/images/output/tower.jpg.REMOVED.git-id
+++ /dev/null
@@ -1 +0,0 @@
-2d5b165c27545a3860d8a6b35f8ac4438f57593a
\ No newline at end of file