Browse Source

Moar T

Former-commit-id: 53f37fb68f78c602df15d87f6c9086f75eed1cfc
Former-commit-id: 79ee79b98b686595c4e5d6054365884a7dbf5b7a
Former-commit-id: afc91142ccd716afb271b29bdbf736d779ef4d84
af/merge-core
James Jackson-South 10 years ago
parent
commit
ff9bca00f7
  1. 10
      src/ImageProcessorCore/Bootstrapper.cs
  2. 8
      src/ImageProcessorCore/Formats/Bmp/BmpDecoder.cs
  3. 48
      src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs
  4. 4
      src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs
  5. 30
      src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs
  6. 10
      src/ImageProcessorCore/Formats/IImageDecoder.cs
  7. 10
      src/ImageProcessorCore/Formats/IImageEncoder.cs
  8. 12
      src/ImageProcessorCore/IImageBase.cs
  9. 4
      src/ImageProcessorCore/IImageFrame.cs
  10. 16
      src/ImageProcessorCore/IImageProcessor.cs
  11. 26
      src/ImageProcessorCore/Image.cs
  12. 32
      src/ImageProcessorCore/ImageBase.cs
  13. 56
      src/ImageProcessorCore/ImageExtensions.cs
  14. 16
      src/ImageProcessorCore/ImageFrame.cs
  15. 28
      src/ImageProcessorCore/ImageProcessor.cs
  16. 8
      src/ImageProcessorCore/PackedVector/IPackedVector.cs
  17. 8
      src/ImageProcessorCore/PixelAccessor/IPixelAccessor.cs
  18. 36
      src/ImageProcessorCore/Samplers/Options/ResizeHelper.cs
  19. 23
      src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs
  20. 40
      src/ImageProcessorCore/Samplers/Resize.cs

10
src/ImageProcessorCore/Bootstrapper.cs

@ -70,16 +70,16 @@ namespace ImageProcessorCore
/// <summary>
/// Gets an instance of the correct <see cref="IPixelAccessor"/> for the packed vector.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixel data.</typeparam>
/// <typeparam name="T">The type of pixel data.</typeparam>
/// <param name="image">The image</param>
/// <returns>The <see cref="IPixelAccessor"/></returns>
public IPixelAccessor<TPackedVector> GetPixelAccessor<TPackedVector>(IImageBase image)
where TPackedVector : IPackedVector, new()
public IPixelAccessor<T> GetPixelAccessor<T>(IImageBase image)
where T : IPackedVector, new()
{
Type packed = typeof(TPackedVector);
Type packed = typeof(T);
if (this.pixelAccessors.ContainsKey(packed))
{
return (IPixelAccessor<TPackedVector>)this.pixelAccessors[packed].Invoke(image);
return (IPixelAccessor<T>)this.pixelAccessors[packed].Invoke(image);
}
throw new NotSupportedException($"PixelAccessor cannot be loaded for {packed}:");

8
src/ImageProcessorCore/Formats/Bmp/BmpDecoder.cs

@ -70,12 +70,12 @@ namespace ImageProcessorCore.Formats
}
/// <summary>
/// Decodes the image from the specified stream to the <see cref="ImageBase{TPackedVector}"/>.
/// Decodes the image from the specified stream to the <see cref="ImageBase{T}"/>.
/// </summary>
/// <param name="image">The <see cref="ImageBase{TPackedVector}"/> to decode to.</param>
/// <param name="image">The <see cref="ImageBase{T}"/> to decode to.</param>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
public void Decode<TPackedVector>(Image<TPackedVector> image, Stream stream)
where TPackedVector : IPackedVector, new()
public void Decode<T>(Image<T> image, Stream stream)
where T : IPackedVector, new()
{
new BmpDecoderCore().Decode(image, stream);
}

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

