Browse Source

Adding Hue and HueRotate

Former-commit-id: 654fd398b5ff802c2ad23f0eea38773337dc8ceb
pull/17/head
James South 12 years ago
parent
commit
42ae3a047b
  1. 37
      src/ImageProcessor.UnitTests/ImageFactoryUnitTests.cs
  2. 1
      src/ImageProcessor.UnitTests/ImageProcessor.UnitTests.csproj
  3. 61
      src/ImageProcessor.UnitTests/Imaging/ColorUnitTests.cs
  4. 31
      src/ImageProcessor/ImageFactory.cs
  5. 1
      src/ImageProcessor/ImageProcessor.csproj
  6. 291
      src/ImageProcessor/Imaging/Colors/HSLAColor.cs
  7. 91
      src/ImageProcessor/Imaging/Colors/RGBAColor.cs
  8. 8
      src/ImageProcessor/Processors/Hue.cs
  9. 95
      src/ImageProcessor/Processors/HueRotate.cs
  10. 3
      src/ImageProcessorConsole/Program.cs
  11. BIN
      src/ImageProcessorConsole/images/output/1aaa.jpg
  12. BIN
      src/ImageProcessorConsole/images/output/2006-citybus.jpg
  13. 1
      src/ImageProcessorConsole/images/output/2008.jpg.REMOVED.git-id
  14. BIN
      src/ImageProcessorConsole/images/output/2012-citybus.jpg
  15. 1
      src/ImageProcessorConsole/images/output/Arc-de-Triomphe-France.jpg.REMOVED.git-id
  16. BIN
      src/ImageProcessorConsole/images/output/IC580196.jpg
  17. BIN
      src/ImageProcessorConsole/images/output/Turtle.jpg
  18. BIN
      src/ImageProcessorConsole/images/output/arc_de_triomphe_paris_france.jpg
  19. BIN
      src/ImageProcessorConsole/images/output/mountain.jpg
  20. BIN
      src/ImageProcessorConsole/images/output/rotate.jpg
  21. BIN
      src/ImageProcessorConsole/images/output/sample1.jpg
  22. BIN
      src/ImageProcessorConsole/images/output/shutterstock_19173982_Arc_de_triomphe-square1.jpg
  23. BIN
      src/ImageProcessorConsole/images/output/test.jpg
  24. BIN
      src/ImageProcessorConsole/images/output/tower.jpg

37
src/ImageProcessor.UnitTests/ImageFactoryUnitTests.cs

