Browse Source

Adding ImageBase and Color

Former-commit-id: ecd7a17ff1efdb1c6a6bce330edd4c9293286564
Former-commit-id: 8cc939c432b922dca286e86a3b8a04c5e859b99b
Former-commit-id: ed384b2a55ec37818085d29fa75d4064ae2a445d
pull/17/head
James South 11 years ago
parent
commit
f05bb5ac12
  1. 221
      src/ImageProcessor/Colors/Color.cs
  2. 51
      src/ImageProcessor/Common/Exceptions/ImageFormatException.cs
  3. 78
      src/ImageProcessor/IImageBase.cs
  4. 208
      src/ImageProcessor/ImageBase.cs
  5. 5
      src/ImageProcessor/ImageProcessor.csproj
  6. 1
      src/ImageProcessor/ImageProcessor.csproj.DotSettings

221
src/ImageProcessor/Colors/Color.cs

@ -0,0 +1,221 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="Color.cs" company="James South">
// Copyright © James South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Represents an BGRA (blue, green, red, alpha) color.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor
{
using System;
using System.ComponentModel;
using System.Globalization;
using System.Runtime.InteropServices;
/// <summary>
/// Represents an BGRA (blue, green, red, alpha) color.
/// </summary>
[StructLayout(LayoutKind.Explicit)]
public struct Color : IEquatable<Color>
{
/// <summary>
/// Represents a <see cref="Color"/> that has B, G, R, and A values set to zero.
/// </summary>
public static readonly Color Empty;
/// <summary>
/// Represents a transparent <see cref="Color"/> that has B, G, R, and A values set to 255, 255, 255, 0.
/// </summary>
public static readonly Color Transparent = new Color(255, 255, 255, 0);
/// <summary>
/// Represents a black <see cref="Color"/> that has B, G, R, and A values set to 0, 0, 0, 0.
/// </summary>
public static readonly Color Black = new Color(0, 0, 0, 255);
/// <summary>
/// Represents a white <see cref="Color"/> that has B, G, R, and A values set to 255, 255, 255, 255.
/// </summary>
public static readonly Color White = new Color(255, 255, 255, 255);
/// <summary>
/// Holds the blue component of the color
/// </summary>
[FieldOffset(0)]
public byte B;
/// <summary>
/// Holds the green component of the color
/// </summary>
[FieldOffset(1)]
public byte G;
/// <summary>
/// Holds the red component of the color
/// </summary>
[FieldOffset(2)]
public byte R;
/// <summary>
/// Holds the alpha component of the color
/// </summary>
[FieldOffset(3)]
public byte A;
/// <summary>
/// Permits the <see cref="Color"/> to be treated as a 32 bit integer.
/// </summary>
[FieldOffset(0)]
public int Bgra;
/// <summary>
/// Initializes a new instance of the <see cref="Color"/> struct.
/// </summary>
/// <param name="b">
/// The blue component of this <see cref="Color"/>.
/// </param>
/// <param name="g">
/// The green component of this <see cref="Color"/>.
/// </param>
/// <param name="r">
/// The red component of this <see cref="Color"/>.
/// </param>
public Color(byte b, byte g, byte r)
: this()
{
this.B = b;
this.G = g;
this.R = r;
this.A = 255;
}
/// <summary>
/// Initializes a new instance of the <see cref="Color"/> struct.
/// </summary>
/// <param name="b">
/// The blue component of this <see cref="Color"/>.
/// </param>
/// <param name="g">
/// The green component of this <see cref="Color"/>.
/// </param>
/// <param name="r">
/// The red component of this <see cref="Color"/>.
/// </param>
/// <param name="a">
/// The alpha component of this <see cref="Color"/>.
/// </param>
public Color(byte b, byte g, byte r, byte a)
: this()
{
this.B = b;
this.G = g;
this.R = r;
this.A = a;
}
/// <summary>
/// Initializes a new instance of the <see cref="Color"/> struct.
/// </summary>
/// <param name="bgra">
/// The combined color components.
/// </param>
public Color(int bgra)
: this()
{
this.Bgra = bgra;
}
/// <summary>
/// Gets a value indicating whether this <see cref="Color"/> is empty.
/// </summary>
[EditorBrowsable(EditorBrowsableState.Never)]
public bool IsEmpty
{
get
{
return this.B == 0 && this.G == 0 && this.R == 0 && this.A == 0;
}
}
/// <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 Color)
{
Color color = (Color)obj;
return this.Bgra == color.Bgra;
}
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()
{
return this.GetHashCode(this);
}
/// <summary>
/// Returns the fully qualified type name of this instance.
/// </summary>
/// <returns>
/// A <see cref="T:System.String"/> containing a fully qualified type name.
/// </returns>
public override string ToString()
{
return "{B=" + this.B.ToString(CultureInfo.CurrentCulture)
+ ",G=" + this.G.ToString(CultureInfo.CurrentCulture)
+ ",R=" + this.R.ToString(CultureInfo.CurrentCulture)
+ ",A=" + this.A.ToString(CultureInfo.CurrentCulture) + "}";
}
/// <summary>
/// Indicates whether the current object is equal to another object of the same type.
/// </summary>
/// <returns>
/// True if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
/// </returns>
/// <param name="other">An object to compare with this object.</param>
public bool Equals(Color other)
{
return this.B.Equals(other.B) && this.G.Equals(other.G)
&& this.R.Equals(other.R) && this.A.Equals(other.A);
}
/// <summary>
/// Returns the hash code for the given instance.
/// </summary>
/// <param name="obj">
/// The instance of <see cref="Color"/> to return the hash code for.
/// </param>
/// <returns>
/// A 32-bit signed integer that is the hash code for this instance.
/// </returns>
private int GetHashCode(Color obj)
{
unchecked
{
int hashCode = obj.B.GetHashCode();
hashCode = (hashCode * 397) ^ obj.G.GetHashCode();
hashCode = (hashCode * 397) ^ obj.R.GetHashCode();
hashCode = (hashCode * 397) ^ obj.A.GetHashCode();
return hashCode;
}
}
}
}