@ -49,7 +49,7 @@ namespace ImageProcessorCore.Formats
/// Decodes the image from the specified this._stream and sets
/// the data to image.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="image">The image, where the data should be set to.
/// Cannot be null (Nothing in Visual Basic).</param>
/// <param name="stream">The this._stream, where the image should be
@ -59,8 +59,8 @@ namespace ImageProcessorCore.Formats
/// <para>- or -</para>
/// <para><paramref name="stream"/> is null.</para>
/// </exception>
public void Decode<TPackedVector>(Image<TPackedVector> image, Stream stream)
where TPackedVector : IPackedVector, new()
public void Decode<T>(Image<T> image, Stream stream)
where T : IPackedVector, new()
{
this.currentStream = stream;
@ -119,7 +119,7 @@ namespace ImageProcessorCore.Formats
+ $"bigger then the max allowed size '{image.MaxWidth}x{image.MaxHeight}'");
}
TPackedVector[] imageData = new TPackedVector[this.infoHeader.Width * this.infoHeader.Height];
T[] imageData = new T[this.infoHeader.Width * this.infoHeader.Height];
switch (this.infoHeader.Compression)
{
@ -192,15 +192,15 @@ namespace ImageProcessorCore.Formats
/// <summary>
/// Reads the color palette from the stream.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <param name="imageData">The <see cref="T:TPackedVector[]"/> image data to assign the palette to.</param>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <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="width">The width of the bitmap.</param>
/// <param name="height">The height of the bitmap.</param>
/// <param name="bits">The number of bits per pixel.</param>
/// <param name="inverted">Whether the bitmap is inverted.</param>
private void ReadRgbPalette<TPackedVector>(TPackedVector[] imageData, byte[] colors, int width, int height, int bits, bool inverted)
where TPackedVector : IPackedVector, new()
private void ReadRgbPalette<T>(T[] imageData, byte[] colors, int width, int height, int bits, bool inverted)
where T : IPackedVector, new()
{
// Pixels per byte (bits per pixel)
int ppb = 8 / bits;
@ -243,7 +243,7 @@ namespace ImageProcessorCore.Formats
int arrayOffset = (row * width) + (colOffset + shift);
// Stored in b-> g-> r-> a order.
TPackedVector packed = new TPackedVector();
T packed = new T();
packed.PackBytes(colors[colorIndex], colors[colorIndex + 1], colors[colorIndex + 2], 255);
imageData[arrayOffset] = packed;
}
@ -254,13 +254,13 @@ namespace ImageProcessorCore.Formats
/// <summary>
/// Reads the 16 bit color palette from the stream
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <param name="imageData">The <see cref="T:TPackedVector[]"/> image data to assign the palette to.</param>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <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="height">The height of the bitmap.</param>
/// <param name="inverted">Whether the bitmap is inverted.</param>
private void ReadRgb16<TPackedVector>(TPackedVector[] imageData, int width, int height, bool inverted)
where TPackedVector : IPackedVector, new()
private void ReadRgb16<T>(T[] imageData, int width, int height, bool inverted)
where T : IPackedVector, new()
{
// We divide here as we will store the colors in our floating point format.
const int ScaleR = 8; // 256/32
@ -292,7 +292,7 @@ namespace ImageProcessorCore.Formats
int arrayOffset = ((row * width) + x);
// Stored in b-> g-> r-> a order.
TPackedVector packed = new TPackedVector();
T packed = new T();
packed.PackBytes(b, g, r, 255);
imageData[arrayOffset] = packed;
}
@ -302,13 +302,13 @@ namespace ImageProcessorCore.Formats
/// <summary>
/// Reads the 24 bit color palette from the stream
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <param name="imageData">The <see cref="T:TPackedVector[]"/> image data to assign the palette to.</param>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <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="height">The height of the bitmap.</param>
/// <param name="inverted">Whether the bitmap is inverted.</param>
private void ReadRgb24<TPackedVector>(TPackedVector[] imageData, int width, int height, bool inverted)
where TPackedVector : IPackedVector, new()
private void ReadRgb24<T>(T[] imageData, int width, int height, bool inverted)
where T : IPackedVector, new()
{
int alignment;
byte[] data = this.GetImageArray(width, height, 3, out alignment);
@ -330,7 +330,7 @@ namespace ImageProcessorCore.Formats
// We divide by 255 as we will store the colors in our floating point format.
// Stored in b-> g-> r-> a order.
TPackedVector packed = new TPackedVector();
T packed = new T();
packed.PackBytes(data[offset], data[offset + 1], data[offset + 2], 255);
imageData[arrayOffset] = packed;
}
@ -340,13 +340,13 @@ namespace ImageProcessorCore.Formats
/// <summary>
/// Reads the 32 bit color palette from the stream
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <param name="imageData">The <see cref="T:TPackedVector[]"/> image data to assign the palette to.</param>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <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="height">The height of the bitmap.</param>
/// <param name="inverted">Whether the bitmap is inverted.</param>
private void ReadRgb32<TPackedVector>(TPackedVector[] imageData, int width, int height, bool inverted)
where TPackedVector : IPackedVector, new()
private void ReadRgb32<T>(T[] imageData, int width, int height, bool inverted)
where T : IPackedVector, new()
{
int alignment;
byte[] data = this.GetImageArray(width, height, 4, out alignment);
@ -367,7 +367,7 @@ namespace ImageProcessorCore.Formats
int arrayOffset = ((row * width) + x);
// Stored in b-> g-> r-> a order.
TPackedVector packed = new TPackedVector();
T packed = new T();
packed.PackBytes(data[offset], data[offset + 1], data[offset + 2], data[offset + 3]);
imageData[arrayOffset] = packed;
}

4
src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs

@ -43,8 +43,8 @@ namespace ImageProcessorCore.Formats
}
/// <inheritdoc/>
public void Encode<TPackedVector>(ImageBase<TPackedVector> image, Stream stream)
where TPackedVector : IPackedVector, new()
public void Encode<T>(ImageBase<T> image, Stream stream)
where T : IPackedVector, new()
{
BmpEncoderCore encoder = new BmpEncoderCore();
encoder.Encode(image, stream, this.BitsPerPixel);

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

@ -22,14 +22,14 @@ namespace ImageProcessorCore.Formats
private BmpBitsPerPixel bmpBitsPerPixel;
/// <summary>
/// Encodes the image to the specified stream from the <see cref="ImageBase{TPackedVector}"/>.
/// Encodes the image to the specified stream from the <see cref="ImageBase{T}"/>.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <param name="image">The <see cref="ImageBase{TPackedVector}"/> to encode from.</param>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="image">The <see cref="ImageBase{T}"/> to encode from.</param>
/// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
/// <param name="bitsPerPixel">The <see cref="BmpBitsPerPixel"/></param>
public void Encode<TPackedVector>(ImageBase<TPackedVector> image, Stream stream, BmpBitsPerPixel bitsPerPixel)
where TPackedVector : IPackedVector, new()
public void Encode<T>(ImageBase<T> image, Stream stream, BmpBitsPerPixel bitsPerPixel)
where T : IPackedVector, new()
{
Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream));
@ -120,15 +120,15 @@ namespace ImageProcessorCore.Formats
/// <summary>
/// Writes the pixel data to the binary stream.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="writer">
/// The <see cref="EndianBinaryWriter"/> containing the stream to write to.
/// </param>
/// <param name="image">
/// The <see cref="ImageBase{TPackedVector}"/> containing pixel data.
/// The <see cref="ImageBase{T}"/> containing pixel data.
/// </param>
private void WriteImage<TPackedVector>(EndianBinaryWriter writer, ImageBase<TPackedVector> image)
where TPackedVector : IPackedVector, new()
private void WriteImage<T>(EndianBinaryWriter writer, ImageBase<T> image)
where T : IPackedVector, new()
{
// TODO: Add more compression formats.
int amount = (image.Width * (int)this.bmpBitsPerPixel) % 4;
@ -137,7 +137,7 @@ namespace ImageProcessorCore.Formats
amount = 4 - amount;
}
using (IPixelAccessor<TPackedVector> pixels = image.Lock())
using (IPixelAccessor<T> pixels = image.Lock())
{
switch (this.bmpBitsPerPixel)
{
@ -155,12 +155,12 @@ namespace ImageProcessorCore.Formats
/// <summary>
/// Writes the 32bit color palette to the stream.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</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="amount">The amount to pad each row by.</param>
private void Write32bit<TPackedVector>(EndianBinaryWriter writer, IPixelAccessor<TPackedVector> pixels, int amount)
where TPackedVector : IPackedVector, new()
private void Write32bit<T>(EndianBinaryWriter writer, IPixelAccessor<T> pixels, int amount)
where T : IPackedVector, new()
{
for (int y = pixels.Height - 1; y >= 0; y--)
{
@ -185,8 +185,8 @@ namespace ImageProcessorCore.Formats
/// <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="amount">The amount to pad each row by.</param>
private void Write24bit<TPackedVector>(EndianBinaryWriter writer, IPixelAccessor<TPackedVector> pixels, int amount)
where TPackedVector : IPackedVector, new()
private void Write24bit<T>(EndianBinaryWriter writer, IPixelAccessor<T> pixels, int amount)
where T : IPackedVector, new()
{
for (int y = pixels.Height - 1; y >= 0; y--)
{

10
src/ImageProcessorCore/Formats/IImageDecoder.cs

@ -39,12 +39,12 @@ namespace ImageProcessorCore.Formats
bool IsSupportedFileFormat(byte[] header);
/// <summary>
/// Decodes the image from the specified stream to the <see cref="ImageBase{TPackedVector}"/>.
/// Decodes the image from the specified stream to the <see cref="ImageBase{T}"/>.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <param name="image">The <see cref="ImageBase{TPackedVector}"/> to decode to.</param>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="image">The <see cref="ImageBase{T}"/> to decode to.</param>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param>
void Decode<TPackedVector>(Image<TPackedVector> image, Stream stream)
where TPackedVector : IPackedVector, new();
void Decode<T>(Image<T> image, Stream stream)
where T : IPackedVector, new();
}
}

10
src/ImageProcessorCore/Formats/IImageEncoder.cs

@ -43,12 +43,12 @@ namespace ImageProcessorCore.Formats
bool IsSupportedFileExtension(string extension);
/// <summary>
/// Encodes the image to the specified stream from the <see cref="ImageBase{TPackedVector}"/>.
/// Encodes the image to the specified stream from the <see cref="ImageBase{T}"/>.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <param name="image">The <see cref="ImageBase{TPackedVector}"/> to encode from.</param>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="image">The <see cref="ImageBase{T}"/> to encode from.</param>
/// <param name="stream">The <see cref="Stream"/> to encode the image data to.</param>
void Encode<TPackedVector>(ImageBase<TPackedVector> image, Stream stream)
where TPackedVector : IPackedVector, new();
void Encode<T>(ImageBase<T> image, Stream stream)
where T : IPackedVector, new();
}
}

12
src/ImageProcessorCore/IImageBase.cs

@ -2,13 +2,13 @@
namespace ImageProcessorCore
{
public interface IImageBase<TPackedVector> : IImageBase
where TPackedVector : IPackedVector, new()
public interface IImageBase<T> : IImageBase
where T : IPackedVector, new()
{
TPackedVector[] Pixels { get; }
void ClonePixels(int width, int height, TPackedVector[] pixels);
IPixelAccessor<TPackedVector> Lock();
void SetPixels(int width, int height, TPackedVector[] pixels);
T[] Pixels { get; }
void ClonePixels(int width, int height, T[] pixels);
IPixelAccessor<T> Lock();
void SetPixels(int width, int height, T[] pixels);
}
public interface IImageBase

4
src/ImageProcessorCore/IImageFrame.cs

@ -1,7 +1,7 @@
namespace ImageProcessorCore
{
public interface IImageFrame<TPacked> : IImageBase<TPacked>
where TPacked : IPackedVector, new()
public interface IImageFrame<T> : IImageBase<T>
where T : IPackedVector, new()
{
}
}

16
src/ImageProcessorCore/IImageProcessor.cs

@ -27,9 +27,9 @@ namespace ImageProcessorCore.Processors
event ProgressEventHandler OnProgress;
/// <summary>
/// Applies the process to the specified portion of the specified <see cref="ImageBase{TPackedVector}"/>.
/// Applies the process to the specified portion of the specified <see cref="ImageBase{T}"/>.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="target">Target image to apply the process to.</param>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="sourceRectangle">
@ -45,14 +45,14 @@ namespace ImageProcessorCore.Processors
/// <exception cref="System.ArgumentException">
/// <paramref name="sourceRectangle"/> doesnt fit the dimension of the image.
/// </exception>
void Apply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, Rectangle sourceRectangle)
where TPackedVector : IPackedVector, new();
void Apply<T>(ImageBase<T> target, ImageBase<T> source, Rectangle sourceRectangle)
where T : IPackedVector, new();
/// <summary>
/// Applies the process to the specified portion of the specified <see cref="ImageBase{TPackedVector}"/> at the specified
/// Applies the process to the specified portion of the specified <see cref="ImageBase{T}"/> at the specified
/// location and with the specified size.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="target">Target image to apply the process to.</param>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="width">The target width.</param>
@ -68,7 +68,7 @@ namespace ImageProcessorCore.Processors
/// The method keeps the source image unchanged and returns the
/// the result of image process as new image.
/// </remarks>
void Apply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, int width, int height, Rectangle targetRectangle, Rectangle sourceRectangle)
where TPackedVector : IPackedVector, new();
void Apply<T>(ImageBase<T> target, ImageBase<T> source, int width, int height, Rectangle targetRectangle, Rectangle sourceRectangle)
where T : IPackedVector, new();
}
}