@ -15,6 +15,9 @@ namespace ImageProcessor.UnitTests
using System.Drawing;
using System.IO;
using System.Linq;
using ImageProcessor.Imaging;
using NUnit.Framework;
/// <summary>
@ -244,7 +247,7 @@ namespace ImageProcessor.UnitTests
{
imageFactory.Load(file.FullName);
Image original = (Image)imageFactory.Image.Clone();
imageFactory.Watermark(new Imaging.TextLayer
imageFactory.Watermark(new TextLayer
{
FontFamily = new FontFamily("Arial"),
FontSize = 10,
@ -286,7 +289,7 @@ namespace ImageProcessor.UnitTests
{
imageFactory.Load(file.FullName);
Image original = (Image)imageFactory.Image.Clone();
imageFactory.GaussianBlur(new Imaging.GaussianLayer { Sigma = 10, Size = 5, Threshold = 2 });
imageFactory.GaussianBlur(new GaussianLayer { Sigma = 10, Size = 5, Threshold = 2 });
Assert.AreNotEqual(original, imageFactory.Image);
}
}
@ -322,7 +325,7 @@ namespace ImageProcessor.UnitTests
{
imageFactory.Load(file.FullName);
Image original = (Image)imageFactory.Image.Clone();
imageFactory.GaussianSharpen(new Imaging.GaussianLayer { Sigma = 10, Size = 5, Threshold = 2 });
imageFactory.GaussianSharpen(new GaussianLayer { Sigma = 10, Size = 5, Threshold = 2 });
Assert.AreNotEqual(original, imageFactory.Image);
}
}
@ -341,43 +344,43 @@ namespace ImageProcessor.UnitTests
imageFactory.Load(file.FullName);
Image original = (Image)imageFactory.Image.Clone();
imageFactory.Filter(Imaging.Filters.MatrixFilters.BlackWhite);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.BlackWhite);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(Imaging.Filters.MatrixFilters.Comic);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Comic);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(Imaging.Filters.MatrixFilters.Gotham);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Gotham);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(Imaging.Filters.MatrixFilters.GreyScale);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.GreyScale);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(Imaging.Filters.MatrixFilters.HiSatch);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.HiSatch);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(Imaging.Filters.MatrixFilters.Invert);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Invert);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(Imaging.Filters.MatrixFilters.Lomograph);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Lomograph);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(Imaging.Filters.MatrixFilters.LoSatch);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.LoSatch);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(Imaging.Filters.MatrixFilters.Polaroid);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Polaroid);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
imageFactory.Filter(Imaging.Filters.MatrixFilters.Sepia);
imageFactory.Filter(ImageProcessor.Imaging.Filters.MatrixFilters.Sepia);
Assert.AreNotEqual(original, imageFactory.Image);
imageFactory.Reset();
}
@ -396,7 +399,7 @@ namespace ImageProcessor.UnitTests
{
imageFactory.Load(file.FullName);
Image original = (Image)imageFactory.Image.Clone();
imageFactory.RoundedCorners(new Imaging.RoundedCornerLayer(5));
imageFactory.RoundedCorners(new RoundedCornerLayer(5));
Assert.AreNotEqual(original, imageFactory.Image);
}
}
@ -455,7 +458,7 @@ namespace ImageProcessor.UnitTests
{
imageFactory.Load(file.FullName);
Image original = (Image)imageFactory.Image.Clone();
imageFactory.Crop(new Imaging.CropLayer(0, 0, MaxSize, MaxSize, Imaging.CropMode.Pixels));
imageFactory.Crop(new CropLayer(0, 0, MaxSize, MaxSize, CropMode.Pixels));
Assert.AreNotEqual(original, imageFactory.Image);
Assert.AreEqual(MaxSize, imageFactory.Image.Width);
Assert.LessOrEqual(MaxSize, imageFactory.Image.Height);
@ -481,7 +484,7 @@ namespace ImageProcessor.UnitTests
Assert.AreEqual(original.Height, imageFactory.Image.Height);
imageFactory.Reset();
imageFactory.Flip(false);
imageFactory.Flip();
Assert.AreNotEqual(original, imageFactory.Image);
Assert.AreEqual(original.Width, imageFactory.Image.Width);
Assert.AreEqual(original.Height, imageFactory.Image.Height);
@ -520,7 +523,7 @@ namespace ImageProcessor.UnitTests
using (ImageFactory imageFactory = new ImageFactory())
{
imageFactory.Load(file.FullName);
imageFactory.Resize(new Imaging.ResizeLayer(new Size(NewSize, NewSize), Imaging.ResizeMode.Stretch, Imaging.AnchorPosition.Left));
imageFactory.Resize(new ResizeLayer(new Size(NewSize, NewSize), ResizeMode.Stretch, AnchorPosition.Left));
Assert.AreEqual(NewSize, imageFactory.Image.Width);
Assert.AreEqual(NewSize, imageFactory.Image.Height);
}

1
src/ImageProcessor.UnitTests/ImageProcessor.UnitTests.csproj

@ -51,6 +51,7 @@
</Compile>
<Compile Include="Extensions\DoubleExtensionsUnitTests.cs" />
<Compile Include="Extensions\IntegerExtensionsUnitTests.cs" />
<Compile Include="Imaging\ColorUnitTests.cs" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ItemGroup>

61
src/ImageProcessor.UnitTests/Imaging/ColorUnitTests.cs

@ -0,0 +1,61 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ColorUnitTests.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Test harness for the color classes.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.UnitTests.Imaging
{
using System.Drawing;
using ImageProcessor.Imaging.Colors;
using NUnit.Framework;
/// <summary>
/// Test harness for the color classes.
/// </summary>
[TestFixture]
public class ColorUnitTests
{
/// <summary>
/// Tests the <see cref="RGBAColor"/> struct equality operators.
/// </summary>
[Test]
public void TestRGBAEquality()
{
RGBAColor first = new RGBAColor(Color.White);
RGBAColor second = new RGBAColor(Color.White);
Assert.AreEqual(first, second);
}
/// <summary>
/// Tests the <see cref="RGBAColor"/> struct equality operators.
/// </summary>
[Test]
public void TestHSLAEquality()
{
HSLAColor first = new HSLAColor(Color.White);
HSLAColor second = new HSLAColor(Color.White);
Assert.AreEqual(first, second);
}
/// <summary>
/// Test conversion to and from a HSLA color.
/// </summary>
[Test]
public void TestHSLAConversion()
{
const string Hex = "#FEFFFE";
Color color = ColorTranslator.FromHtml(Hex);
HSLAColor hslaColor = new HSLAColor(color);
string outPut = ColorTranslator.ToHtml(hslaColor);
Assert.AreEqual(Hex, outPut);
}
}
}

31
src/ImageProcessor/ImageFactory.cs

@ -597,11 +597,11 @@ namespace ImageProcessor
}
/// <summary>
/// Changes the hue of the current image.
/// Alters the hue of the current image changing the overall color.
/// </summary>
/// <param name="degrees">
/// The angle by which to alter the images hue.
/// Any integer between 0 and 359.
/// Any integer between 0 and 360.
/// </param>
/// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
@ -623,6 +623,33 @@ namespace ImageProcessor
return this;
}
/// <summary>
/// Rotates the hue of the current image altering each color.
/// </summary>
/// <param name="degrees">
/// The angle by which to rotate the images hue.
/// Any integer between 0 and 360.
/// </param>
/// <returns>
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
public ImageFactory HueRotate(int degrees)
{
// Sanitize the input.
if (degrees > 360 || degrees < 0)
{
degrees = 0;
}
if (this.ShouldProcess)
{
HueRotate hue = new HueRotate { DynamicParameter = degrees };
this.CurrentImageFormat.ApplyProcessor(hue.ProcessImage, this);
}
return this;
}
/// <summary>
/// Alters the output quality of the current image.
/// <remarks>

