@ -0,0 +1,359 @@ |
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="HSLAColor.cs" company="James South">
|
|||
// Copyright (c) James South.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
|
|||
namespace ImageProcessor.Imaging.Colors |
|||
{ |
|||
using System; |
|||
using System.Drawing; |
|||
|
|||
/// <summary>
|
|||
/// Represents an HSLA (hue, saturation, luminosity, alpha) color.
|
|||
/// </summary>
|
|||
public struct HSLAColor |
|||
{ |
|||
// Private data members below are on scale 0-1
|
|||
// They are scaled for use externally based on scale
|
|||
|
|||
/// <summary>
|
|||
/// The hue component.
|
|||
/// </summary>
|
|||
private double hue; |
|||
|
|||
/// <summary>
|
|||
/// The luminosity component.
|
|||
/// </summary>
|
|||
private double luminosity; |
|||
|
|||
/// <summary>
|
|||
/// The saturation component.
|
|||
/// </summary>
|
|||
private double saturation; |
|||
|
|||
/// <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>
|
|||
public HSLAColor(Color color) |
|||
: this() |
|||
{ |
|||
this.SetRGBA(color.R, color.G, color.B, color.A); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="HSLAColor"/> class.
|
|||
/// </summary>
|
|||
/// <param name="red">
|
|||
/// The red.
|
|||
/// </param>
|
|||
/// <param name="green">
|
|||
/// The green.
|
|||
/// </param>
|
|||
/// <param name="blue">
|
|||
/// The blue.
|
|||
/// </param>
|
|||
public HSLAColor(int red, int green, int blue, int alpha) |
|||
: this() |
|||
{ |
|||
this.SetRGBA(red, green, blue, alpha); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="HSLAColor"/> class.
|
|||
/// </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() |
|||
{ |
|||
this.Hue = hue; |
|||
this.Saturation = saturation; |
|||
this.Luminosity = luminosity; |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Public Properties
|
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the hue.
|
|||
/// </summary>
|
|||
public double Hue |
|||
{ |
|||
get |
|||
{ |
|||
return this.hue; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
this.hue = this.CheckRange(value); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the luminosity.
|
|||
/// </summary>
|
|||
public double Luminosity |
|||
{ |
|||
get |
|||
{ |
|||
return this.luminosity; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
this.luminosity = this.CheckRange(value); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the saturation.
|
|||
/// </summary>
|
|||
public double Saturation |
|||
{ |
|||
get |
|||
{ |
|||
return this.saturation; |
|||
} |
|||
|
|||
set |
|||
{ |
|||
this.saturation = this.CheckRange(value); |
|||
} |
|||
} |
|||
|
|||
#endregion
|
|||
|
|||
#region Public Methods and Operators
|
|||
|
|||
/// <summary>
|
|||
/// The op_ implicit.
|
|||
/// </summary>
|
|||
/// <param name="hslColor">
|
|||
/// The hsl color.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// </returns>
|
|||
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)); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The op_ implicit.
|
|||
/// </summary>
|
|||
/// <param name="color">
|
|||
/// The color.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// </returns>
|
|||
public static implicit operator HSLAColor(Color color) |
|||
{ |
|||
HSLAColor hslColor = new HSLAColor |
|||
{ |
|||
hue = color.GetHue() / 360.0, |
|||
luminosity = color.GetBrightness(), |
|||
saturation = color.GetSaturation() |
|||
}; |
|||
|
|||
return hslColor; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The set rgb components.
|
|||
/// </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) |
|||
{ |
|||
HSLAColor hslColor = Color.FromArgb(alpha, red, green, blue); |
|||
this.hue = hslColor.hue; |
|||
this.saturation = hslColor.saturation; |
|||
this.luminosity = hslColor.luminosity; |
|||
this.a = hslColor.a; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The to rgb string.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// The <see cref="string"/>.
|
|||
/// </returns>
|
|||
public string ToRGBString() |
|||
{ |
|||
Color color = this; |
|||
return string.Format("R: {0:#0.##} G: {1:#0.##} B: {2:#0.##}", color.R, color.G, color.B); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The to string.
|
|||
/// </summary>
|
|||
/// <returns>
|
|||
/// The <see cref="string"/>.
|
|||
/// </returns>
|
|||
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
|
|||
|
|||
/// <summary>
|
|||
/// The get color component.
|
|||
/// </summary>
|
|||
/// <param name="temp1">
|
|||
/// The temp 1.
|
|||
/// </param>
|
|||
/// <param name="temp2">
|
|||
/// The temp 2.
|
|||
/// </param>
|
|||
/// <param name="temp3">
|
|||
/// The temp 3.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// The <see cref="double"/>.
|
|||
/// </returns>
|
|||
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; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The get temp 2.
|
|||
/// </summary>
|
|||
/// <param name="hslColor">
|
|||
/// The hsl color.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// The <see cref="double"/>.
|
|||
/// </returns>
|
|||
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; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The move into range.
|
|||
/// </summary>
|
|||
/// <param name="temp3">
|
|||
/// The temp 3.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// The <see cref="double"/>.
|
|||
/// </returns>
|
|||
private static double MoveIntoRange(double temp3) |
|||
{ |
|||
if (temp3 < 0.0) |
|||
{ |
|||
temp3 += 1.0; |
|||
} |
|||
else if (temp3 > 1.0) |
|||
{ |
|||
temp3 -= 1.0; |
|||
} |
|||
|
|||
return temp3; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// The check range.
|
|||
/// </summary>
|
|||
/// <param name="value">
|
|||
/// The value.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// The <see cref="double"/>.
|
|||
/// </returns>
|
|||
private double CheckRange(double value) |
|||
{ |
|||
if (value < 0.0) |
|||
{ |
|||
value = 0.0; |
|||
} |
|||
else if (value > 1.0) |
|||
{ |
|||
value = 1.0; |
|||
} |
|||
|
|||
return value; |
|||
} |
|||
|
|||
#endregion
|
|||
} |
|||
} |
|||
@ -0,0 +1,109 @@ |
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="RGBAColor.cs" company="James South">
|
|||
// Copyright (c) James South.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
|
|||
namespace ImageProcessor.Imaging.Colors |
|||
{ |
|||
using System.Drawing; |
|||
|
|||
/// <summary>
|
|||
/// Represents an RGBA (red, green, blue, alpha) color.
|
|||
/// </summary>
|
|||
public struct RGBAColor |
|||
{ |
|||
/// <summary>
|
|||
/// The alpha component.
|
|||
/// </summary>
|
|||
public byte A; |
|||
|
|||
/// <summary>
|
|||
/// The blue component.
|
|||
/// </summary>
|
|||
public byte B; |
|||
|
|||
/// <summary>
|
|||
/// The green component.
|
|||
/// </summary>
|
|||
public byte G; |
|||
|
|||
/// <summary>
|
|||
/// The red component.
|
|||
/// </summary>
|
|||
public byte R; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RGBAColor"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="red">
|
|||
/// The red component.
|
|||
/// </param>
|
|||
/// <param name="green">
|
|||
/// The green component.
|
|||
/// </param>
|
|||
/// <param name="blue">
|
|||
/// The blue component.
|
|||
/// </param>
|
|||
public RGBAColor(byte red, byte green, byte blue) |
|||
{ |
|||
this.R = red; |
|||
this.G = green; |
|||
this.B = blue; |
|||
this.A = 255; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RGBAColor"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="red">
|
|||
/// The red component.
|
|||
/// </param>
|
|||
/// <param name="green">
|
|||
/// The green component.
|
|||
/// </param>
|
|||
/// <param name="blue">
|
|||
/// The blue component.
|
|||
/// </param>
|
|||
/// <param name="alpha">
|
|||
/// The alpha component.
|
|||
/// </param>
|
|||
public RGBAColor(byte red, byte green, byte blue, byte alpha) |
|||
{ |
|||
this.R = red; |
|||
this.G = green; |
|||
this.B = blue; |
|||
this.A = alpha; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="RGBAColor"/> struct.
|
|||
/// </summary>
|
|||
/// <param name="color">
|
|||
/// The <see cref="System.Drawing.Color">color.</see>
|
|||
/// </param>
|
|||
public RGBAColor(Color color) |
|||
{ |
|||
this.R = color.R; |
|||
this.G = color.G; |
|||
this.B = color.B; |
|||
this.A = color.A; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Allows the implicit conversion of an instance of <see cref="RGBAColor"/> to a
|
|||
/// <see cref="System.Drawing.Color"/>.
|
|||
/// </summary>
|
|||
/// <param name="rgba">
|
|||
/// The instance of <see cref="RGBAColor"/> to convert.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// An instance of <see cref="System.Drawing.Color"/>.
|
|||
/// </returns>
|
|||
public static implicit operator Color(RGBAColor rgba) |
|||
{ |
|||
return System.Drawing.Color.FromArgb(rgba.A, rgba.R, rgba.G, rgba.B); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,256 @@ |
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="FastBitmap.cs" company="James South">
|
|||
// Copyright (c) James South.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
// <summary>
|
|||
// Allows fast access to <see cref="System.Drawing.Bitmap" />'s pixel data.
|
|||
// </summary>
|
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
|
|||
namespace ImageProcessor.Imaging |
|||
{ |
|||
using System; |
|||
using System.Drawing; |
|||
using System.Drawing.Imaging; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
/// <summary>
|
|||
/// Allows fast access to <see cref="System.Drawing.Bitmap"/>'s pixel data.
|
|||
/// </summary>
|
|||
public class FastBitmap : IDisposable |
|||
{ |
|||
/// <summary>
|
|||
/// The bitmap.
|
|||
/// </summary>
|
|||
private readonly Bitmap bitmap; |
|||
|
|||
/// <summary>
|
|||
/// The width of the bitmap.
|
|||
/// </summary>
|
|||
private readonly int width; |
|||
|
|||
/// <summary>
|
|||
/// The height of the bitmap.
|
|||
/// </summary>
|
|||
private readonly int height; |
|||
|
|||
/// <summary>
|
|||
/// The stride width of the bitmap.
|
|||
/// </summary>
|
|||
private int stride; |
|||
|
|||
/// <summary>
|
|||
/// The bitmap data.
|
|||
/// </summary>
|
|||
private BitmapData bitmapData; |
|||
|
|||
/// <summary>
|
|||
/// The pixel buffer for holding pixel data.
|
|||
/// </summary>
|
|||
private byte[] pixelBuffer; |
|||
|
|||
/// <summary>
|
|||
/// The buffer length.
|
|||
/// </summary>
|
|||
private int bufferLength; |
|||
|
|||
/// <summary>
|
|||
/// A value indicating whether this instance of the given entity has been disposed.
|
|||
/// </summary>
|
|||
/// <value><see langword="true"/> if this instance has been disposed; otherwise, <see langword="false"/>.</value>
|
|||
/// <remarks>
|
|||
/// 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.
|
|||
/// </remarks>
|
|||
private bool isDisposed; |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="FastBitmap"/> class.
|
|||
/// </summary>
|
|||
/// <param name="bitmap">The input bitmap.</param>
|
|||
public FastBitmap(Bitmap bitmap) |
|||
{ |
|||
this.bitmap = bitmap; |
|||
this.width = this.bitmap.Width; |
|||
this.height = this.bitmap.Height; |
|||
this.LockBitmap(); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the width, in pixels of the <see cref="System.Drawing.Bitmap"/>.
|
|||
/// </summary>
|
|||
public int Width |
|||
{ |
|||
get |
|||
{ |
|||
return this.width; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the height, in pixels of the <see cref="System.Drawing.Bitmap"/>.
|
|||
/// </summary>
|
|||
public int Height |
|||
{ |
|||
get |
|||
{ |
|||
return this.height; |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Allows the implicit conversion of an instance of <see cref="FastBitmap"/> to a
|
|||
/// <see cref="System.Drawing.Image"/>.
|
|||
/// </summary>
|
|||
/// <param name="fastBitmap">
|
|||
/// The instance of <see cref="FastBitmap"/> to convert.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// An instance of <see cref="System.Drawing.Image"/>.
|
|||
/// </returns>
|
|||
public static implicit operator Image(FastBitmap fastBitmap) |
|||
{ |
|||
return fastBitmap.bitmap; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Allows the implicit conversion of an instance of <see cref="FastBitmap"/> to a
|
|||
/// <see cref="System.Drawing.Bitmap"/>.
|
|||
/// </summary>
|
|||
/// <param name="fastBitmap">
|
|||
/// The instance of <see cref="FastBitmap"/> to convert.
|
|||
/// </param>
|
|||
/// <returns>
|
|||
/// An instance of <see cref="System.Drawing.Bitmap"/>.
|
|||
/// </returns>
|
|||
public static implicit operator Bitmap(FastBitmap fastBitmap) |
|||
{ |
|||
return fastBitmap.bitmap; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the color at the specified pixel of the <see cref="System.Drawing.Bitmap"/>.
|
|||
/// </summary>
|
|||
/// <param name="x">The x-coordinate of the pixel to retrieve.</param>
|
|||
/// <param name="y">The y-coordinate of the pixel to retrieve.</param>
|
|||
/// <returns>The <see cref="System.Drawing.Color"/> at the given pixel.</returns>
|
|||
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); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Sets the color of the specified pixel of the <see cref="System.Drawing.Bitmap"/>.
|
|||
/// </summary>
|
|||
/// <param name="x">The x-coordinate of the pixel to set.</param>
|
|||
/// <param name="y">The y-coordinate of the pixel to set.</param>
|
|||
/// <param name="color">
|
|||
/// A <see cref="System.Drawing.Color"/> color structure that represents the
|
|||
/// color to set the specified pixel.
|
|||
/// </param>
|
|||
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; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Disposes the object and frees resources for the Garbage Collector.
|
|||
/// </summary>
|
|||
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); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Disposes the object and frees resources for the Garbage Collector.
|
|||
/// </summary>
|
|||
/// <param name="disposing">If true, the object gets disposed.</param>
|
|||
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; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Locks the bitmap into system memory.
|
|||
/// </summary>
|
|||
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); |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Unlocks the bitmap from system memory.
|
|||
/// </summary>
|
|||
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; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,96 @@ |
|||
// --------------------------------------------------------------------------------------------------------------------
|
|||
// <copyright file="Hue.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 Hue : IGraphicsProcessor |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="Hue"/> class.
|
|||
/// </summary>
|
|||
public Hue() |
|||
{ |
|||
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 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; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1 @@ |
|||
9ab3fa52dd238ee4caffb47c82929f4079dc38d3 |
|||
|
After Width: | Height: | Size: 54 KiB |
|
After Width: | Height: | Size: 33 KiB |
@ -1 +0,0 @@ |
|||
e41022eb5fe724ba5fe2b7aeda29a1f4b6878484 |
|||
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 41 KiB |
@ -1 +0,0 @@ |
|||
c6cb11afaf9fdb9181772246e5c873d8f7d1b99c |
|||
@ -1 +1 @@ |
|||
10b48cac44776a023df7585ba2c68c3f51b0f803 |
|||
73753ca19a0818ee4a88b6e9e0eb85ca17624269 |
|||
|
After Width: | Height: | Size: 39 KiB |
@ -1 +0,0 @@ |
|||
e631eb3491496bb83f99cd41a752f79c9d7f6830 |
|||
|
Before Width: | Height: | Size: 12 KiB |
@ -1 +1 @@ |
|||
782056919992bb7e453eeee5d9c0034e03b57506 |
|||
dff097307936637d1c43f82ca28f4582c9810de7 |
|||
|
After Width: | Height: | Size: 39 KiB |
@ -1 +0,0 @@ |
|||
1d9ded0201edcd248140b4ec02f69ccdb4b539e5 |
|||
@ -1 +0,0 @@ |
|||
f5681324d193a42492647f4952057c2b72026096 |
|||
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 35 KiB |
@ -1 +0,0 @@ |
|||
2880457cc09cd2897b5f9f377807ec22f8f83013 |
|||
|
Before Width: | Height: | Size: 4.9 KiB |
@ -1 +0,0 @@ |
|||
d8d3354b684cad79d9a46f92ed3a58747a808ad1 |
|||
|
After Width: | Height: | Size: 46 KiB |
@ -1 +0,0 @@ |
|||
34dcced6c7c3e4dd6fae239eba8eddef6234028d |
|||
@ -1 +0,0 @@ |
|||
b65d9e937cad7ddd02ff0d01a3be2f09c55e63e8 |
|||
|
Before Width: | Height: | Size: 55 KiB |
|
After Width: | Height: | Size: 49 KiB |
@ -1 +0,0 @@ |
|||
de6754762f7705f9109ea364f42ca128e454e853 |
|||
|
After Width: | Height: | Size: 38 KiB |
|
After Width: | Height: | Size: 41 KiB |
@ -1 +0,0 @@ |
|||
24db72130626e81b9a4262c891dd28e6d97e5a96 |
|||
|
After Width: | Height: | Size: 53 KiB |
@ -1 +0,0 @@ |
|||
4885438f0b97e3aae59d6e214b5ec455358ae225 |
|||
|
Before Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 46 KiB |
@ -1 +0,0 @@ |
|||
2d5b165c27545a3860d8a6b35f8ac4438f57593a |
|||