mirror of https://github.com/SixLabors/ImageSharp
Browse Source
Former-commit-id: 9b7174022ac6745534acff3ed69718d143e91e6f Former-commit-id: f8d1e182dec104b3c77fec79cd4d7c00a299a70f Former-commit-id: 98f22a9d62b5133aeba4b4525a71b2e6c2b18133pull/1/head
41 changed files with 1039 additions and 1018 deletions
@ -1,103 +0,0 @@ |
|||
// <copyright file="IImage.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
using System; |
|||
using System.Collections.Generic; |
|||
using System.IO; |
|||
|
|||
using ImageProcessorCore.Formats; |
|||
|
|||
/// <summary>
|
|||
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
|
|||
/// </summary>
|
|||
public interface IImage : IImageBase |
|||
{ |
|||
/// <summary>
|
|||
/// Gets or sets the resolution of the image in x- direction. It is defined as
|
|||
/// number of dots per inch and should be an positive value.
|
|||
/// </summary>
|
|||
/// <value>The density of the image in x- direction.</value>
|
|||
double HorizontalResolution { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the resolution of the image in y- direction. It is defined as
|
|||
/// number of dots per inch and should be an positive value.
|
|||
/// </summary>
|
|||
/// <value>The density of the image in y- direction.</value>
|
|||
double VerticalResolution { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the width of the image in inches. It is calculated as the width of the image
|
|||
/// in pixels multiplied with the density. When the density is equals or less than zero
|
|||
/// the default value is used.
|
|||
/// </summary>
|
|||
/// <value>The width of the image in inches.</value>
|
|||
double InchWidth { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the height of the image in inches. It is calculated as the height of the image
|
|||
/// in pixels multiplied with the density. When the density is equals or less than zero
|
|||
/// the default value is used.
|
|||
/// </summary>
|
|||
/// <value>The height of the image in inches.</value>
|
|||
double InchHeight { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether this image is animated.
|
|||
/// </summary>
|
|||
/// <value>
|
|||
/// <c>True</c> if this image is animated; otherwise, <c>false</c>.
|
|||
/// </value>
|
|||
bool IsAnimated { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the number of times any animation is repeated.
|
|||
/// <remarks>0 means to repeat indefinitely.</remarks>
|
|||
/// </summary>
|
|||
ushort RepeatCount { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the currently loaded image format.
|
|||
/// </summary>
|
|||
IImageFormat CurrentImageFormat { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the other frames for the animation.
|
|||
/// </summary>
|
|||
/// <value>The list of frame images.</value>
|
|||
IList<ImageFrame> Frames { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the list of properties for storing meta information about this image.
|
|||
/// </summary>
|
|||
/// <value>A list of image properties.</value>
|
|||
IList<ImageProperty> Properties { get; } |
|||
|
|||
/// <summary>
|
|||
/// Saves the image to the given stream using the currently loaded image format.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to save the image to.</param>
|
|||
/// <exception cref="ArgumentNullException">Thrown if the stream is null.</exception>
|
|||
void Save(Stream stream); |
|||
|
|||
/// <summary>
|
|||
/// Saves the image to the given stream using the given image format.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to save the image to.</param>
|
|||
/// <param name="format">The format to save the image as.</param>
|
|||
/// <exception cref="ArgumentNullException">Thrown if the stream is null.</exception>
|
|||
void Save(Stream stream, IImageFormat format); |
|||
|
|||
/// <summary>
|
|||
/// Saves the image to the given stream using the given image encoder.
|
|||
/// </summary>
|
|||
/// <param name="stream">The stream to save the image to.</param>
|
|||
/// <param name="encoder">The encoder to save the image with.</param>
|
|||
/// <exception cref="ArgumentNullException">Thrown if the stream is null.</exception>
|
|||
void Save(Stream stream, IImageEncoder encoder); |
|||
} |
|||
} |
|||
@ -1,106 +0,0 @@ |
|||
// <copyright file="IImageBase.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
using System; |
|||
using System.Runtime.CompilerServices; |
|||
|
|||
/// <summary>
|
|||
/// Encapsulates 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 red, the green, the blue, and the alpha value for
|
|||
/// each pixel in this order.
|
|||
/// </remarks>
|
|||
float[] 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 th quality of the image. This affects the output quality of lossy image formats.
|
|||
/// </summary>
|
|||
int Quality { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Gets or sets the frame delay for animated images.
|
|||
/// If not 0, this field specifies the number of hundredths (1/100) of a second to
|
|||
/// wait before continuing with the processing of the Data Stream.
|
|||
/// The clock starts ticking immediately after the graphic is rendered.
|
|||
/// </summary>
|
|||
int FrameDelay { get; set; } |
|||
|
|||
/// <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 to the given value.
|
|||
/// </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 times the 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>
|
|||
void SetPixels(int width, int height, float[] pixels); |
|||
|
|||
/// <summary>
|
|||
/// Sets the pixel array of the image to the given value, creating a copy of
|
|||
/// the original pixels.
|
|||
/// </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 times the 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>
|
|||
void ClonePixels(int width, int height, float[] pixels); |
|||
} |
|||
} |
|||
@ -0,0 +1,164 @@ |
|||
// <copyright file="PixelAccessor.cs" company="James Jackson-South">
|
|||
// Copyright (c) James Jackson-South and contributors.
|
|||
// Licensed under the Apache License, Version 2.0.
|
|||
// </copyright>
|
|||
|
|||
namespace ImageProcessorCore |
|||
{ |
|||
using System; |
|||
using System.Runtime.InteropServices; |
|||
|
|||
/// <summary>
|
|||
/// Provides per-pixel access to an images pixels.
|
|||
/// </summary>
|
|||
public sealed unsafe class PixelAccessor : IDisposable |
|||
{ |
|||
/// <summary>
|
|||
/// The position of the first pixel in the bitmap.
|
|||
/// </summary>
|
|||
private float* 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="PixelAccessor"/> class.
|
|||
/// </summary>
|
|||
/// <param name="image">
|
|||
/// The image to provide pixel access for.
|
|||
/// </param>
|
|||
public PixelAccessor(ImageBase image) |
|||
{ |
|||
Guard.NotNull(image, nameof(image)); |
|||
Guard.MustBeGreaterThan(image.Width, 0, "image width"); |
|||
Guard.MustBeGreaterThan(image.Height, 0, "image height"); |
|||
|
|||
int size = image.Pixels.Length; |
|||
this.Width = image.Width; |
|||
this.Height = image.Height; |
|||
|
|||
// Assign the pointer.
|
|||
// If buffer is allocated on Large Object Heap, then we are going to pin it instead of making a copy.
|
|||
if (size > (85 * 1024)) |
|||
{ |
|||
this.pixelsHandle = GCHandle.Alloc(image.Pixels, GCHandleType.Pinned); |
|||
this.pixelsBase = (float*)this.pixelsHandle.AddrOfPinnedObject().ToPointer(); |
|||
} |
|||
else |
|||
{ |
|||
fixed (float* pbuffer = image.Pixels) |
|||
{ |
|||
this.pixelsBase = pbuffer; |
|||
} |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Finalizes an instance of the <see cref="PixelAccessor"/> class.
|
|||
/// </summary>
|
|||
~PixelAccessor() |
|||
{ |
|||
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="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(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 *((Color*)(this.pixelsBase + ((y * this.Width) + x) * 4)); |
|||
} |
|||
|
|||
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
|
|||
*(Color*)(this.pixelsBase + (((y * this.Width) + x) * 4)) = 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