1
src/ImageProcessor/ImageProcessor.csproj

@ -121,6 +121,7 @@
<Compile Include="Processors\Brightness.cs" />
<Compile Include="Processors\Contrast.cs" />
<Compile Include="Processors\GaussianSharpen.cs" />
<Compile Include="Processors\HueRotate.cs" />
<Compile Include="Processors\Hue.cs" />
<Compile Include="Processors\Meta.cs" />
<Compile Include="Processors\RoundedCorners.cs" />

291
src/ImageProcessor/Imaging/Colors/HSLAColor.cs

@ -12,6 +12,7 @@ namespace ImageProcessor.Imaging.Colors
/// <summary>
/// Represents an HSLA (hue, saturation, luminosity, alpha) color.
/// Adapted from <see href="http://richnewman.wordpress.com/about/code-listings-and-diagrams/hslcolor-class/"/>
/// </summary>
public struct HSLAColor
{
@ -21,235 +22,293 @@ namespace ImageProcessor.Imaging.Colors
/// <summary>
/// The hue component.
/// </summary>
private double hue;
private double h;
/// <summary>
/// The luminosity component.
/// </summary>
private double luminosity;
private double l;
/// <summary>
/// The saturation component.
/// </summary>
private double saturation;
private double s;
/// <summary>
/// The alpha component.
/// </summary>
private double a;
#region Constructors and Destructors
/// <summary>
/// Initializes a new instance of the <see cref="HSLAColor"/> struct.
/// </summary>
/// <param name="color">
/// The color.
/// <param name="hue">
/// The hue.
/// </param>
public HSLAColor(Color color)
/// <param name="saturation">
/// The saturation.
/// </param>
/// <param name="luminosity">
/// The luminosity.
/// </param>
public HSLAColor(double hue, double saturation, double luminosity)
: this()
{
this.SetRGBA(color.R, color.G, color.B, color.A);
this.H = hue;
this.S = saturation;
this.L = luminosity;
}
/// <summary>
/// Initializes a new instance of the <see cref="HSLAColor"/> class.
/// Initializes a new instance of the <see cref="HSLAColor"/> struct.
/// </summary>
/// <param name="red">
/// The red.
/// </param>
/// <param name="green">
/// The green.
/// </param>
/// <param name="blue">
/// The blue.
/// <param name="color">
/// The <see cref="System.Drawing.Color"/> to initialize from.
/// </param>
public HSLAColor(int red, int green, int blue, int alpha)
public HSLAColor(Color color)
: this()
{
this.SetRGBA(red, green, blue, alpha);
HSLAColor hslColor = color;
this.h = hslColor.h;
this.s = hslColor.s;
this.l = hslColor.l;
this.a = hslColor.a;
}
/// <summary>
/// Initializes a new instance of the <see cref="HSLAColor"/> class.
/// Gets or sets the hue component.
/// </summary>
/// <param name="hue">
/// The hue.
/// </param>
/// <param name="saturation">
/// The saturation.
/// </param>
/// <param name="luminosity">
/// The luminosity.
/// </param>
public HSLAColor(double hue, double saturation, double luminosity)
: this()
public double H
{
this.Hue = hue;
this.Saturation = saturation;
this.Luminosity = luminosity;
}
#endregion
get
{
return this.h;
}
#region Public Properties
set
{
this.h = this.CheckRange(value);
}
}
/// <summary>
/// Gets or sets the hue.
/// Gets or sets the luminosity component.
/// </summary>
public double Hue
public double L
{
get
{
return this.hue;
return this.l;
}
set
{
this.hue = this.CheckRange(value);
this.l = this.CheckRange(value);
}
}
/// <summary>
/// Gets or sets the luminosity.
/// Gets or sets the saturation component.
/// </summary>
public double Luminosity
public double S
{
get
{
return this.luminosity;
return this.s;
}
set
{
this.luminosity = this.CheckRange(value);
this.s = this.CheckRange(value);
}
}
/// <summary>
/// Gets or sets the saturation.
/// Gets or sets the alpha component.
/// </summary>
public double Saturation
public double A
{
get
{
return this.saturation;
return this.a;
}
set
{
this.saturation = this.CheckRange(value);
this.a = this.CheckRange(value);
}
}
#endregion
/// <summary>
/// Allows the implicit conversion of an instance of <see cref="System.Drawing.Color"/> to a
/// <see cref="HSLAColor"/>.
/// </summary>
/// <param name="color">
/// The instance of <see cref="System.Drawing.Color"/> to convert.
/// </param>
/// <returns>
/// An instance of <see cref="HSLAColor"/>.
/// </returns>
public static implicit operator HSLAColor(Color color)
{
HSLAColor hslColor = new HSLAColor
{
h = color.GetHue() / 360.0,
l = color.GetBrightness(),
s = color.GetSaturation(),
a = color.A / 255f
};
#region Public Methods and Operators
return hslColor;
}
/// <summary>
/// The op_ implicit.
/// Allows the implicit conversion of an instance of <see cref="System.Drawing.Color"/> to a
/// <see cref="HSLAColor"/>.
/// </summary>
/// <param name="hslColor">
/// The hsl color.
/// <param name="rgbaColor">
/// The instance of <see cref="RGBAColor"/> to convert.
/// </param>
/// <returns>
/// An instance of <see cref="HSLAColor"/>.
/// </returns>
public static implicit operator Color(HSLAColor hslColor)
public static implicit operator HSLAColor(RGBAColor rgbaColor)
{
Color color = rgbaColor;
HSLAColor hslColor = new HSLAColor
{
h = color.GetHue() / 360.0,
l = color.GetBrightness(),
s = color.GetSaturation(),
a = color.A / 255f
};
return hslColor;
}
/// <summary>
/// Allows the implicit conversion of an instance of <see cref="HSLAColor"/> to a
/// <see cref="System.Drawing.Color"/>.
/// </summary>
/// <param name="hslaColor">
/// The instance of <see cref="HSLAColor"/> to convert.
/// </param>
/// <returns>
/// An instance of <see cref="System.Drawing.Color"/>.
/// </returns>
public static implicit operator Color(HSLAColor hslaColor)
{
double r = 0, g = 0, b = 0;
if (Math.Abs(hslColor.luminosity - 0) > .0001)
if (Math.Abs(hslaColor.l - 0) > .0001)
{
if (Math.Abs(hslColor.saturation - 0) <= .0001)
if (Math.Abs(hslaColor.s - 0) <= .0001)
{
r = g = b = hslColor.luminosity;
r = g = b = hslaColor.l;
}
else
{
double temp2 = GetTemp2(hslColor);
double temp1 = (2.0 * hslColor.luminosity) - temp2;
double temp2 = GetTemp2(hslaColor);
double temp1 = (2.0 * hslaColor.l) - 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));
r = GetColorComponent(temp1, temp2, hslaColor.h + (1.0 / 3.0));
g = GetColorComponent(temp1, temp2, hslaColor.h);
b = GetColorComponent(temp1, temp2, hslaColor.h - (1.0 / 3.0));
}
}
return Color.FromArgb((int)(255 * r), (int)(255 * g), (int)(255 * b));
return Color.FromArgb(Convert.ToInt32(255 * hslaColor.a), Convert.ToInt32(255 * r), Convert.ToInt32(255 * g), Convert.ToInt32(255 * b));
}
/// <summary>
/// The op_ implicit.
/// Allows the implicit conversion of an instance of <see cref="HSLAColor"/> to a
/// <see cref="RGBAColor"/>.
/// </summary>
/// <param name="color">
/// The color.
/// <param name="hslaColor">
/// The instance of <see cref="HSLAColor"/> to convert.
/// </param>
/// <returns>
/// An instance of <see cref="RGBAColor"/>.
/// </returns>
public static implicit operator HSLAColor(Color color)
public static implicit operator RGBAColor(HSLAColor hslaColor)
{
HSLAColor hslColor = new HSLAColor
double r = 0, g = 0, b = 0;
if (Math.Abs(hslaColor.l - 0) > .0001)
{
hue = color.GetHue() / 360.0,
luminosity = color.GetBrightness(),
saturation = color.GetSaturation()
};
if (Math.Abs(hslaColor.s - 0) <= .0001)
{
r = g = b = hslaColor.l;
}
else
{
double temp2 = GetTemp2(hslaColor);
double temp1 = (2.0 * hslaColor.l) - temp2;
return hslColor;
r = GetColorComponent(temp1, temp2, hslaColor.h + (1.0 / 3.0));
g = GetColorComponent(temp1, temp2, hslaColor.h);
b = GetColorComponent(temp1, temp2, hslaColor.h - (1.0 / 3.0));
}
}
return new RGBAColor(Convert.ToByte(255 * r), Convert.ToByte(255 * g), Convert.ToByte(255 * b), Convert.ToByte(255 * hslaColor.a));
}
/// <summary>
/// The set rgb components.
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <param name="red">
/// The red.
/// </param>
/// <param name="green">
/// The green component.
/// </param>
/// <param name="blue">
/// The blue component.
/// </param>
/// <param name="alpha">
/// The alpha component.
/// </param>
public void SetRGBA(int red, int green, int blue, int alpha)
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public string ToRGBAString()
{
HSLAColor hslColor = Color.FromArgb(alpha, red, green, blue);
this.hue = hslColor.hue;
this.saturation = hslColor.saturation;
this.luminosity = hslColor.luminosity;
this.a = hslColor.a;
Color color = this;
return string.Format("R={0}, G={1}, B={2}, A={3}", color.R, color.G, color.B, color.A);
}
/// <summary>
/// The to rgb string.
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public string ToRGBString()
public override string ToString()
{
Color color = this;
return string.Format("R: {0:#0.##} G: {1:#0.##} B: {2:#0.##}", color.R, color.G, color.B);
return string.Format("H={0:#0.##}, S={1:#0.##}, L={2:#0.##}, A={3:#0.##}", this.H, this.S, this.L, this.A);
}
/// <summary>
/// The to string.
/// Indicates whether this instance and a specified object are equal.
/// </summary>
/// <returns>
/// The <see cref="string"/>.
/// true if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, false.
/// </returns>
public override string ToString()
/// <param name="obj">Another object to compare to. </param>
public override bool Equals(object obj)
{
return string.Format("H: {0:#0.##} S: {1:#0.##} L: {2:#0.##}", this.Hue, this.Saturation, this.Luminosity);
}
if (obj is HSLAColor)
{
Color thisColor = this;
Color otherColor = (HSLAColor)obj;
return thisColor.Equals(otherColor);
}
#endregion
return false;
}
#region Methods
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
public override int GetHashCode()
{
Color thisColor = this;
return thisColor.GetHashCode();
}
/// <summary>
/// The get color component.
/// Gets the color component from the given hue values.
/// </summary>
/// <param name="temp1">
/// The temp 1.
@ -288,7 +347,7 @@ namespace ImageProcessor.Imaging.Colors
/// The get temp 2.
/// </summary>
/// <param name="hslColor">
/// The hsl color.
/// The <see cref="HSLAColor"/> color.
/// </param>
/// <returns>
/// The <see cref="double"/>.
@ -296,13 +355,13 @@ namespace ImageProcessor.Imaging.Colors
private static double GetTemp2(HSLAColor hslColor)
{
double temp2;
if (hslColor.luminosity <= 0.5)
if (hslColor.l <= 0.5)
{
temp2 = hslColor.luminosity * (1.0 + hslColor.saturation);
temp2 = hslColor.l * (1.0 + hslColor.s);
}
else
{
temp2 = hslColor.luminosity + hslColor.saturation - (hslColor.luminosity * hslColor.saturation);
temp2 = hslColor.l + hslColor.s - (hslColor.l * hslColor.s);
}
return temp2;
@ -332,13 +391,13 @@ namespace ImageProcessor.Imaging.Colors
}
/// <summary>
/// The check range.
/// Checks the range of the given value to ensure that it remains within the acceptable boundaries.
/// </summary>
/// <param name="value">
/// The value.
/// The value to check.
/// </param>
/// <returns>
/// The <see cref="double"/>.
/// The sanitized <see cref="double"/>.
/// </returns>
private double CheckRange(double value)
{
@ -353,7 +412,5 @@ namespace ImageProcessor.Imaging.Colors
return value;
}
#endregion
}
}

