Browse Source

Now Color

Former-commit-id: df0c84ebe32444c8e2bf964f839af8fd6b80d196
Former-commit-id: af528ad7c73c8c20f1f1fb5f0e4864bc00dfc4ee
Former-commit-id: e62c836d6621e86a03386c83867d4dbcb668dc5e
af/merge-core
James Jackson-South 10 years ago
parent
commit
ee8987857d
  1. 2
      src/ImageProcessorCore/Bootstrapper.cs
  2. 27
      src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs
  3. 36
      src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs
  4. 4
      src/ImageProcessorCore/Image.cs
  5. 45
      src/ImageProcessorCore/PackedVector/Color.cs
  6. 1
      src/ImageProcessorCore/PackedVector/IPackedVector.cs
  7. 20
      src/ImageProcessorCore/PixelAccessor/ColorPixelAccessor.cs
  8. 12
      tests/ImageProcessorCore.Benchmarks/Image/GetSetPixel.cs

2
src/ImageProcessorCore/Bootstrapper.cs

@ -44,7 +44,7 @@ namespace ImageProcessorCore
this.pixelAccessors = new Dictionary<Type, Func<IImageBase, IPixelAccessor>> this.pixelAccessors = new Dictionary<Type, Func<IImageBase, IPixelAccessor>>
{ {
{ typeof(Bgra32), i=> new Bgra32PixelAccessor(i) } { typeof(Color), i=> new ColorPixelAccessor(i) }
}; };
} }

27
src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs

@ -49,7 +49,8 @@ namespace ImageProcessorCore.Formats
/// Decodes the image from the specified this._stream and sets /// Decodes the image from the specified this._stream and sets
/// the data to image. /// the data to image.
/// </summary> /// </summary>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam> /// <typeparam name="T">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="image">The image, where the data should be set to. /// <param name="image">The image, where the data should be set to.
/// Cannot be null (Nothing in Visual Basic).</param> /// Cannot be null (Nothing in Visual Basic).</param>
/// <param name="stream">The this._stream, where the image should be /// <param name="stream">The this._stream, where the image should be
@ -187,7 +188,8 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Reads the color palette from the stream. /// Reads the color palette from the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam> /// <typeparam name="T">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="imageData">The <see cref="T:T[]"/> image data to assign the palette to.</param> /// <param name="imageData">The <see cref="T:T[]"/> image data to assign the palette to.</param>
/// <param name="colors">The <see cref="T:byte[]"/> containing the colors.</param> /// <param name="colors">The <see cref="T:byte[]"/> containing the colors.</param>
/// <param name="width">The width of the bitmap.</param> /// <param name="width">The width of the bitmap.</param>
@ -238,9 +240,9 @@ namespace ImageProcessorCore.Formats
int colorIndex = ((data[offset] >> (8 - bits - (shift * bits))) & mask) * 4; int colorIndex = ((data[offset] >> (8 - bits - (shift * bits))) & mask) * 4;
int arrayOffset = (row * width) + (colOffset + shift); int arrayOffset = (row * width) + (colOffset + shift);
// Stored in b-> g-> r-> a order. // Stored in b-> g-> r order.
T packed = default(T); T packed = default(T);
packed.PackBytes(colors[colorIndex], colors[colorIndex + 1], colors[colorIndex + 2], 255); packed.PackBytes(colors[colorIndex + 2], colors[colorIndex + 1], colors[colorIndex], 255);
imageData[arrayOffset] = packed; imageData[arrayOffset] = packed;
} }
} }
@ -250,7 +252,8 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Reads the 16 bit color palette from the stream /// Reads the 16 bit color palette from the stream
/// </summary> /// </summary>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam> /// <typeparam name="T">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="imageData">The <see cref="T:T[]"/> image data to assign the palette to.</param> /// <param name="imageData">The <see cref="T:T[]"/> image data to assign the palette to.</param>
/// <param name="width">The width of the bitmap.</param> /// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param> /// <param name="height">The height of the bitmap.</param>
@ -288,9 +291,9 @@ namespace ImageProcessorCore.Formats
int arrayOffset = ((row * width) + x); int arrayOffset = ((row * width) + x);
// Stored in b-> g-> r-> a order. // Stored in b-> g-> r order.
T packed = default(T); T packed = default(T);
packed.PackBytes(b, g, r, 255); packed.PackBytes(r, g, b, 255);
imageData[arrayOffset] = packed; imageData[arrayOffset] = packed;
} }
}); });
@ -299,7 +302,8 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Reads the 24 bit color palette from the stream /// Reads the 24 bit color palette from the stream
/// </summary> /// </summary>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam> /// <typeparam name="T">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="imageData">The <see cref="T:T[]"/> image data to assign the palette to.</param> /// <param name="imageData">The <see cref="T:T[]"/> image data to assign the palette to.</param>
/// <param name="width">The width of the bitmap.</param> /// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param> /// <param name="height">The height of the bitmap.</param>
@ -329,7 +333,7 @@ namespace ImageProcessorCore.Formats
// We divide by 255 as we will store the colors in our floating point format. // We divide by 255 as we will store the colors in our floating point format.
// Stored in b-> g-> r-> a order. // Stored in b-> g-> r-> a order.
T packed = default(T); T packed = default(T);
packed.PackBytes(data[offset], data[offset + 1], data[offset + 2], 255); packed.PackBytes(data[offset + 2], data[offset + 1], data[offset], 255);
imageData[arrayOffset] = packed; imageData[arrayOffset] = packed;
} }
}); });
@ -338,7 +342,8 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Reads the 32 bit color palette from the stream /// Reads the 32 bit color palette from the stream
/// </summary> /// </summary>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam> /// <typeparam name="T">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="imageData">The <see cref="T:T[]"/> image data to assign the palette to.</param> /// <param name="imageData">The <see cref="T:T[]"/> image data to assign the palette to.</param>
/// <param name="width">The width of the bitmap.</param> /// <param name="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param> /// <param name="height">The height of the bitmap.</param>
@ -367,7 +372,7 @@ namespace ImageProcessorCore.Formats
// Stored in b-> g-> r-> a order. // Stored in b-> g-> r-> a order.
T packed = default(T); T packed = default(T);
packed.PackBytes(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]); packed.PackBytes(data[offset + 2], data[offset + 1], data[offset], data[offset + 3]);
imageData[arrayOffset] = packed; imageData[arrayOffset] = packed;
} }
}); });