51
src/ImageProcessor/Common/Exceptions/ImageFormatException.cs

@ -0,0 +1,51 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ImageFormatException.cs" company="James South">
// Copyright © James South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The exception that is thrown when the library tries to load
// an image, which has an invalid format.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor
{
using System;
/// <summary>
/// The exception that is thrown when the library tries to load
/// an image, which has an invalid format.
/// </summary>
public class ImageFormatException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="ImageFormatException"/> class.
/// </summary>
public ImageFormatException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageFormatException"/> class with the name of the
/// parameter that causes this exception.
/// </summary>
/// <param name="errorMessage">The error message that explains the reason for this exception.</param>
public ImageFormatException(string errorMessage)
: base(errorMessage)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageFormatException"/> class with a specified
/// error message and the exception that is the cause of this exception.
/// </summary>
/// <param name="errorMessage">The error message that explains the reason for this exception.</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic)
/// if no inner exception is specified.</param>
public ImageFormatException(string errorMessage, Exception innerException)
: base(errorMessage, innerException)
{
}
}
}

78
src/ImageProcessor/IImageBase.cs

@ -0,0 +1,78 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="IImageBase.cs" company="James South">
// Copyright © James South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// Encapsulates all the basic properties and methods required to manipulate images.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor
{
/// <summary>
/// Encapsulates all the basic properties and methods required to manipulate images.
/// </summary>
public interface IImageBase
{
/// <summary>
/// Gets the image pixels as byte array.
/// </summary>
/// <remarks>
/// The returned array has a length of Width * Height * 4 bytes
/// and stores the blue, the green, the red and the alpha value for
/// each pixel in this order.
/// </remarks>
byte[] Pixels { get; }
/// <summary>
/// Gets the width in pixels.
/// </summary>
int Width { get; }
/// <summary>
/// Gets the height in pixels.
/// </summary>
int Height { get; }
/// <summary>
/// Gets the pixel ratio made up of the width and height.
/// </summary>
double PixelRatio { get; }
/// <summary>
/// Gets the <see cref="Rectangle"/> representing the bounds of the image.
/// </summary>
Rectangle Bounds { get; }
/// <summary>
/// Gets or sets the color of a pixel at the specified position.
/// </summary>
/// <param name="x">
/// The x-coordinate of the pixel. Must be greater
/// than zero and smaller than the width of the pixel.
/// </param>
/// <param name="y">
/// The y-coordinate of the pixel. Must be greater
/// than zero and smaller than the width of the pixel.
/// </param>
/// <returns>The <see cref="Color"/> at the specified position.</returns>
Color this[int x, int y]
{
get;
set;
}
/// <summary>
/// Sets the pixel array of the image.
/// </summary>
/// <param name="width">
/// The new width of the image. Must be greater than zero.</param>
/// <param name="height">The new height of the image. Must be greater than zero.</param>
/// <param name="pixels">
/// The array with colors. Must be a multiple
/// of four, width and height.
/// </param>
void SetPixels(int width, int height, byte[] pixels);
}
}

208
src/ImageProcessor/ImageBase.cs