91
src/ImageProcessor/Imaging/Colors/RGBAColor.cs

@ -8,6 +8,7 @@
namespace ImageProcessor.Imaging.Colors
{
using System.Drawing;
using System.Text;
/// <summary>
/// Represents an RGBA (red, green, blue, alpha) color.
@ -91,6 +92,36 @@ namespace ImageProcessor.Imaging.Colors
this.A = color.A;
}
/// <summary>
/// Allows the implicit conversion of an instance of <see cref="System.Drawing.Color"/> to a
/// <see cref="RGBAColor"/>.
/// </summary>
/// <param name="color">
/// The instance of <see cref="System.Drawing.Color"/> to convert.
/// </param>
/// <returns>
/// An instance of <see cref="RGBAColor"/>.
/// </returns>
public static implicit operator RGBAColor(Color color)
{
return new RGBAColor(color);
}
/// <summary>
/// Allows the implicit conversion of an instance of <see cref="System.Drawing.Color"/> to a
/// <see cref="RGBAColor"/>.
/// </summary>
/// <param name="color">
/// The instance of <see cref="System.Drawing.Color"/> to convert.
/// </param>
/// <returns>
/// An instance of <see cref="RGBAColor"/>.
/// </returns>
public static implicit operator RGBAColor(HSLAColor color)
{
return new RGBAColor(color);
}
/// <summary>
/// Allows the implicit conversion of an instance of <see cref="RGBAColor"/> to a
/// <see cref="System.Drawing.Color"/>.
@ -103,7 +134,65 @@ namespace ImageProcessor.Imaging.Colors
/// </returns>
public static implicit operator Color(RGBAColor rgba)
{
return System.Drawing.Color.FromArgb(rgba.A, rgba.R, rgba.G, rgba.B);
return Color.FromArgb(rgba.A, rgba.R, rgba.G, rgba.B);
}
/// <summary>
/// Allows the implicit conversion of an instance of <see cref="RGBAColor"/> to a
/// <see cref="HSLAColor"/>.
/// </summary>
/// <param name="rgba">
/// The instance of <see cref="RGBAColor"/> to convert.
/// </param>
/// <returns>
/// An instance of <see cref="HSLAColor"/>.
/// </returns>
public static implicit operator HSLAColor(RGBAColor rgba)
{
return new HSLAColor(rgba);
}
/// <summary>
/// Returns a <see cref="System.String" /> that represents this instance.
/// </summary>
/// <returns>
/// A <see cref="System.String" /> that represents this instance.
/// </returns>
public override string ToString()
{
return string.Format("R={0}, G={1}, B={2}, A={3}", this.R, this.G, this.B, this.A);
}
/// <summary>
/// Indicates whether this instance and a specified object are equal.
/// </summary>
/// <returns>
/// true if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, false.
/// </returns>
/// <param name="obj">Another object to compare to. </param>
public override bool Equals(object obj)
{
if (obj is RGBAColor)
{
Color thisColor = this;
Color otherColor = (RGBAColor)obj;
return thisColor.Equals(otherColor);
}
return false;
}
/// <summary>
/// Returns the hash code for this instance.
/// </summary>
/// <returns>
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
public override int GetHashCode()
{
Color thisColor = this;
return thisColor.GetHashCode();
}
}
}