36
src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs

@ -13,7 +13,6 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Image encoder for writing an image to a stream as a Windows bitmap. /// Image encoder for writing an image to a stream as a Windows bitmap.
/// </summary> /// </summary>
/// <remarks>The encoder can currently only write 24-bit rgb images to streams.</remarks>
internal sealed class BmpEncoderCore internal sealed class BmpEncoderCore
{ {
/// <summary> /// <summary>
@ -22,13 +21,14 @@ namespace ImageProcessorCore.Formats
private BmpBitsPerPixel bmpBitsPerPixel; private BmpBitsPerPixel bmpBitsPerPixel;
/// <summary> /// <summary>
/// Encodes the image to the specified stream from the <see cref="ImageBase{T}"/>. /// Encodes the image to the specified stream from the <see cref="ImageBase{T,TP}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam> /// <typeparam name="T">The pixel format.</typeparam>
/// <param name="image">The <see cref="ImageBase{T}"/> to encode from.</param> /// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="image">The <see cref="ImageBase{T,TP}"/> to encode from.</param>
/// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param> /// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
/// <param name="bitsPerPixel">The <see cref="BmpBitsPerPixel"/></param> /// <param name="bitsPerPixel">The <see cref="BmpBitsPerPixel"/></param>
public void Encode<T,TP>(ImageBase<T,TP> image, Stream stream, BmpBitsPerPixel bitsPerPixel) public void Encode<T, TP>(ImageBase<T, TP> image, Stream stream, BmpBitsPerPixel bitsPerPixel)
where T : IPackedVector<TP>, new() where T : IPackedVector<TP>, new()
where TP : struct where TP : struct
{ {
@ -121,14 +121,14 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the pixel data to the binary stream. /// Writes the pixel data to the binary stream.
/// </summary> /// </summary>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam> /// <typeparam name="T">The pixel format.</typeparam>
/// <param name="writer"> /// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>/// <param name="writer">
/// The <see cref="EndianBinaryWriter"/> containing the stream to write to. /// The <see cref="EndianBinaryWriter"/> containing the stream to write to.
/// </param> /// </param>
/// <param name="image"> /// <param name="image">
/// The <see cref="ImageBase{T}"/> containing pixel data. /// The <see cref="ImageBase{T,TP}"/> containing pixel data.
/// </param> /// </param>
private void WriteImage<T,TP>(EndianBinaryWriter writer, ImageBase<T,TP> image) private void WriteImage<T, TP>(EndianBinaryWriter writer, ImageBase<T, TP> image)
where T : IPackedVector<TP>, new() where T : IPackedVector<TP>, new()
where TP : struct where TP : struct
{ {
@ -139,7 +139,7 @@ namespace ImageProcessorCore.Formats
amount = 4 - amount; amount = 4 - amount;
} }
using (IPixelAccessor<T,TP> pixels = image.Lock()) using (IPixelAccessor<T, TP> pixels = image.Lock())
{ {
switch (this.bmpBitsPerPixel) switch (this.bmpBitsPerPixel)
{ {
@ -157,11 +157,12 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the 32bit color palette to the stream. /// Writes the 32bit color palette to the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam> /// <typeparam name="T">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="writer">The <see cref="EndianBinaryWriter"/> containing the stream to write to.</param> /// <param name="writer">The <see cref="EndianBinaryWriter"/> containing the stream to write to.</param>
/// <param name="pixels">The <see cref="IPixelAccessor"/> containing pixel data.</param> /// <param name="pixels">The <see cref="IPixelAccessor"/> containing pixel data.</param>
/// <param name="amount">The amount to pad each row by.</param> /// <param name="amount">The amount to pad each row by.</param>
private void Write32bit<T,TP>(EndianBinaryWriter writer, IPixelAccessor<T,TP> pixels, int amount) private void Write32bit<T, TP>(EndianBinaryWriter writer, IPixelAccessor<T, TP> pixels, int amount)
where T : IPackedVector<TP>, new() where T : IPackedVector<TP>, new()
where TP : struct where TP : struct
{ {
@ -171,7 +172,7 @@ namespace ImageProcessorCore.Formats
{ {
// Convert back to b-> g-> r-> a order. // Convert back to b-> g-> r-> a order.
byte[] bytes = pixels[x, y].ToBytes(); byte[] bytes = pixels[x, y].ToBytes();
writer.Write(bytes); writer.Write(new[] { bytes[2], bytes[1], bytes[0], bytes[3] });
} }
// Pad // Pad
@ -185,10 +186,11 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the 24bit color palette to the stream. /// Writes the 24bit color palette to the stream.
/// </summary> /// </summary>
/// <param name="writer">The <see cref="EndianBinaryWriter"/> containing the stream to write to.</param> /// <typeparam name="T">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>/// <param name="writer">The <see cref="EndianBinaryWriter"/> containing the stream to write to.</param>
/// <param name="pixels">The <see cref="IPixelAccessor"/> containing pixel data.</param> /// <param name="pixels">The <see cref="IPixelAccessor"/> containing pixel data.</param>
/// <param name="amount">The amount to pad each row by.</param> /// <param name="amount">The amount to pad each row by.</param>
private void Write24bit<T,TP>(EndianBinaryWriter writer, IPixelAccessor<T,TP> pixels, int amount) private void Write24bit<T, TP>(EndianBinaryWriter writer, IPixelAccessor<T, TP> pixels, int amount)
where T : IPackedVector<TP>, new() where T : IPackedVector<TP>, new()
where TP : struct where TP : struct
{ {
@ -196,9 +198,9 @@ namespace ImageProcessorCore.Formats
{ {
for (int x = 0; x < pixels.Width; x++) for (int x = 0; x < pixels.Width; x++)
{ {
// Convert back to b-> g-> r-> a order. // Convert back to b-> g-> r order.
byte[] bytes = pixels[x, y].ToBytes(); byte[] bytes = pixels[x, y].ToBytes();
writer.Write(new[] { bytes[0], bytes[1], bytes[2] }); writer.Write(new[] { bytes[2], bytes[1], bytes[0] });
} }
// Pad // Pad

4
src/ImageProcessorCore/Image.cs

@ -9,9 +9,9 @@ namespace ImageProcessorCore
using System.IO; using System.IO;
/// <summary> /// <summary>
/// Represents an image. Each pixel is a made up four 8-bit components blue, green, red, and alpha. /// Represents an image. Each pixel is a made up four 8-bit components red, green, blue, and alpha.
/// </summary> /// </summary>
public class Image : Image<Bgra32, uint> public class Image : Image<Color, uint>
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Image"/> class /// Initializes a new instance of the <see cref="Image"/> class

45
src/ImageProcessorCore/PackedVector/Bgra32.cs → src/ImageProcessorCore/PackedVector/Color.cs

@ -1,7 +1,8 @@
// <copyright file="Bgra32.cs" company="James Jackson-South"> // <copyright file="Color.cs" company="James Jackson-South">
// Copyright (c) James Jackson-South and contributors. // Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0. // Licensed under the Apache License, Version 2.0.
// </copyright> // </copyright>
namespace ImageProcessorCore namespace ImageProcessorCore
{ {
using System; using System;
@ -13,13 +14,13 @@ namespace ImageProcessorCore
/// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 255. /// Packed vector type containing four 8-bit unsigned normalized values ranging from 0 to 255.
/// </summary> /// </summary>
[StructLayout(LayoutKind.Explicit)] [StructLayout(LayoutKind.Explicit)]
public struct Bgra32 : IPackedVector<uint>, IEquatable<Bgra32> public struct Color : IPackedVector<uint>, IEquatable<Color>
{ {
/// <summary> /// <summary>
/// Gets or sets the blue component. /// Gets or sets the blue component.
/// </summary> /// </summary>
[FieldOffset(0)] [FieldOffset(0)]
public byte B; public byte R;
/// <summary> /// <summary>
/// Gets or sets the green component. /// Gets or sets the green component.
@ -31,7 +32,7 @@ namespace ImageProcessorCore
/// Gets or sets the red component. /// Gets or sets the red component.
/// </summary> /// </summary>
[FieldOffset(2)] [FieldOffset(2)]
public byte R; public byte B;
/// <summary> /// <summary>
/// Gets or sets the alpha component. /// Gets or sets the alpha component.
@ -46,13 +47,13 @@ namespace ImageProcessorCore
private readonly uint packedValue; private readonly uint packedValue;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Bgra32"/> struct. /// Initializes a new instance of the <see cref="Color"/> struct.
/// </summary> /// </summary>
/// <param name="b">The blue component.</param> /// <param name="b">The blue component.</param>
/// <param name="g">The green component.</param> /// <param name="g">The green component.</param>
/// <param name="r">The red component.</param> /// <param name="r">The red component.</param>
/// <param name="a">The alpha component.</param> /// <param name="a">The alpha component.</param>
public Bgra32(float b, float g, float r, float a) public Color(float b, float g, float r, float a)
: this() : this()
{ {
Vector4 clamped = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, Vector4.One) * 255f; Vector4 clamped = Vector4.Clamp(new Vector4(b, g, r, a), Vector4.Zero, Vector4.One) * 255f;
@ -63,13 +64,13 @@ namespace ImageProcessorCore
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Bgra32"/> struct. /// Initializes a new instance of the <see cref="Color"/> struct.
/// </summary> /// </summary>
/// <param name="b">The blue component.</param> /// <param name="b">The blue component.</param>
/// <param name="g">The green component.</param> /// <param name="g">The green component.</param>
/// <param name="r">The red component.</param> /// <param name="r">The red component.</param>
/// <param name="a">The alpha component.</param> /// <param name="a">The alpha component.</param>
public Bgra32(byte b, byte g, byte r, byte a) public Color(byte b, byte g, byte r, byte a)
: this() : this()
{ {
this.B = b; this.B = b;
@ -79,12 +80,12 @@ namespace ImageProcessorCore
} }
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Bgra32"/> struct. /// Initializes a new instance of the <see cref="Color"/> struct.
/// </summary> /// </summary>
/// <param name="vector"> /// <param name="vector">
/// The vector containing the components for the packed vector. /// The vector containing the components for the packed vector.
/// </param> /// </param>
public Bgra32(Vector4 vector) public Color(Vector4 vector)
: this() : this()
{ {
Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 255f; Vector4 clamped = Vector4.Clamp(vector, Vector4.Zero, Vector4.One) * 255f;
@ -95,31 +96,31 @@ namespace ImageProcessorCore
} }
/// <summary> /// <summary>
/// Compares two <see cref="Bgra32"/> objects for equality. /// Compares two <see cref="Color"/> objects for equality.
/// </summary> /// </summary>
/// <param name="left"> /// <param name="left">
/// The <see cref="Bgra32"/> on the left side of the operand. /// The <see cref="Color"/> on the left side of the operand.
/// </param> /// </param>
/// <param name="right"> /// <param name="right">
/// The <see cref="Bgra32"/> on the right side of the operand. /// The <see cref="Color"/> on the right side of the operand.
/// </param> /// </param>
/// <returns> /// <returns>
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false. /// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns> /// </returns>
public static bool operator ==(Bgra32 left, Bgra32 right) public static bool operator ==(Color left, Color right)
{ {
return left.packedValue == right.packedValue; return left.packedValue == right.packedValue;
} }
/// <summary> /// <summary>
/// Compares two <see cref="Bgra32"/> objects for equality. /// Compares two <see cref="Color"/> objects for equality.
/// </summary> /// </summary>
/// <param name="left">The <see cref="Bgra32"/> on the left side of the operand.</param> /// <param name="left">The <see cref="Color"/> on the left side of the operand.</param>
/// <param name="right">The <see cref="Bgra32"/> on the right side of the operand.</param> /// <param name="right">The <see cref="Color"/> on the right side of the operand.</param>
/// <returns> /// <returns>
/// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false. /// True if the current left is equal to the <paramref name="right"/> parameter; otherwise, false.
/// </returns> /// </returns>
public static bool operator !=(Bgra32 left, Bgra32 right) public static bool operator !=(Color left, Color right)
{ {
return left.packedValue != right.packedValue; return left.packedValue != right.packedValue;
} }
@ -164,11 +165,11 @@ namespace ImageProcessorCore
/// <inheritdoc/> /// <inheritdoc/>
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
return (obj is Bgra32) && this.Equals((Bgra32)obj); return (obj is Color) && this.Equals((Color)obj);
} }
/// <inheritdoc/> /// <inheritdoc/>
public bool Equals(Bgra32 other) public bool Equals(Color other)
{ {
return this.packedValue == other.packedValue; return this.packedValue == other.packedValue;
} }
@ -192,13 +193,13 @@ namespace ImageProcessorCore
/// Returns the hash code for this instance. /// Returns the hash code for this instance.
/// </summary> /// </summary>
/// <param name="packed"> /// <param name="packed">
/// The instance of <see cref="Bgra32"/> to return the hash code for. /// The instance of <see cref="Color"/> to return the hash code for.
/// </param> /// </param>
/// <returns> /// <returns>
/// A 32-bit signed integer that is the hash code for this instance. /// A 32-bit signed integer that is the hash code for this instance.
/// </returns> /// </returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private int GetHashCode(Bgra32 packed) private int GetHashCode(Color packed)
{ {
return packed.packedValue.GetHashCode(); return packed.packedValue.GetHashCode();
} }

1
src/ImageProcessorCore/PackedVector/IPackedVector.cs

@ -55,6 +55,7 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Expands the packed representation into a <see cref="T:byte[]"/>. /// Expands the packed representation into a <see cref="T:byte[]"/>.
/// The bytes are typically expanded in least to greatest significance order. /// The bytes are typically expanded in least to greatest significance order.
/// Red -> Green -> Blue -> Alpha
/// </summary> /// </summary>
/// <returns>The <see cref="Vector4"/>.</returns> /// <returns>The <see cref="Vector4"/>.</returns>
byte[] ToBytes(); byte[] ToBytes();

20
src/ImageProcessorCore/PixelAccessor/Bgra32PixelAccessor.cs → src/ImageProcessorCore/PixelAccessor/ColorPixelAccessor.cs

@ -12,15 +12,15 @@ namespace ImageProcessorCore
/// Provides per-pixel access to an images pixels. /// Provides per-pixel access to an images pixels.
/// </summary> /// </summary>
/// <remarks> /// <remarks>
/// The image data is always stored in <see cref="Bgra32"/> format, where the blue, green, red, and /// The image data is always stored in <see cref="Color"/> format, where the red, green, blue, and
/// alpha values are 8 bit unsigned bytes. /// alpha values are 8 bit unsigned bytes.
/// </remarks> /// </remarks>
public sealed unsafe class Bgra32PixelAccessor : IPixelAccessor<Bgra32, uint> public sealed unsafe class ColorPixelAccessor : IPixelAccessor<Color, uint>
{ {
/// <summary> /// <summary>
/// The position of the first pixel in the bitmap. /// The position of the first pixel in the bitmap.
/// </summary> /// </summary>
private Bgra32* pixelsBase; private Color* pixelsBase;
/// <summary> /// <summary>
/// Provides a way to access the pixels from unmanaged memory. /// Provides a way to access the pixels from unmanaged memory.
@ -41,12 +41,12 @@ namespace ImageProcessorCore
private bool isDisposed; private bool isDisposed;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="Bgra32PixelAccessor"/> class. /// Initializes a new instance of the <see cref="ColorPixelAccessor"/> class.
/// </summary> /// </summary>
/// <param name="image"> /// <param name="image">
/// The image to provide pixel access for. /// The image to provide pixel access for.
/// </param> /// </param>
public Bgra32PixelAccessor(IImageBase image) public ColorPixelAccessor(IImageBase image)
{ {
Guard.NotNull(image, nameof(image)); Guard.NotNull(image, nameof(image));
Guard.MustBeGreaterThan(image.Width, 0, "image width"); Guard.MustBeGreaterThan(image.Width, 0, "image width");
@ -55,14 +55,14 @@ namespace ImageProcessorCore
this.Width = image.Width; this.Width = image.Width;
this.Height = image.Height; this.Height = image.Height;
this.pixelsHandle = GCHandle.Alloc(((ImageBase<Bgra32, uint>)image).Pixels, GCHandleType.Pinned); this.pixelsHandle = GCHandle.Alloc(((ImageBase<Color, uint>)image).Pixels, GCHandleType.Pinned);
this.pixelsBase = (Bgra32*)this.pixelsHandle.AddrOfPinnedObject().ToPointer(); this.pixelsBase = (Color*)this.pixelsHandle.AddrOfPinnedObject().ToPointer();
} }
/// <summary> /// <summary>
/// Finalizes an instance of the <see cref="Bgra32PixelAccessor"/> class. /// Finalizes an instance of the <see cref="ColorPixelAccessor"/> class.
/// </summary> /// </summary>
~Bgra32PixelAccessor() ~ColorPixelAccessor()
{ {
this.Dispose(); this.Dispose();
} }
@ -89,7 +89,7 @@ namespace ImageProcessorCore
/// than zero and smaller than the width of the pixel. /// than zero and smaller than the width of the pixel.
/// </param> /// </param>
/// <returns>The <see cref="IPackedVector"/> at the specified position.</returns> /// <returns>The <see cref="IPackedVector"/> at the specified position.</returns>
public Bgra32 this[int x, int y] public Color this[int x, int y]
{ {
get get
{ {

12
tests/ImageProcessorCore.Benchmarks/Image/GetSetPixel.cs

@ -4,8 +4,8 @@
using BenchmarkDotNet.Attributes; using BenchmarkDotNet.Attributes;
//using CoreColor = ImageProcessorCore.Color; using CoreColor = ImageProcessorCore.Color;
//using CoreImage = ImageProcessorCore.Image<Bgra32>; using CoreImage = ImageProcessorCore.Image;
using SystemColor = System.Drawing.Color; using SystemColor = System.Drawing.Color;
public class GetSetPixel public class GetSetPixel
@ -21,12 +21,12 @@
} }
[Benchmark(Description = "ImageProcessorCore GetSet Pixel")] [Benchmark(Description = "ImageProcessorCore GetSet Pixel")]
public Bgra32 ResizeCore() public CoreColor ResizeCore()
{ {
Image<Bgra32, uint> image = new Image<Bgra32, uint>(400, 400); CoreImage image = new CoreImage(400, 400);
using (IPixelAccessor<Bgra32, uint> imagePixels = image.Lock()) using (IPixelAccessor<CoreColor, uint> imagePixels = image.Lock())
{ {
imagePixels[200, 200] = new Bgra32(1, 1, 1, 1); imagePixels[200, 200] = new CoreColor(255, 255, 255, 255);
return imagePixels[200, 200]; return imagePixels[200, 200];
} }
} }

Loading…
Cancel
Save