@ -0,0 +1,208 @@
// --------------------------------------------------------------------------------------------------------------------
// <copyright file="ImageBase.cs" company="James South">
// Copyright © James South and contributors.
// Licensed under the Apache License, Version 2.0.
// </copyright>
// <summary>
// The base class of all image. Encapsulates all the properties and methods
// required to manipulate images.
// </summary>
// --------------------------------------------------------------------------------------------------------------------
namespace ImageProcessor
{
using System;
/// <summary>
/// The base class of all image. Encapsulates all the properties and methods
/// required to manipulate images.
/// </summary>
public abstract class ImageBase : IImageBase
{
/// <summary>
/// Initializes a new instance of the <see cref="ImageBase"/> class.
/// </summary>
/// <param name="width">
/// The width of the image in pixels.
/// </param>
/// <param name="height">
/// The height of the image in pixels.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown if either <paramref name="width"/> or <paramref name="height"/> are less than or equal to 0.
/// </exception>
protected ImageBase(int width, int height)
{
if (width <= 0)
{
throw new ArgumentOutOfRangeException("width", "Width must be greater than or equals than zero.");
}
if (height <= 0)
{
throw new ArgumentOutOfRangeException("height", "Height must be greater than or equal than zero.");
}
this.Width = width;
this.Height = height;
this.Pixels = new byte[width * height * 4];
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageBase"/> class.
/// </summary>
/// <param name="other">
/// The other <see cref="ImageBase"/> to create this instance from.
/// </param>
/// <exception cref="ArgumentNullException">
/// Thrown if the given <see cref="ImageBase"/> is null.
/// </exception>
protected ImageBase(ImageBase other)
{
if (other == null)
{
throw new ArgumentNullException("other", "Other image cannot be null.");
}
byte[] pixels = other.Pixels;
this.Width = other.Width;
this.Height = other.Height;
this.Pixels = new byte[pixels.Length];
Array.Copy(pixels, this.Pixels, pixels.Length);
}
/// <summary>
/// Gets the image pixels as byte array.
/// </summary>
/// <remarks>
/// The returned array has a length of Width * Height * 4 bytes
/// and stores the blue, the green, the red and the alpha value for
/// each pixel in this order.
/// </remarks>
public byte[] Pixels { get; private set; }
/// <summary>
/// Gets the width in pixels.
/// </summary>
public int Width { get; private set; }
/// <summary>
/// Gets the height in pixels.
/// </summary>
public int Height { get; private set; }
/// <summary>
/// Gets the pixel ratio made up of the width and height.
/// </summary>
public double PixelRatio
{
get { return (double)this.Width / this.Height; }
}
/// <summary>
/// Gets the <see cref="Rectangle"/> representing the bounds of the image.
/// </summary>
public Rectangle Bounds
{
get
{
return new Rectangle(0, 0, this.Width, this.Height);
}
}
/// <summary>
/// Gets or sets the color of a pixel at the specified position.
/// </summary>
/// <param name="x">
/// The x-coordinate of the pixel. Must be greater
/// than zero and smaller than the width of the pixel.
/// </param>
/// <param name="y">
/// The y-coordinate of the pixel. Must be greater
/// than zero and smaller than the width of the pixel.
/// </param>
/// <returns>The <see cref="Color"/> at the specified position.</returns>
public Color this[int x, int y]
{
get
{
#if DEBUG
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.Width))
{
throw new ArgumentOutOfRangeException("y", "Value cannot be less than zero or greater than the bitmap height.");
}
#endif
int start = ((y * this.Width) + x) * 4;
return new Color(this.Pixels[start], this.Pixels[start + 1], this.Pixels[start + 2], this.Pixels[start + 3]);
}
set
{
#if DEBUG
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.Width))
{
throw new ArgumentOutOfRangeException("y", "Value cannot be less than zero or greater than the bitmap height.");
}
#endif
int start = ((y * this.Width) + x) * 4;
this.Pixels[start + 0] = value.B;
this.Pixels[start + 1] = value.G;
this.Pixels[start + 2] = value.R;
this.Pixels[start + 3] = value.A;
}
}
/// <summary>
/// Sets the pixel array of the image.
/// </summary>
/// <param name="width">
/// The new width of the image. Must be greater than zero.</param>
/// <param name="height">The new height of the image. Must be greater than zero.</param>
/// <param name="pixels">
/// The array with colors. Must be a multiple
/// of four, width and height.
/// </param>
/// <exception cref="ArgumentOutOfRangeException">
/// Thrown if either <paramref name="width"/> or <paramref name="height"/> are less than or equal to 0.
/// </exception>
/// <exception cref="ArgumentException">
/// Thrown if the <paramref name="pixels"/> length is not equal to Width * Height * 4.
/// </exception>
public void SetPixels(int width, int height, byte[] pixels)
{
if (width <= 0)
{
throw new ArgumentOutOfRangeException("width", "Width must be greater than or equals than zero.");
}
if (height <= 0)
{
throw new ArgumentOutOfRangeException("height", "Height must be greater than or equal than zero.");
}
if (pixels.Length != width * height * 4)
{
throw new ArgumentException("Pixel array must have the length of Width * Height * 4.");
}
this.Width = width;
this.Height = height;
this.Pixels = pixels;
}
}
}

5
src/ImageProcessor/ImageProcessor.csproj

@ -35,13 +35,16 @@
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<Folder Include="Common\Exceptions\" />
<Folder Include="Common\Extensions\" />
<Folder Include="Common\Helpers\" />
<Folder Include="Encoders\" />
<Folder Include="Filters\" />
</ItemGroup>
<ItemGroup>
<Compile Include="Colors\Color.cs" />
<Compile Include="Common\Exceptions\ImageFormatException.cs" />
<Compile Include="IImageBase.cs" />
<Compile Include="ImageBase.cs" />
<Compile Include="Numerics\Point.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Numerics\Rectangle.cs" />

1
src/ImageProcessor/ImageProcessor.csproj.DotSettings

@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=colors/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=common/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=common_005Cexceptions/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/CodeInspection/NamespaceProvider/NamespaceFoldersToSkip/=common_005Cextensions/@EntryIndexedValue">True</s:Boolean>

Loading…
Cancel
Save