8
src/ImageProcessor/Processors/Hue.cs

@ -18,7 +18,7 @@ namespace ImageProcessor.Processors
using ImageProcessor.Imaging.Colors;
/// <summary>
/// Encapsulates methods to rotate the hue component of an image.
/// Encapsulates methods to adjust the hue component of an image.
/// </summary>
public class Hue : IGraphicsProcessor
{
@ -69,10 +69,8 @@ namespace ImageProcessor.Processors
{
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);
HSLAColor hsla = new HSLAColor(fastBitmap.GetPixel(i, j)) { H = degrees / 360f };
fastBitmap.SetPixel(i, j, hsla);
}
}
}

95
src/ImageProcessor/Processors/HueRotate.cs

@ -0,0 +1,95 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="HueRotate.cs" company="James South">
// Copyright (c) James South.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Encapsulates methods to rotate the hue component of an image.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor.Processors
{
using System;
using System.Collections.Generic;
using System.Drawing;
using ImageProcessor.Common.Exceptions;
using ImageProcessor.Imaging;
using ImageProcessor.Imaging.Colors;
/// <summary>
/// Encapsulates methods to rotate the hue component of an image.
/// </summary>
public class HueRotate : IGraphicsProcessor
{
/// <summary>
/// Initializes a new instance of the <see cref="HueRotate"/> class.
/// </summary>
public HueRotate()
{
this.Settings = new Dictionary<string, string>();
}
/// <summary>
/// Gets or sets the dynamic parameter.
/// </summary>
public dynamic DynamicParameter { get; set; }
/// <summary>
/// Gets or sets any additional settings required by the processor.
/// </summary>
public Dictionary<string, string> Settings { get; set; }
/// <summary>
/// Processes the image.
/// </summary>
/// <param name="factory">
/// The current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class containing
/// the image to process.
/// </param>
/// <returns>
/// The processed image from the current instance of the <see cref="T:ImageProcessor.ImageFactory"/> class.
/// </returns>
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 hsla = new HSLAColor(fastBitmap.GetPixel(i, j));
hsla.H = (hsla.H + (degrees / 360f)) % 1;
fastBitmap.SetPixel(i, j, hsla);
}
}
}
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;
}
}
}

