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..07d96543b
--- /dev/null
+++ b/src/ImageProcessorConsole/images/input/Turtle.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9e5c576b0c5e743cfd498b110305268ecbae63c62061ba6c7eb8e060728191f1
+size 55126
diff --git a/src/ImageProcessorConsole/images/input/sample1.jpg b/src/ImageProcessorConsole/images/input/sample1.jpg
new file mode 100644
index 000000000..b56f9a83c
--- /dev/null
+++ b/src/ImageProcessorConsole/images/input/sample1.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:6b2012b2eda13a531645c287c254ae5de0e9070368cb4bc806f48314e0464ccd
+size 33850
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..e59f64110
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/1aaa.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d14cef359c56dd4c96a32bcd481f850a4fd92456f10924c489e40d11b6dec07f
+size 30595
diff --git a/src/ImageProcessorConsole/images/output/2006-citybus.jpg b/src/ImageProcessorConsole/images/output/2006-citybus.jpg
new file mode 100644
index 000000000..239c9e420
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/2006-citybus.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7b064358a5ea1ab9b955b003cfedad5766f7fbe4ed697ee5c78e99ab3da55367
+size 41725
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..4f6033272
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/2012-citybus.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:467ba90a3e6e12846a9688e23f6b88720a7122b5f56bd2941f593093845f432e
+size 40091
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 1cce96a6c..000000000
--- a/src/ImageProcessorConsole/images/output/4.sm.webp
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:bc9ccd29734ed06d2916389cc363955924f4bbb200fea91c113ae2b9334eca1f
-size 12162
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..952143496
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/IC580196.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e1d0a6823f6e169bddf04f53c6b9658dadfa5ec044d097521e2ad987c9476a32
+size 40336
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..02b83c21f
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/Turtle.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ac5e652d9164404b39a652a6835edfdd93407edf2dc5d4f5f177f304f3250251
+size 49160
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..eaf0eb91f
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/arc_de_triomphe_paris_france.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a8b8013175ece5b73dc5f8d20704c6b01b5de1649b0d553f1187d6ab199f0f5d
+size 35513
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 557d8631f..000000000
--- a/src/ImageProcessorConsole/images/output/circle.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:be35a2ed96081bdb3f2b6da83036554509f6b53b6a145f2ae5de91d381e63fc0
-size 5001
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..924e37a1e
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/mountain.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a1a2018c1936a90b0d61b2a007353cbdec7b322d7407413c64cb02ccea2e203c
+size 46923
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 4ad78f6dc..000000000
--- a/src/ImageProcessorConsole/images/output/night-bridge.jpg
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:7929c57d7a5711d6fec185afc0063ad1a3fbd4e281067a1b36f18682662752be
-size 56360
diff --git a/src/ImageProcessorConsole/images/output/rotate.jpg b/src/ImageProcessorConsole/images/output/rotate.jpg
new file mode 100644
index 000000000..1b7cf10aa
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/rotate.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3a74078fdeb9e790d1bf8352dfdbefded009f167666832fc9a84b51537730a7f
+size 49894
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..b6c778895
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/sample1.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b86a79be3c4c94ffb790b9bc8c60e294447c53bc05e308d14dd167df2c257ff9
+size 39071
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..e03394417
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/shutterstock_19173982_Arc_de_triomphe-square1.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5309055af67cbd35a21a2ad178bc0e7ec92c971329bdc2b3da4800d4dc27822f
+size 41847
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..673dd527e
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/test.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9638658680655e1c42b84f06728c8a0faa5ff82dbc1029118c93ada0553e2e7f
+size 54357
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 4534523db..000000000
--- a/src/ImageProcessorConsole/images/output/test.webp
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:b41b4fe144f9d3eaee706b516021efc7abc598f17655d9592866963bfa62f3ad
-size 5590
diff --git a/src/ImageProcessorConsole/images/output/tower.jpg b/src/ImageProcessorConsole/images/output/tower.jpg
new file mode 100644
index 000000000..97397b7ce
--- /dev/null
+++ b/src/ImageProcessorConsole/images/output/tower.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4d1f4409d53b75a5b650cd45356f70b3e05ad554aaf54211a810e7ca17ec21f1
+size 47276
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