26
src/ImageProcessorCore/Image.cs

@ -17,11 +17,11 @@ namespace ImageProcessorCore
/// <summary>
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
/// </summary>
/// <typeparam name="TPackedVector">
/// <typeparam name="T">
/// The packed vector containing pixel information.
/// </typeparam>
public class Image<TPackedVector> : ImageBase<TPackedVector>
where TPackedVector : IPackedVector, new()
public class Image<T> : ImageBase<T>
where T : IPackedVector, new()
{
/// <summary>
/// The default horizontal resolution value (dots per inch) in x direction.
@ -36,7 +36,7 @@ namespace ImageProcessorCore
public const double DefaultVerticalResolution = 96;
/// <summary>
/// Initializes a new instance of the <see cref="Image{TPackedVector}"/> class.
/// Initializes a new instance of the <see cref="Image{T}"/> class.
/// </summary>
public Image()
{
@ -44,7 +44,7 @@ namespace ImageProcessorCore
}
/// <summary>
/// Initializes a new instance of the <see cref="Image{TPackedVector}"/> class
/// Initializes a new instance of the <see cref="Image{T}"/> class
/// with the height and the width of the image.
/// </summary>
/// <param name="width">The width of the image in pixels.</param>
@ -57,7 +57,7 @@ namespace ImageProcessorCore
}
/// <summary>
/// Initializes a new instance of the <see cref="Image{TPackedVector}"/> class.
/// Initializes a new instance of the <see cref="Image{T}"/> class.
/// </summary>
/// <param name="stream">
/// The stream containing image information.
@ -70,18 +70,18 @@ namespace ImageProcessorCore
}
/// <summary>
/// Initializes a new instance of the <see cref="Image{TPackedVector}"/> class
/// Initializes a new instance of the <see cref="Image{T}"/> class
/// by making a copy from another image.
/// </summary>
/// <param name="other">The other image, where the clone should be made from.</param>
/// <exception cref="ArgumentNullException"><paramref name="other"/> is null.</exception>
public Image(Image<TPackedVector> other)
public Image(Image<T> other)
{
foreach (ImageFrame<TPackedVector> frame in other.Frames)
foreach (ImageFrame<T> frame in other.Frames)
{
if (frame != null)
{
this.Frames.Add(new ImageFrame<TPackedVector>(frame));
this.Frames.Add(new ImageFrame<T>(frame));
}
}
@ -170,7 +170,7 @@ namespace ImageProcessorCore
/// Gets the other frames for the animation.
/// </summary>
/// <value>The list of frame images.</value>
public IList<ImageFrame<TPackedVector>> Frames { get; } = new List<ImageFrame<TPackedVector>>();
public IList<ImageFrame<T>> Frames { get; } = new List<ImageFrame<T>>();
/// <summary>
/// Gets the list of properties for storing meta information about this image.
@ -184,9 +184,9 @@ namespace ImageProcessorCore
public IImageFormat CurrentImageFormat { get; internal set; }
/// <inheritdoc/>
public override IPixelAccessor<TPackedVector> Lock()
public override IPixelAccessor<T> Lock()
{
return Bootstrapper.Instance.GetPixelAccessor<TPackedVector>(this);
return Bootstrapper.Instance.GetPixelAccessor<T>(this);
}
/// <summary>

32
src/ImageProcessorCore/ImageBase.cs

@ -11,21 +11,21 @@ namespace ImageProcessorCore
/// The base class of all images. Encapsulates the basic properties and methods required to manipulate images
/// in different pixel formats.
/// </summary>
/// <typeparam name="TPackedVector">
/// <typeparam name="T">
/// The packed vector pixels format.
/// </typeparam>
public abstract class ImageBase<TPackedVector> : IImageBase<TPackedVector>
where TPackedVector : IPackedVector, new()
public abstract class ImageBase<T> : IImageBase<T>
where T : IPackedVector, new()
{
/// <summary>
/// Initializes a new instance of the <see cref="ImageBase{TPacked}"/> class.
/// Initializes a new instance of the <see cref="ImageBase{T}"/> class.
/// </summary>
protected ImageBase()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageBase{TPacked}"/> class.
/// Initializes a new instance of the <see cref="ImageBase{T}"/> class.
/// </summary>
/// <param name="width">The width of the image in pixels.</param>
/// <param name="height">The height of the image in pixels.</param>
@ -39,19 +39,19 @@ namespace ImageProcessorCore
this.Width = width;
this.Height = height;
this.Pixels = new TPackedVector[width * height];
this.Pixels = new T[width * height];
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageBase{TPacked}"/> class.
/// Initializes a new instance of the <see cref="ImageBase{T}"/> class.
/// </summary>
/// <param name="other">
/// The other <see cref="ImageBase{TPacked}"/> to create this instance from.
/// The other <see cref="ImageBase{T}"/> to create this instance from.
/// </param>
/// <exception cref="ArgumentNullException">
/// Thrown if the given <see cref="ImageBase{TPacked}"/> is null.
/// Thrown if the given <see cref="ImageBase{T}"/> is null.
/// </exception>
protected ImageBase(ImageBase<TPackedVector> other)
protected ImageBase(ImageBase<T> other)
{
Guard.NotNull(other, nameof(other), "Other image cannot be null.");
@ -61,7 +61,7 @@ namespace ImageProcessorCore
this.FrameDelay = other.FrameDelay;
// Copy the pixels.
this.Pixels = new TPackedVector[this.Width * this.Height];
this.Pixels = new T[this.Width * this.Height];
Array.Copy(other.Pixels, this.Pixels, other.Pixels.Length);
}
@ -78,7 +78,7 @@ namespace ImageProcessorCore
/// <summary>
/// Gets the pixels as an array of the given packed pixel format.
/// </summary>
public TPackedVector[] Pixels { get; private set; }
public T[] Pixels { get; private set; }
/// <summary>
/// Gets the width in pixels.
@ -127,7 +127,7 @@ namespace ImageProcessorCore
/// <exception cref="ArgumentException">
/// Thrown if the <paramref name="pixels"/> length is not equal to Width * Height.
/// </exception>
public void SetPixels(int width, int height, TPackedVector[] pixels)
public void SetPixels(int width, int height, T[] pixels)
{
if (width <= 0)
{
@ -164,7 +164,7 @@ namespace ImageProcessorCore
/// <exception cref="ArgumentException">
/// Thrown if the <paramref name="pixels"/> length is not equal to Width * Height.
/// </exception>
public void ClonePixels(int width, int height, TPackedVector[] pixels)
public void ClonePixels(int width, int height, T[] pixels)
{
if (width <= 0)
{
@ -185,7 +185,7 @@ namespace ImageProcessorCore
this.Height = height;
// Copy the pixels.
this.Pixels = new TPackedVector[pixels.Length];
this.Pixels = new T[pixels.Length];
Array.Copy(pixels, this.Pixels, pixels.Length);
}
@ -196,6 +196,6 @@ namespace ImageProcessorCore
/// </remarks>
/// </summary>
/// <returns>The <see cref="IPixelAccessor"/></returns>
public abstract IPixelAccessor<TPackedVector> Lock();
public abstract IPixelAccessor<T> Lock();
}
}

56
src/ImageProcessorCore/ImageExtensions.cs

@ -12,7 +12,7 @@ namespace ImageProcessorCore
using Processors;
/// <summary>
/// Extension methods for the <see cref="Image{TPackedVector}"/> type.
/// Extension methods for the <see cref="Image{T}"/> type.
/// </summary>
public static partial class ImageExtensions
{
@ -57,12 +57,12 @@ namespace ImageProcessorCore
/// Applies the collection of processors to the image.
/// <remarks>This method does not resize the target image.</remarks>
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="processor">The processor to apply to the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/>.</returns>
public static Image<TPackedVector> Process<TPackedVector>(this Image<TPackedVector> source, IImageProcessor processor)
where TPackedVector : IPackedVector, new()
/// <returns>The <see cref="Image{T}"/>.</returns>
public static Image<T> Process<T>(this Image<T> source, IImageProcessor processor)
where T : IPackedVector, new()
{
return Process(source, source.Bounds, processor);
}
@ -71,15 +71,15 @@ namespace ImageProcessorCore
/// Applies the collection of processors to the image.
/// <remarks>This method does not resize the target image.</remarks>
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The image this method extends.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
/// <param name="processor">The processors to apply to the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/>.</returns>
public static Image<TPackedVector> Process<TPackedVector>(this Image<TPackedVector> source, Rectangle sourceRectangle, IImageProcessor processor)
where TPackedVector : IPackedVector, new()
/// <returns>The <see cref="Image{T}"/>.</returns>
public static Image<T> Process<T>(this Image<T> source, Rectangle sourceRectangle, IImageProcessor processor)
where T : IPackedVector, new()
{
return PerformAction(source, true, (sourceImage, targetImage) => processor.Apply(targetImage, sourceImage, sourceRectangle));
}
@ -90,14 +90,14 @@ namespace ImageProcessorCore
/// This method is not chainable.
/// </remarks>
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
/// <param name="sampler">The processor to apply to the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/>.</returns>
public static Image<TPackedVector> Process<TPackedVector>(this Image<TPackedVector> source, int width, int height, IImageSampler sampler)
where TPackedVector : IPackedVector, new()
/// <returns>The <see cref="Image{T}"/>.</returns>
public static Image<T> Process<T>(this Image<T> source, int width, int height, IImageSampler sampler)
where T : IPackedVector, new()
{
return Process(source, width, height, source.Bounds, default(Rectangle), sampler);
}
@ -108,7 +108,7 @@ namespace ImageProcessorCore
/// This method does will resize the target image if the source and target rectangles are different.
/// </remarks>
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
@ -120,9 +120,9 @@ namespace ImageProcessorCore
/// The image is scaled to fit the rectangle.
/// </param>
/// <param name="sampler">The processor to apply to the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/>.</returns>
public static Image<TPackedVector> Process<TPackedVector>(this Image<TPackedVector> source, int width, int height, Rectangle sourceRectangle, Rectangle targetRectangle, IImageSampler sampler)
where TPackedVector : IPackedVector, new()
/// <returns>The <see cref="Image{T}"/>.</returns>
public static Image<T> Process<T>(this Image<T> source, int width, int height, Rectangle sourceRectangle, Rectangle targetRectangle, IImageSampler sampler)
where T : IPackedVector, new()
{
return PerformAction(source, false, (sourceImage, targetImage) => sampler.Apply(targetImage, sourceImage, width, height, targetRectangle, sourceRectangle));
}
@ -130,17 +130,17 @@ namespace ImageProcessorCore
/// <summary>
/// Performs the given action on the source image.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The image to perform the action against.</param>
/// <param name="clone">Whether to clone the image.</param>
/// <param name="action">The <see cref="Action"/> to perform against the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/>.</returns>
private static Image<TPackedVector> PerformAction<TPackedVector>(Image<TPackedVector> source, bool clone, Action<ImageBase<TPackedVector>, ImageBase<TPackedVector>> action)
where TPackedVector : IPackedVector, new()
/// <returns>The <see cref="Image{T}"/>.</returns>
private static Image<T> PerformAction<T>(Image<T> source, bool clone, Action<ImageBase<T>, ImageBase<T>> action)
where T : IPackedVector, new()
{
Image<TPackedVector> transformedImage = clone
? new Image<TPackedVector>(source)
: new Image<TPackedVector>
Image<T> transformedImage = clone
? new Image<T>(source)
: new Image<T>
{
// Several properties require copying
// TODO: Check why we need to set these?
@ -154,10 +154,10 @@ namespace ImageProcessorCore
for (int i = 0; i < source.Frames.Count; i++)
{
ImageFrame<TPackedVector> sourceFrame = source.Frames[i];
ImageFrame<TPackedVector> tranformedFrame = clone
? new ImageFrame<TPackedVector>(sourceFrame)
: new ImageFrame<TPackedVector> { FrameDelay = sourceFrame.FrameDelay };
ImageFrame<T> sourceFrame = source.Frames[i];
ImageFrame<T> tranformedFrame = clone
? new ImageFrame<T>(sourceFrame)
: new ImageFrame<T> { FrameDelay = sourceFrame.FrameDelay };
action(sourceFrame, tranformedFrame);

16
src/ImageProcessorCore/ImageFrame.cs

@ -8,34 +8,34 @@ namespace ImageProcessorCore
/// <summary>
/// Represents a single frame in a animation.
/// </summary>
/// <typeparam name="TPackedVector">
/// <typeparam name="T">
/// The packed vector containing pixel information.
/// </typeparam>
public class ImageFrame<TPackedVector> : ImageBase<TPackedVector>
where TPackedVector : IPackedVector, new()
public class ImageFrame<T> : ImageBase<T>
where T : IPackedVector, new()
{
/// <summary>
/// Initializes a new instance of the <see cref="ImageFrame{TPackedVector}"/> class.
/// Initializes a new instance of the <see cref="ImageFrame{T}"/> class.
/// </summary>
public ImageFrame()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ImageFrame{TPackedVector}"/> class.
/// Initializes a new instance of the <see cref="ImageFrame{T}"/> class.
/// </summary>
/// <param name="frame">
/// The frame to create the frame from.
/// </param>
public ImageFrame(ImageFrame<TPackedVector> frame)
public ImageFrame(ImageFrame<T> frame)
: base(frame)
{
}
/// <inheritdoc />
public override IPixelAccessor<TPackedVector> Lock()
public override IPixelAccessor<T> Lock()
{
return Bootstrapper.Instance.GetPixelAccessor<TPackedVector>(this);
return Bootstrapper.Instance.GetPixelAccessor<T>(this);
}
}
}

28
src/ImageProcessorCore/ImageProcessor.cs

@ -27,8 +27,8 @@ namespace ImageProcessorCore.Processors
private int totalRows;
/// <inheritdoc/>
public void Apply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, Rectangle sourceRectangle)
where TPackedVector : IPackedVector, new()
public void Apply<T>(ImageBase<T> target, ImageBase<T> source, Rectangle sourceRectangle)
where T : IPackedVector, new()
{
try
{
@ -49,12 +49,12 @@ namespace ImageProcessorCore.Processors
}
/// <inheritdoc/>
public void Apply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, int width, int height, Rectangle targetRectangle = default(Rectangle), Rectangle sourceRectangle = default(Rectangle))
where TPackedVector : IPackedVector, new()
public void Apply<T>(ImageBase<T> target, ImageBase<T> source, int width, int height, Rectangle targetRectangle = default(Rectangle), Rectangle sourceRectangle = default(Rectangle))
where T : IPackedVector, new()
{
try
{
TPackedVector[] pixels = new TPackedVector[width * height];
T[] pixels = new T[width * height];
target.SetPixels(width, height, pixels);
// Ensure we always have bounds.
@ -95,16 +95,16 @@ namespace ImageProcessorCore.Processors
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
protected virtual void OnApply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, Rectangle targetRectangle, Rectangle sourceRectangle)
where TPackedVector : IPackedVector, new()
protected virtual void OnApply<T>(ImageBase<T> target, ImageBase<T> source, Rectangle targetRectangle, Rectangle sourceRectangle)
where T : IPackedVector, new()
{
}
/// <summary>
/// Applies the process to the specified portion of the specified <see cref="ImageBase{TPackedVector}"/> at the specified location
/// Applies the process to the specified portion of the specified <see cref="ImageBase{T}"/> at the specified location
/// and with the specified size.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="target">Target image to apply the process to.</param>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="targetRectangle">
@ -120,13 +120,13 @@ namespace ImageProcessorCore.Processors
/// The method keeps the source image unchanged and returns the
/// the result of image process as new image.
/// </remarks>
protected abstract void Apply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
where TPackedVector : IPackedVector, new();
protected abstract void Apply<T>(ImageBase<T> target, ImageBase<T> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
where T : IPackedVector, new();
/// <summary>
/// This method is called after the process is applied to prepare the processor.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="target">Target image to apply the process to.</param>
/// <param name="source">The source image. Cannot be null.</param>
/// <param name="targetRectangle">
@ -136,8 +136,8 @@ namespace ImageProcessorCore.Processors
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// </param>
protected virtual void AfterApply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, Rectangle targetRectangle, Rectangle sourceRectangle)
where TPackedVector : IPackedVector, new()
protected virtual void AfterApply<T>(ImageBase<T> target, ImageBase<T> source, Rectangle targetRectangle, Rectangle sourceRectangle)
where T : IPackedVector, new()
{
}

8
src/ImageProcessorCore/PackedVector/IPackedVector.cs

@ -11,17 +11,17 @@ namespace ImageProcessorCore
/// An interface that converts packed vector types to and from <see cref="Vector4"/> values,
/// allowing multiple encodings to be manipulated in a generic way.
/// </summary>
/// <typeparam name="TPacked">
/// <typeparam name="T">
/// The type of object representing the packed value.
/// </typeparam>
public interface IPackedVector<TPacked> : IPackedVector
where TPacked : struct
public interface IPackedVector<T> : IPackedVector
where T : struct
{
/// <summary>
/// Gets or sets the packed representation of the value.
/// Typically packed in least to greatest significance order.
/// </summary>
TPacked PackedValue { get; set; }
T PackedValue { get; set; }
}
/// <summary>

8
src/ImageProcessorCore/PixelAccessor/IPixelAccessor.cs

@ -10,8 +10,8 @@ namespace ImageProcessorCore
/// <summary>
/// Encapsulates properties to provides per-pixel access to an images pixels.
/// </summary>
public interface IPixelAccessor<TPackedVector> : IPixelAccessor
where TPackedVector : IPackedVector, new()
public interface IPixelAccessor<T> : IPixelAccessor
where T : IPackedVector, new()
{
/// <summary>
/// Gets or sets the pixel at the specified position.
@ -24,8 +24,8 @@ namespace ImageProcessorCore
/// The y-coordinate of the pixel. Must be greater
/// than zero and smaller than the width of the pixel.
/// </param>
/// <returns>The <see cref="TPackedVector"/> at the specified position.</returns>
TPackedVector this[int x, int y]
/// <returns>The <see cref="T"/> at the specified position.</returns>
T this[int x, int y]
{
get;
set;

36
src/ImageProcessorCore/Samplers/Options/ResizeHelper.cs

@ -17,14 +17,14 @@ namespace ImageProcessorCore
/// <summary>
/// Calculates the target location and bounds to perform the resize operation against.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The source image.</param>
/// <param name="options">The resize options.</param>
/// <returns>
/// The <see cref="Rectangle"/>.
/// </returns>
public static Rectangle CalculateTargetLocationAndBounds<TPackedVector>(ImageBase<TPackedVector> source, ResizeOptions options)
where TPackedVector : IPackedVector, new()
public static Rectangle CalculateTargetLocationAndBounds<T>(ImageBase<T> source, ResizeOptions options)
where T : IPackedVector, new()
{
switch (options.Mode)
{
@ -48,14 +48,14 @@ namespace ImageProcessorCore
/// <summary>
/// Calculates the target rectangle for crop mode.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The source image.</param>
/// <param name="options">The resize options.</param>
/// <returns>
/// The <see cref="Rectangle"/>.
/// </returns>
private static Rectangle CalculateCropRectangle<TPackedVector>(ImageBase<TPackedVector> source, ResizeOptions options)
where TPackedVector : IPackedVector, new()
private static Rectangle CalculateCropRectangle<T>(ImageBase<T> source, ResizeOptions options)
where T : IPackedVector, new()
{
int width = options.Size.Width;
int height = options.Size.Height;
@ -167,14 +167,14 @@ namespace ImageProcessorCore
/// <summary>
/// Calculates the target rectangle for pad mode.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The source image.</param>
/// <param name="options">The resize options.</param>
/// <returns>
/// The <see cref="Rectangle"/>.
/// </returns>
private static Rectangle CalculatePadRectangle<TPackedVector>(ImageBase<TPackedVector> source, ResizeOptions options)
where TPackedVector : IPackedVector, new()
private static Rectangle CalculatePadRectangle<T>(ImageBase<T> source, ResizeOptions options)
where T : IPackedVector, new()
{
int width = options.Size.Width;
int height = options.Size.Height;
@ -248,14 +248,14 @@ namespace ImageProcessorCore
/// <summary>
/// Calculates the target rectangle for box pad mode.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The source image.</param>
/// <param name="options">The resize options.</param>
/// <returns>
/// The <see cref="Rectangle"/>.
/// </returns>
private static Rectangle CalculateBoxPadRectangle<TPackedVector>(ImageBase<TPackedVector> source, ResizeOptions options)
where TPackedVector : IPackedVector, new()
private static Rectangle CalculateBoxPadRectangle<T>(ImageBase<T> source, ResizeOptions options)
where T : IPackedVector, new()
{
int width = options.Size.Width;
int height = options.Size.Height;
@ -335,14 +335,14 @@ namespace ImageProcessorCore
/// <summary>
/// Calculates the target rectangle for max mode.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The source image.</param>
/// <param name="options">The resize options.</param>
/// <returns>
/// The <see cref="Rectangle"/>.
/// </returns>
private static Rectangle CalculateMaxRectangle<TPackedVector>(ImageBase<TPackedVector> source, ResizeOptions options)
where TPackedVector : IPackedVector, new()
private static Rectangle CalculateMaxRectangle<T>(ImageBase<T> source, ResizeOptions options)
where T : IPackedVector, new()
{
int width = options.Size.Width;
int height = options.Size.Height;
@ -376,14 +376,14 @@ namespace ImageProcessorCore
/// <summary>
/// Calculates the target rectangle for min mode.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The source image.</param>
/// <param name="options">The resize options.</param>
/// <returns>
/// The <see cref="Rectangle"/>.
/// </returns>
private static Rectangle CalculateMinRectangle<TPackedVector>(ImageBase<TPackedVector> source, ResizeOptions options)
where TPackedVector : IPackedVector, new()
private static Rectangle CalculateMinRectangle<T>(ImageBase<T> source, ResizeOptions options)
where T : IPackedVector, new()
{
int width = options.Size.Width;
int height = options.Size.Height;

23
src/ImageProcessorCore/Samplers/Processors/ResizeProcessor.cs

@ -43,7 +43,7 @@ namespace ImageProcessorCore.Processors
protected Weights[] VerticalWeights { get; set; }
/// <inheritdoc/>
protected override void OnApply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, Rectangle targetRectangle, Rectangle sourceRectangle)
protected override void OnApply<T>(ImageBase<T> target, ImageBase<T> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{
if (!(this.Sampler is NearestNeighborResampler))
{
@ -53,7 +53,7 @@ namespace ImageProcessorCore.Processors
}
/// <inheritdoc/>
protected override void Apply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
protected override void Apply<T>(ImageBase<T> target, ImageBase<T> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{
// Jump out, we'll deal with that later.
if (source.Bounds == target.Bounds && sourceRectangle == targetRectangle)
@ -78,8 +78,8 @@ namespace ImageProcessorCore.Processors
float widthFactor = sourceRectangle.Width / (float)targetRectangle.Width;
float heightFactor = sourceRectangle.Height / (float)targetRectangle.Height;
using (IPixelAccessor<TPackedVector> sourcePixels = source.Lock())
using (IPixelAccessor<TPackedVector> targetPixels = target.Lock())
using (IPixelAccessor<T> sourcePixels = source.Lock())
using (IPixelAccessor<T> targetPixels = target.Lock())
{
Parallel.For(
startY,
@ -114,10 +114,10 @@ namespace ImageProcessorCore.Processors
// A 2-pass 1D algorithm appears to be faster than splitting a 1-pass 2D algorithm
// First process the columns. Since we are not using multiple threads startY and endY
// are the upper and lower bounds of the source rectangle.
Image<TPackedVector> firstPass = new Image<TPackedVector>(target.Width, source.Height);
using (IPixelAccessor<TPackedVector> sourcePixels = source.Lock())
using (IPixelAccessor<TPackedVector> firstPassPixels = firstPass.Lock())
using (IPixelAccessor<TPackedVector> targetPixels = target.Lock())
Image<T> firstPass = new Image<T>(target.Width, source.Height);
using (IPixelAccessor<T> sourcePixels = source.Lock())
using (IPixelAccessor<T> firstPassPixels = firstPass.Lock())
using (IPixelAccessor<T> targetPixels = target.Lock())
{
Parallel.For(
0,
@ -163,7 +163,6 @@ namespace ImageProcessorCore.Processors
//Color sourceColor = compand
// ? Color.Expand(sourcePixels[originX, y])
// : sourcePixels[originX, y];
destination += sourceColor * xw.Value;
}
@ -171,7 +170,7 @@ namespace ImageProcessorCore.Processors
//{
// destination = Color.Compress(destination);
//}
TPackedVector packed = new TPackedVector();
T packed = new T();
packed.PackVector(destination);
firstPassPixels[x, y] = packed;
@ -213,7 +212,7 @@ namespace ImageProcessorCore.Processors
// destination = Color.Compress(destination);
//}
TPackedVector packed = new TPackedVector();
T packed = new T();
packed.PackVector(destination);
targetPixels[x, y] = packed;
@ -227,7 +226,7 @@ namespace ImageProcessorCore.Processors
}
/// <inheritdoc/>
protected override void AfterApply<TPackedVector>(ImageBase<TPackedVector> target, ImageBase<TPackedVector> source, Rectangle targetRectangle, Rectangle sourceRectangle)
protected override void AfterApply<T>(ImageBase<T> target, ImageBase<T> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{
// Copy the pixels over.
if (source.Bounds == target.Bounds && sourceRectangle == targetRectangle)

40
src/ImageProcessorCore/Samplers/Resize.cs

@ -15,14 +15,14 @@ namespace ImageProcessorCore
/// <summary>
/// Resizes an image in accordance with the given <see cref="ResizeOptions"/>.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="options">The resize options.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/></returns>
/// <returns>The <see cref="Image{T}"/></returns>
/// <remarks>Passing zero for one of height or width within the resize options will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPackedVector> Resize<TPackedVector>(this Image<TPackedVector> source, ResizeOptions options, ProgressEventHandler progressHandler = null)
where TPackedVector : IPackedVector, new()
public static Image<T> Resize<T>(this Image<T> source, ResizeOptions options, ProgressEventHandler progressHandler = null)
where T : IPackedVector, new()
{
// Ensure size is populated across both dimensions.
if (options.Size.Width == 0 && options.Size.Height > 0)
@ -43,15 +43,15 @@ namespace ImageProcessorCore
/// <summary>
/// Resizes an image to the given width and height.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/></returns>
/// <returns>The <see cref="Image{T}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPackedVector> Resize<TPackedVector>(this Image<TPackedVector> source, int width, int height, ProgressEventHandler progressHandler = null)
where TPackedVector : IPackedVector, new()
public static Image<T> Resize<T>(this Image<T> source, int width, int height, ProgressEventHandler progressHandler = null)
where T : IPackedVector, new()
{
return Resize(source, width, height, new BicubicResampler(), false, progressHandler);
}
@ -59,16 +59,16 @@ namespace ImageProcessorCore
/// <summary>
/// Resizes an image to the given width and height.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
/// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/></returns>
/// <returns>The <see cref="Image{T}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPackedVector> Resize<TPackedVector>(this Image<TPackedVector> source, int width, int height, bool compand, ProgressEventHandler progressHandler = null)
where TPackedVector : IPackedVector, new()
public static Image<T> Resize<T>(this Image<T> source, int width, int height, bool compand, ProgressEventHandler progressHandler = null)
where T : IPackedVector, new()
{
return Resize(source, width, height, new BicubicResampler(), compand, progressHandler);
}
@ -76,17 +76,17 @@ namespace ImageProcessorCore
/// <summary>
/// Resizes an image to the given width and height with the given sampler.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
/// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param>
/// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/></returns>
/// <returns>The <see cref="Image{T}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPackedVector> Resize<TPackedVector>(this Image<TPackedVector> source, int width, int height, IResampler sampler, bool compand, ProgressEventHandler progressHandler = null)
where TPackedVector : IPackedVector, new()
public static Image<T> Resize<T>(this Image<T> source, int width, int height, IResampler sampler, bool compand, ProgressEventHandler progressHandler = null)
where T : IPackedVector, new()
{
return Resize(source, width, height, sampler, source.Bounds, new Rectangle(0, 0, width, height), compand, progressHandler);
}
@ -95,7 +95,7 @@ namespace ImageProcessorCore
/// Resizes an image to the given width and height with the given sampler and
/// source rectangle.
/// </summary>
/// <typeparam name="TPackedVector">The type of pixels contained within the image.</typeparam>
/// <typeparam name="T">The type of pixels contained within the image.</typeparam>
/// <param name="source">The image to resize.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
@ -108,10 +108,10 @@ namespace ImageProcessorCore
/// </param>
/// <param name="compand">Whether to compress and expand the image color-space to gamma correct the image during processing.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{TPackedVector}"/></returns>
/// <returns>The <see cref="Image{T}"/></returns>
/// <remarks>Passing zero for one of height or width will automatically preserve the aspect ratio of the original image</remarks>
public static Image<TPackedVector> Resize<TPackedVector>(this Image<TPackedVector> source, int width, int height, IResampler sampler, Rectangle sourceRectangle, Rectangle targetRectangle, bool compand = false, ProgressEventHandler progressHandler = null)
where TPackedVector : IPackedVector, new()
public static Image<T> Resize<T>(this Image<T> source, int width, int height, IResampler sampler, Rectangle sourceRectangle, Rectangle targetRectangle, bool compand = false, ProgressEventHandler progressHandler = null)
where T : IPackedVector, new()
{
if (width == 0 && height > 0)
{

Loading…
Cancel
Save