3
src/ImageProcessorConsole/Program.cs

@ -82,7 +82,8 @@ namespace ImageProcessorConsole
//.Resize(new Size((int)(size.Width * 1.1), 0))
//.ContentAwareResize(layer)
.Constrain(size)
.Hue(180)
.HueRotate(270)
.Quality(100)
.Save(Path.GetFullPath(Path.Combine(Path.GetDirectoryName(path), @"..\..\images\output", fileInfo.Name)));
stopwatch.Stop();

BIN
src/ImageProcessorConsole/images/output/1aaa.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

BIN
src/ImageProcessorConsole/images/output/2006-citybus.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

1
src/ImageProcessorConsole/images/output/2008.jpg.REMOVED.git-id

@ -1 +0,0 @@
73753ca19a0818ee4a88b6e9e0eb85ca17624269

BIN
src/ImageProcessorConsole/images/output/2012-citybus.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

1
src/ImageProcessorConsole/images/output/Arc-de-Triomphe-France.jpg.REMOVED.git-id

@ -1 +0,0 @@
dff097307936637d1c43f82ca28f4582c9810de7

BIN
src/ImageProcessorConsole/images/output/IC580196.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 39 KiB

BIN
src/ImageProcessorConsole/images/output/Turtle.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 48 KiB

BIN
src/ImageProcessorConsole/images/output/arc_de_triomphe_paris_france.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

BIN
src/ImageProcessorConsole/images/output/mountain.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

BIN
src/ImageProcessorConsole/images/output/rotate.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

BIN
src/ImageProcessorConsole/images/output/sample1.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

BIN
src/ImageProcessorConsole/images/output/shutterstock_19173982_Arc_de_triomphe-square1.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 41 KiB

BIN
src/ImageProcessorConsole/images/output/test.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 53 KiB

BIN
src/ImageProcessorConsole/images/output/tower.jpg

Binary file not shown.

Before

Width:  |  Height:  |  Size: 46 KiB

Loading…
Cancel
Save