mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: e8d174508130e99cb9152e3c6dad690232425075 Former-commit-id: 4191408f0e2678dfb6937918c46a0d588da073d7 Former-commit-id: 3dc34dfac9b7e02f3dca4e80b1d8cf41fe40ee35pull/1/head
3 changed files with 177 additions and 4 deletions
@ -0,0 +1,25 @@ |
|||||
|
namespace GenericImage |
||||
|
{ |
||||
|
using GenericImage.PackedVectors; |
||||
|
|
||||
|
public class ImageRgba32 : IImageBase<Rgba32> |
||||
|
{ |
||||
|
public ImageRgba32(int width, int height) |
||||
|
{ |
||||
|
this.Width = width; |
||||
|
this.Height = height; |
||||
|
this.Pixels = new Rgba32[width * height]; |
||||
|
} |
||||
|
|
||||
|
public Rgba32[] Pixels { get; } |
||||
|
|
||||
|
public int Width { get; } |
||||
|
|
||||
|
public int Height { get; } |
||||
|
|
||||
|
public IPixelAccessor Lock() |
||||
|
{ |
||||
|
return new PixelAccessorRgba32(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,148 @@ |
|||||
|
namespace GenericImage |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Runtime.InteropServices; |
||||
|
|
||||
|
using GenericImage.PackedVectors; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides per-pixel access to an images pixels.
|
||||
|
/// </summary>
|
||||
|
public sealed unsafe class PixelAccessorRgba32 : IPixelAccessor |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// The position of the first pixel in the bitmap.
|
||||
|
/// </summary>
|
||||
|
private Rgba32* pixelsBase; |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Provides a way to access the pixels from unmanaged memory.
|
||||
|
/// </summary>
|
||||
|
private GCHandle pixelsHandle; |
||||
|
|
||||
|
/// <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="PixelAccessorRgba32"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="image">
|
||||
|
/// The image to provide pixel access for.
|
||||
|
/// </param>
|
||||
|
public PixelAccessorRgba32(IImageBase<Rgba32> image) |
||||
|
{ |
||||
|
//Guard.NotNull(image, nameof(image));
|
||||
|
//Guard.MustBeGreaterThan(image.Width, 0, "image width");
|
||||
|
//Guard.MustBeGreaterThan(image.Height, 0, "image height");
|
||||
|
|
||||
|
this.Width = image.Width; |
||||
|
this.Height = image.Height; |
||||
|
|
||||
|
this.pixelsHandle = GCHandle.Alloc(image.Pixels, GCHandleType.Pinned); |
||||
|
this.pixelsBase = (Rgba32*)this.pixelsHandle.AddrOfPinnedObject().ToPointer(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Finalizes an instance of the <see cref="PixelAccessorRgba32"/> class.
|
||||
|
/// </summary>
|
||||
|
~PixelAccessorRgba32() |
||||
|
{ |
||||
|
this.Dispose(); |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the width of the image.
|
||||
|
/// </summary>
|
||||
|
public int Width { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the height of the image.
|
||||
|
/// </summary>
|
||||
|
public int Height { 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="IPackedVector"/> at the specified position.</returns>
|
||||
|
public IPackedVector this[int x, int y] |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
#if DEBUG
|
||||
|
if ((x < 0) || (x >= this.Width)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width."); |
||||
|
} |
||||
|
|
||||
|
if ((y < 0) || (y >= this.Height)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height."); |
||||
|
} |
||||
|
#endif
|
||||
|
return *(this.pixelsBase + ((y * this.Width) + x)); |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
#if DEBUG
|
||||
|
if ((x < 0) || (x >= this.Width)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(x), "Value cannot be less than zero or greater than the bitmap width."); |
||||
|
} |
||||
|
|
||||
|
if ((y < 0) || (y >= this.Height)) |
||||
|
{ |
||||
|
throw new ArgumentOutOfRangeException(nameof(y), "Value cannot be less than zero or greater than the bitmap height."); |
||||
|
} |
||||
|
#endif
|
||||
|
*(this.pixelsBase + ((y * this.Width) + x)) = (Rgba32)value; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
|
||||
|
/// </summary>
|
||||
|
public void Dispose() |
||||
|
{ |
||||
|
if (this.isDisposed) |
||||
|
{ |
||||
|
return; |
||||
|
} |
||||
|
|
||||
|
if (this.pixelsHandle.IsAllocated) |
||||
|
{ |
||||
|
this.pixelsHandle.Free(); |
||||
|
} |
||||
|
|
||||
|
this.pixelsBase = null; |
||||
|
|
||||
|
// Note disposing is done.
|
||||
|
this.isDisposed = true; |
||||
|
|
||||
|
// This object will be cleaned up by the Dispose method.
|
||||
|
// Therefore, you should call GC.SuppressFinalize to
|
||||
|
// take this object off the finalization queue
|
||||
|
// and prevent finalization code for this object
|
||||
|
// from executing a second time.
|
||||
|
GC.SuppressFinalize(this); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue