Browse Source

Use PixelAcessor<TColor, TPacked> #457

Former-commit-id: 38a4a37351b55ae4027064c96983460a440140b8
Former-commit-id: db9a4f0f2ce7930ae633e3a7ceee0fab7f5db464
Former-commit-id: 34289d7967ca5c8cdbb0949ed8bf0f65586fa297
af/merge-core
James Jackson-South 10 years ago
parent
commit
7c624d0b27
  1. 2
      README.md
  2. 48
      src/ImageProcessorCore/Bootstrapper.cs
  3. 8
      src/ImageProcessorCore/Colors/Colorspaces/IAlmostEquatable.cs
  4. 12
      src/ImageProcessorCore/Colors/PackedVector/IPackedVector.cs
  5. 2
      src/ImageProcessorCore/Common/Extensions/ByteExtensions.cs
  6. 4
      src/ImageProcessorCore/Common/Helpers/Guard.cs
  7. 22
      src/ImageProcessorCore/Common/Helpers/ImageMaths.cs
  8. 24
      src/ImageProcessorCore/Filters/Alpha.cs
  9. 16
      src/ImageProcessorCore/Filters/BackgroundColor.cs
  10. 28
      src/ImageProcessorCore/Filters/BinaryThreshold.cs
  11. 28
      src/ImageProcessorCore/Filters/BlackWhite.cs
  12. 26
      src/ImageProcessorCore/Filters/Blend.cs
  13. 28
      src/ImageProcessorCore/Filters/BoxBlur.cs
  14. 26
      src/ImageProcessorCore/Filters/Brightness.cs
  15. 44
      src/ImageProcessorCore/Filters/ColorBlindness.cs
  16. 28
      src/ImageProcessorCore/Filters/Contrast.cs
  17. 102
      src/ImageProcessorCore/Filters/DetectEdges.cs
  18. 72
      src/ImageProcessorCore/Filters/Glow.cs
  19. 32
      src/ImageProcessorCore/Filters/Grayscale.cs
  20. 28
      src/ImageProcessorCore/Filters/GuassianBlur.cs
  21. 28
      src/ImageProcessorCore/Filters/GuassianSharpen.cs
  22. 28
      src/ImageProcessorCore/Filters/Hue.cs
  23. 14
      src/ImageProcessorCore/Filters/Invert.cs
  24. 28
      src/ImageProcessorCore/Filters/Kodachrome.cs
  25. 28
      src/ImageProcessorCore/Filters/Lomograph.cs
  26. 24
      src/ImageProcessorCore/Filters/Pixelate.cs
  27. 28
      src/ImageProcessorCore/Filters/Polaroid.cs
  28. 22
      src/ImageProcessorCore/Filters/Processors/AlphaProcessor.cs
  29. 20
      src/ImageProcessorCore/Filters/Processors/BackgroundColorProcessor.cs
  30. 40
      src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs
  31. 26
      src/ImageProcessorCore/Filters/Processors/BlendProcessor.cs
  32. 22
      src/ImageProcessorCore/Filters/Processors/BrightnessProcessor.cs
  33. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/BlackWhiteProcessor.cs
  34. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs
  35. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs
  36. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs
  37. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs
  38. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs
  39. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs
  40. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs
  41. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs
  42. 20
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs
  43. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/GrayscaleBt601Processor.cs
  44. 6
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/GrayscaleBt709Processor.cs
  45. 12
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/HueProcessor.cs
  46. 6
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/IColorMatrixFilter.cs
  47. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/KodachromeProcessor.cs
  48. 16
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/LomographProcessor.cs
  49. 20
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/PolaroidProcessor.cs
  50. 12
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/SaturationProcessor.cs
  51. 10
      src/ImageProcessorCore/Filters/Processors/ColorMatrix/SepiaProcessor.cs
  52. 20
      src/ImageProcessorCore/Filters/Processors/ContrastProcessor.cs
  53. 12
      src/ImageProcessorCore/Filters/Processors/Convolution/BoxBlurProcessor.cs
  54. 18
      src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2DFilter.cs
  55. 24
      src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2PassFilter.cs
  56. 14
      src/ImageProcessorCore/Filters/Processors/Convolution/ConvolutionFilter.cs
  57. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs
  58. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs
  59. 6
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs
  60. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs
  61. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs
  62. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs
  63. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs
  64. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs
  65. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs
  66. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs
  67. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs
  68. 10
      src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs
  69. 12
      src/ImageProcessorCore/Filters/Processors/Convolution/GuassianBlurProcessor.cs
  70. 12
      src/ImageProcessorCore/Filters/Processors/Convolution/GuassianSharpenProcessor.cs
  71. 28
      src/ImageProcessorCore/Filters/Processors/GlowProcessor.cs
  72. 20
      src/ImageProcessorCore/Filters/Processors/InvertProcessor.cs
  73. 22
      src/ImageProcessorCore/Filters/Processors/PixelateProcessor.cs
  74. 28
      src/ImageProcessorCore/Filters/Processors/VignetteProcessor.cs
  75. 28
      src/ImageProcessorCore/Filters/Saturation.cs
  76. 24
      src/ImageProcessorCore/Filters/Sepia.cs
  77. 72
      src/ImageProcessorCore/Filters/Vignette.cs
  78. 6
      src/ImageProcessorCore/Formats/Bmp/BmpDecoder.cs
  79. 78
      src/ImageProcessorCore/Formats/Bmp/BmpDecoderCore.cs
  80. 6
      src/ImageProcessorCore/Formats/Bmp/BmpEncoder.cs
  81. 48
      src/ImageProcessorCore/Formats/Bmp/BmpEncoderCore.cs
  82. 8
      src/ImageProcessorCore/Formats/Gif/GifDecoder.cs
  83. 32
      src/ImageProcessorCore/Formats/Gif/GifDecoderCore.cs
  84. 6
      src/ImageProcessorCore/Formats/Gif/GifEncoder.cs
  85. 82
      src/ImageProcessorCore/Formats/Gif/GifEncoderCore.cs
  86. 2
      src/ImageProcessorCore/Formats/Gif/LzwDecoder.cs
  87. 2
      src/ImageProcessorCore/Formats/Gif/LzwEncoder.cs
  88. 2
      src/ImageProcessorCore/Formats/Gif/Sections/GifGraphicsControlExtension.cs
  89. 14
      src/ImageProcessorCore/Formats/IImageDecoder.cs
  90. 10
      src/ImageProcessorCore/Formats/IImageEncoder.cs
  91. 6
      src/ImageProcessorCore/Formats/Jpg/JpegDecoder.cs
  92. 2
      src/ImageProcessorCore/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id
  93. 6
      src/ImageProcessorCore/Formats/Jpg/JpegEncoder.cs
  94. 38
      src/ImageProcessorCore/Formats/Jpg/JpegEncoderCore.cs
  95. 2
      src/ImageProcessorCore/Formats/Png/Filters/UpFilter.cs
  96. 10
      src/ImageProcessorCore/Formats/Png/PngDecoder.cs
  97. 80
      src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs
  98. 6
      src/ImageProcessorCore/Formats/Png/PngEncoder.cs
  99. 78
      src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs
  100. 2
      src/ImageProcessorCore/IO/EndianBinaryWriter.cs

2
README.md

@ -182,7 +182,7 @@ Individual processors can be initialised and apply processing against images. Th
new Brightness(50).Apply(sourceImage, targetImage, sourceImage.Bounds); new Brightness(50).Apply(sourceImage, targetImage, sourceImage.Bounds);
``` ```
For advanced usage the `Image<T,TP>` class is available allowing developers to implement their own color models in the same manner as Microsoft XNA Game Studio and MonoGame For advanced usage the `Image<TColor, TPacked>` class is available allowing developers to implement their own color models in the same manner as Microsoft XNA Game Studio and MonoGame
All in all this should allow image processing to be much more accessible to developers which has always been my goal from the start. All in all this should allow image processing to be much more accessible to developers which has always been my goal from the start.

48
src/ImageProcessorCore/Bootstrapper.cs

@ -29,8 +29,6 @@ namespace ImageProcessorCore
/// </summary> /// </summary>
private readonly List<IImageFormat> imageFormats; private readonly List<IImageFormat> imageFormats;
private readonly Dictionary<Type, Func<IImageBase, IPixelAccessor>> pixelAccessors;
/// <summary> /// <summary>
/// Prevents a default instance of the <see cref="Bootstrapper"/> class from being created. /// Prevents a default instance of the <see cref="Bootstrapper"/> class from being created.
/// </summary> /// </summary>
@ -43,11 +41,6 @@ namespace ImageProcessorCore
new PngFormat(), new PngFormat(),
new GifFormat() new GifFormat()
}; };
this.pixelAccessors = new Dictionary<Type, Func<IImageBase, IPixelAccessor>>
{
{ typeof(Color), i=> new ColorPixelAccessor(i) }
};
} }
/// <summary> /// <summary>
@ -61,12 +54,6 @@ namespace ImageProcessorCore
public IReadOnlyCollection<IImageFormat> ImageFormats => public IReadOnlyCollection<IImageFormat> ImageFormats =>
new ReadOnlyCollection<IImageFormat>(this.imageFormats); new ReadOnlyCollection<IImageFormat>(this.imageFormats);
/// <summary>
/// Gets the collection of supported pixel accessors
/// </summary>
public IReadOnlyDictionary<Type, Func<IImageBase, IPixelAccessor>> PixelAccessors =>
new ReadOnlyDictionary<Type, Func<IImageBase, IPixelAccessor>>(this.pixelAccessors);
/// <summary> /// <summary>
/// Gets or sets the global parallel options for processing tasks in parallel. /// Gets or sets the global parallel options for processing tasks in parallel.
/// </summary> /// </summary>
@ -80,40 +67,5 @@ namespace ImageProcessorCore
{ {
this.imageFormats.Add(format); this.imageFormats.Add(format);
} }
/// <summary>
/// Adds a pixel accessor for the given pixel format.
/// </summary>
/// <param name="packedType">The packed format type, must implement <see cref="IPackedVector"/></param>
/// <param name="initializer">The function to return a new instance of the pixel accessor.</param>
public void AddPixelAccessor(Type packedType, Func<IImageBase, IPixelAccessor> initializer)
{
if (!typeof(IPackedVector).GetTypeInfo().IsAssignableFrom(packedType.GetTypeInfo()))
{
throw new ArgumentException($"Type {packedType} must implement {nameof(IPackedVector)}");
}
this.pixelAccessors.Add(packedType, initializer);
}
/// <summary>
/// Gets an instance of the correct <see cref="IPixelAccessor"/> for the packed vector.
/// </summary>
/// <typeparam name="T">The type of pixel data.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="image">The image</param>
/// <returns>The <see cref="IPixelAccessor"/></returns>
public IPixelAccessor<T, TP> GetPixelAccessor<T, TP>(IImageBase image)
where T : IPackedVector<TP>
where TP : struct
{
Type packed = typeof(T);
if (this.pixelAccessors.ContainsKey(packed))
{
return (IPixelAccessor<T, TP>)this.pixelAccessors[packed].Invoke(image);
}
throw new NotSupportedException($"PixelAccessor cannot be loaded for {packed}:");
}
} }
} }

8
src/ImageProcessorCore/Colors/Colorspaces/IAlmostEquatable.cs

@ -11,9 +11,9 @@ namespace ImageProcessorCore
/// Defines a generalized method that a value type or class implements to create /// Defines a generalized method that a value type or class implements to create
/// a type-specific method for determining approximate equality of instances. /// a type-specific method for determining approximate equality of instances.
/// </summary> /// </summary>
/// <typeparam name="T">The type of objects to compare.</typeparam> /// <typeparam name="TColor">The type of objects to compare.</typeparam>
/// <typeparam name="TP">The object specifying the type to specify precision with.</typeparam> /// <typeparam name="TPacked">The object specifying the type to specify precision with.</typeparam>
public interface IAlmostEquatable<T, TP> where TP : struct, IComparable<TP> public interface IAlmostEquatable<TColor, TPacked> where TPacked : struct, IComparable<TPacked>
{ {
/// <summary> /// <summary>
/// Indicates whether the current object is equal to another object of the same type /// Indicates whether the current object is equal to another object of the same type
@ -24,6 +24,6 @@ namespace ImageProcessorCore
/// <returns> /// <returns>
/// true if the current object is equal to the other parameter; otherwise, false. /// true if the current object is equal to the other parameter; otherwise, false.
/// </returns> /// </returns>
bool AlmostEquals(T other, TP precision); bool AlmostEquals(TColor other, TPacked precision);
} }
} }

12
src/ImageProcessorCore/Colors/PackedVector/IPackedVector.cs

@ -11,25 +11,25 @@ namespace ImageProcessorCore
/// An interface that converts packed vector types to and from <see cref="Vector4"/> values, /// An interface that converts packed vector types to and from <see cref="Vector4"/> values,
/// allowing multiple encodings to be manipulated in a generic manner. /// allowing multiple encodings to be manipulated in a generic manner.
/// </summary> /// </summary>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public interface IPackedVector<TP> : IPackedVector public interface IPackedVector<TPacked> : IPackedVector
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Directly gets the packed representation of the packed vector. /// Directly gets the packed representation of the packed vector.
/// Typically packed in least to greatest significance order. /// Typically packed in least to greatest significance order.
/// </summary> /// </summary>
/// <returns> /// <returns>
/// The <see cref="TP"/>. /// The <see cref="TPacked"/>.
/// </returns> /// </returns>
TP GetPackedValue(); TPacked GetPackedValue();
/// <summary> /// <summary>
/// Directly sets the packed representation of the packed vector. /// Directly sets the packed representation of the packed vector.
/// Typically packed in least to greatest significance order. /// Typically packed in least to greatest significance order.
/// </summary> /// </summary>
/// <param name="value">The packed value.</param> /// <param name="value">The packed value.</param>
void SetPackedValue(TP value); void SetPackedValue(TPacked value);
} }
/// <summary> /// <summary>

2
src/ImageProcessorCore/Common/Extensions/ByteExtensions.cs

@ -19,7 +19,7 @@ namespace ImageProcessorCore
/// <param name="bytes">The bytes to convert from. Cannot be null.</param> /// <param name="bytes">The bytes to convert from. Cannot be null.</param>
/// <param name="bits">The number of bits per value.</param> /// <param name="bits">The number of bits per value.</param>
/// <returns>The resulting <see cref="T:byte[]"/> array. Is never null.</returns> /// <returns>The resulting <see cref="T:byte[]"/> array. Is never null.</returns>
/// <exception cref="ArgumentNullException"><paramref name="bytes"/> is null.</exception> /// <exception cref="System.ArgumentNullException"><paramref name="bytes"/> is null.</exception>
/// <exception cref="ArgumentException"><paramref name="bits"/> is less than or equals than zero.</exception> /// <exception cref="ArgumentException"><paramref name="bits"/> is less than or equals than zero.</exception>
public static byte[] ToArrayByBitsLength(this byte[] bytes, int bits) public static byte[] ToArrayByBitsLength(this byte[] bytes, int bits)
{ {

4
src/ImageProcessorCore/Common/Helpers/Guard.cs

@ -35,7 +35,7 @@ namespace ImageProcessorCore
/// <param name="message"> /// <param name="message">
/// The error message, if any to add to the exception. /// The error message, if any to add to the exception.
/// </param> /// </param>
/// <exception cref="ArgumentNullException"> /// <exception cref="System.ArgumentNullException">
/// <paramref name="target"/> is null /// <paramref name="target"/> is null
/// </exception> /// </exception>
public static void NotNull(object target, string parameterName, string message = "") public static void NotNull(object target, string parameterName, string message = "")
@ -58,7 +58,7 @@ namespace ImageProcessorCore
/// </summary> /// </summary>
/// <param name="target">The target string, which should be checked against being null or empty.</param> /// <param name="target">The target string, which should be checked against being null or empty.</param>
/// <param name="parameterName">Name of the parameter.</param> /// <param name="parameterName">Name of the parameter.</param>
/// <exception cref="ArgumentNullException"> /// <exception cref="System.ArgumentNullException">
/// <paramref name="target"/> is null. /// <paramref name="target"/> is null.
/// </exception> /// </exception>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">

22
src/ImageProcessorCore/Common/Helpers/ImageMaths.cs

@ -156,17 +156,17 @@ namespace ImageProcessorCore
/// Finds the bounding rectangle based on the first instance of any color component other /// Finds the bounding rectangle based on the first instance of any color component other
/// than the given one. /// than the given one.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="bitmap">The <see cref="Image"/> to search within.</param> /// <param name="bitmap">The <see cref="Image"/> to search within.</param>
/// <param name="componentValue">The color component value to remove.</param> /// <param name="componentValue">The color component value to remove.</param>
/// <param name="channel">The <see cref="RgbaComponent"/> channel to test against.</param> /// <param name="channel">The <see cref="RgbaComponent"/> channel to test against.</param>
/// <returns> /// <returns>
/// The <see cref="Rectangle"/>. /// The <see cref="Rectangle"/>.
/// </returns> /// </returns>
public static Rectangle GetFilteredBoundingRectangle<T, TP>(ImageBase<T, TP> bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B) public static Rectangle GetFilteredBoundingRectangle<TColor, TPacked>(ImageBase<TColor, TPacked> bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
const float Epsilon = .00001f; const float Epsilon = .00001f;
int width = bitmap.Width; int width = bitmap.Width;
@ -174,7 +174,7 @@ namespace ImageProcessorCore
Point topLeft = new Point(); Point topLeft = new Point();
Point bottomRight = new Point(); Point bottomRight = new Point();
Func<IPixelAccessor<T, TP>, int, int, float, bool> delegateFunc; Func<PixelAccessor<TColor, TPacked>, int, int, float, bool> delegateFunc;
// Determine which channel to check against // Determine which channel to check against
switch (channel) switch (channel)
@ -196,7 +196,7 @@ namespace ImageProcessorCore
break; break;
} }
Func<IPixelAccessor<T, TP>, int> getMinY = pixels => Func<PixelAccessor<TColor, TPacked>, int> getMinY = pixels =>
{ {
for (int y = 0; y < height; y++) for (int y = 0; y < height; y++)
{ {
@ -212,7 +212,7 @@ namespace ImageProcessorCore
return 0; return 0;
}; };
Func<IPixelAccessor<T, TP>, int> getMaxY = pixels => Func<PixelAccessor<TColor, TPacked>, int> getMaxY = pixels =>
{ {
for (int y = height - 1; y > -1; y--) for (int y = height - 1; y > -1; y--)
{ {
@ -228,7 +228,7 @@ namespace ImageProcessorCore
return height; return height;
}; };
Func<IPixelAccessor<T, TP>, int> getMinX = pixels => Func<PixelAccessor<TColor, TPacked>, int> getMinX = pixels =>
{ {
for (int x = 0; x < width; x++) for (int x = 0; x < width; x++)
{ {
@ -244,7 +244,7 @@ namespace ImageProcessorCore
return 0; return 0;
}; };
Func<IPixelAccessor<T, TP>, int> getMaxX = pixels => Func<PixelAccessor<TColor, TPacked>, int> getMaxX = pixels =>
{ {
for (int x = width - 1; x > -1; x--) for (int x = width - 1; x > -1; x--)
{ {
@ -260,7 +260,7 @@ namespace ImageProcessorCore
return height; return height;
}; };
using (IPixelAccessor<T, TP> bitmapPixels = bitmap.Lock()) using (PixelAccessor<TColor, TPacked> bitmapPixels = bitmap.Lock())
{ {
topLeft.Y = getMinY(bitmapPixels); topLeft.Y = getMinY(bitmapPixels);
topLeft.X = getMinX(bitmapPixels); topLeft.X = getMinX(bitmapPixels);

24
src/ImageProcessorCore/Filters/Alpha.cs

@ -15,15 +15,15 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Alters the alpha component of the image. /// Alters the alpha component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="percent">The new opacity of the image. Must be between 0 and 100.</param> /// <param name="percent">The new opacity of the image. Must be between 0 and 100.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Alpha<T, TP>(this Image<T, TP> source, int percent, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Alpha<TColor, TPacked>(this Image<TColor, TPacked> source, int percent, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Alpha(source, percent, source.Bounds, progressHandler); return Alpha(source, percent, source.Bounds, progressHandler);
} }
@ -31,8 +31,8 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Alters the alpha component of the image. /// Alters the alpha component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="percent">The new opacity of the image. Must be between 0 and 100.</param> /// <param name="percent">The new opacity of the image. Must be between 0 and 100.</param>
/// <param name="rectangle"> /// <param name="rectangle">
@ -40,11 +40,11 @@ namespace ImageProcessorCore
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image<T, TP> Alpha<T, TP>(this Image<T, TP> source, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Alpha<TColor, TPacked>(this Image<TColor, TPacked> source, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
AlphaProcessor<T, TP> processor = new AlphaProcessor<T, TP>(percent); AlphaProcessor<TColor, TPacked> processor = new AlphaProcessor<TColor, TPacked>(percent);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

16
src/ImageProcessorCore/Filters/BackgroundColor.cs

@ -8,24 +8,24 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Replaces the background color of image with the given one. /// Replaces the background color of image with the given one.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the background.</param> /// <param name="color">The color to set as the background.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> BackgroundColor<T, TP>(this Image<T, TP> source, T color, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> BackgroundColor<TColor, TPacked>(this Image<TColor, TPacked> source, TColor color, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
BackgroundColorProcessor<T, TP> processor = new BackgroundColorProcessor<T, TP>(color); BackgroundColorProcessor<TColor, TPacked> processor = new BackgroundColorProcessor<TColor, TPacked>(color);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

28
src/ImageProcessorCore/Filters/BinaryThreshold.cs

@ -8,22 +8,22 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies binerization to the image splitting the pixels at the given threshold. /// Applies binerization to the image splitting the pixels at the given threshold.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="threshold">The threshold to apply binerization of the image. Must be between 0 and 1.</param> /// <param name="threshold">The threshold to apply binerization of the image. Must be between 0 and 1.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> BinaryThreshold<T, TP>(this Image<T, TP> source, float threshold, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> BinaryThreshold<TColor, TPacked>(this Image<TColor, TPacked> source, float threshold, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return BinaryThreshold(source, threshold, source.Bounds, progressHandler); return BinaryThreshold(source, threshold, source.Bounds, progressHandler);
} }
@ -31,20 +31,20 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies binerization to the image splitting the pixels at the given threshold. /// Applies binerization to the image splitting the pixels at the given threshold.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="threshold">The threshold to apply binerization of the image. Must be between 0 and 1.</param> /// <param name="threshold">The threshold to apply binerization of the image. Must be between 0 and 1.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> BinaryThreshold<T, TP>(this Image<T, TP> source, float threshold, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> BinaryThreshold<TColor, TPacked>(this Image<TColor, TPacked> source, float threshold, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
BinaryThresholdProcessor<T, TP> processor = new BinaryThresholdProcessor<T, TP>(threshold); BinaryThresholdProcessor<TColor, TPacked> processor = new BinaryThresholdProcessor<TColor, TPacked>(threshold);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

28
src/ImageProcessorCore/Filters/BlackWhite.cs

@ -8,21 +8,21 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies black and white toning to the image. /// Applies black and white toning to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> BlackWhite<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> BlackWhite<TColor, TPacked>(this Image<TColor, TPacked> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return BlackWhite(source, source.Bounds, progressHandler); return BlackWhite(source, source.Bounds, progressHandler);
} }
@ -30,19 +30,19 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies black and white toning to the image. /// Applies black and white toning to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> BlackWhite<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> BlackWhite<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
BlackWhiteProcessor<T, TP> processor = new BlackWhiteProcessor<T, TP>(); BlackWhiteProcessor<TColor, TPacked> processor = new BlackWhiteProcessor<TColor, TPacked>();
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

26
src/ImageProcessorCore/Filters/Blend.cs

@ -17,14 +17,14 @@ namespace ImageProcessorCore
/// </summary> /// </summary>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="image">The image to blend with the currently processing image.</param> /// <param name="image">The image to blend with the currently processing image.</param>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="percent">The opacity of the image image to blend. Must be between 0 and 100.</param> /// <param name="percent">The opacity of the image image to blend. Must be between 0 and 100.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Blend<T, TP>(this Image<T, TP> source, ImageBase<T, TP> image, int percent = 50, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Blend<TColor, TPacked>(this Image<TColor, TPacked> source, ImageBase<TColor, TPacked> image, int percent = 50, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Blend(source, image, percent, source.Bounds, progressHandler); return Blend(source, image, percent, source.Bounds, progressHandler);
} }
@ -34,19 +34,19 @@ namespace ImageProcessorCore
/// </summary> /// </summary>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="image">The image to blend with the currently processing image.</param> /// <param name="image">The image to blend with the currently processing image.</param>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="percent">The opacity of the image image to blend. Must be between 0 and 100.</param> /// <param name="percent">The opacity of the image image to blend. Must be between 0 and 100.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Blend<T, TP>(this Image<T, TP> source, ImageBase<T, TP> image, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Blend<TColor, TPacked>(this Image<TColor, TPacked> source, ImageBase<TColor, TPacked> image, int percent, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
BlendProcessor<T, TP> processor = new BlendProcessor<T, TP>(image, percent); BlendProcessor<TColor, TPacked> processor = new BlendProcessor<TColor, TPacked>(image, percent);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

28
src/ImageProcessorCore/Filters/BoxBlur.cs

@ -8,22 +8,22 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies a box blur to the image. /// Applies a box blur to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param> /// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> BoxBlur<T, TP>(this Image<T, TP> source, int radius = 7, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> BoxBlur<TColor, TPacked>(this Image<TColor, TPacked> source, int radius = 7, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return BoxBlur(source, radius, source.Bounds, progressHandler); return BoxBlur(source, radius, source.Bounds, progressHandler);
} }
@ -31,20 +31,20 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies a box blur to the image. /// Applies a box blur to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="radius">The 'radius' value representing the size of the area to sample.</param> /// <param name="radius">The 'radius' value representing the size of the area to sample.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> BoxBlur<T, TP>(this Image<T, TP> source, int radius, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> BoxBlur<TColor, TPacked>(this Image<TColor, TPacked> source, int radius, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
BoxBlurProcessor<T, TP> processor = new BoxBlurProcessor<T, TP>(radius); BoxBlurProcessor<TColor, TPacked> processor = new BoxBlurProcessor<TColor, TPacked>(radius);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

26
src/ImageProcessorCore/Filters/Brightness.cs

@ -8,22 +8,21 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Alters the brightness component of the image. /// Alters the brightness component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param> /// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Brightness<T, TP>(this Image<T, TP> source, int amount, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Brightness<TColor, TPacked>(this Image<TColor, TPacked> source, int amount, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Brightness(source, amount, source.Bounds, progressHandler); return Brightness(source, amount, source.Bounds, progressHandler);
} }
@ -31,20 +30,19 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Alters the brightness component of the image. /// Alters the brightness component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param> /// <param name="amount">The new brightness of the image. Must be between -100 and 100.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Brightness<T, TP>(this Image<T, TP> source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Brightness<TColor, TPacked>(this Image<TColor, TPacked> source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
BrightnessProcessor<T, TP> processor = new BrightnessProcessor<T, TP>(amount); BrightnessProcessor<TColor, TPacked> processor = new BrightnessProcessor<TColor, TPacked>(amount);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

44
src/ImageProcessorCore/Filters/ColorBlindness.cs

@ -8,22 +8,22 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies the given colorblindness simulator to the image. /// Applies the given colorblindness simulator to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="colorBlindness">The type of color blindness simulator to apply.</param> /// <param name="colorBlindness">The type of color blindness simulator to apply.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> ColorBlindness<T, TP>(this Image<T, TP> source, ColorBlindness colorBlindness, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> ColorBlindness<TColor, TPacked>(this Image<TColor, TPacked> source, ColorBlindness colorBlindness, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return ColorBlindness(source, colorBlindness, source.Bounds, progressHandler); return ColorBlindness(source, colorBlindness, source.Bounds, progressHandler);
} }
@ -31,53 +31,53 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies the given colorblindness simulator to the image. /// Applies the given colorblindness simulator to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="colorBlindness">The type of color blindness simulator to apply.</param> /// <param name="colorBlindness">The type of color blindness simulator to apply.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> ColorBlindness<T, TP>(this Image<T, TP> source, ColorBlindness colorBlindness, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> ColorBlindness<TColor, TPacked>(this Image<TColor, TPacked> source, ColorBlindness colorBlindness, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
IImageProcessor<T, TP> processor; IImageProcessor<TColor, TPacked> processor;
switch (colorBlindness) switch (colorBlindness)
{ {
case ImageProcessorCore.ColorBlindness.Achromatomaly: case ImageProcessorCore.ColorBlindness.Achromatomaly:
processor = new AchromatomalyProcessor<T, TP>(); processor = new AchromatomalyProcessor<TColor, TPacked>();
break; break;
case ImageProcessorCore.ColorBlindness.Achromatopsia: case ImageProcessorCore.ColorBlindness.Achromatopsia:
processor = new AchromatopsiaProcessor<T, TP>(); processor = new AchromatopsiaProcessor<TColor, TPacked>();
break; break;
case ImageProcessorCore.ColorBlindness.Deuteranomaly: case ImageProcessorCore.ColorBlindness.Deuteranomaly:
processor = new DeuteranomalyProcessor<T, TP>(); processor = new DeuteranomalyProcessor<TColor, TPacked>();
break; break;
case ImageProcessorCore.ColorBlindness.Deuteranopia: case ImageProcessorCore.ColorBlindness.Deuteranopia:
processor = new DeuteranopiaProcessor<T, TP>(); processor = new DeuteranopiaProcessor<TColor, TPacked>();
break; break;
case ImageProcessorCore.ColorBlindness.Protanomaly: case ImageProcessorCore.ColorBlindness.Protanomaly:
processor = new ProtanomalyProcessor<T, TP>(); processor = new ProtanomalyProcessor<TColor, TPacked>();
break; break;
case ImageProcessorCore.ColorBlindness.Protanopia: case ImageProcessorCore.ColorBlindness.Protanopia:
processor = new ProtanopiaProcessor<T, TP>(); processor = new ProtanopiaProcessor<TColor, TPacked>();
break; break;
case ImageProcessorCore.ColorBlindness.Tritanomaly: case ImageProcessorCore.ColorBlindness.Tritanomaly:
processor = new TritanomalyProcessor<T, TP>(); processor = new TritanomalyProcessor<TColor, TPacked>();
break; break;
default: default:
processor = new TritanopiaProcessor<T, TP>(); processor = new TritanopiaProcessor<TColor, TPacked>();
break; break;
} }

28
src/ImageProcessorCore/Filters/Contrast.cs

@ -8,22 +8,22 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Alters the contrast component of the image. /// Alters the contrast component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="amount">The new contrast of the image. Must be between -100 and 100.</param> /// <param name="amount">The new contrast of the image. Must be between -100 and 100.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Contrast<T, TP>(this Image<T, TP> source, int amount, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Contrast<TColor, TPacked>(this Image<TColor, TPacked> source, int amount, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Contrast(source, amount, source.Bounds, progressHandler); return Contrast(source, amount, source.Bounds, progressHandler);
} }
@ -31,20 +31,20 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Alters the contrast component of the image. /// Alters the contrast component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="amount">The new contrast of the image. Must be between -100 and 100.</param> /// <param name="amount">The new contrast of the image. Must be between -100 and 100.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Contrast<T, TP>(this Image<T, TP> source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Contrast<TColor, TPacked>(this Image<TColor, TPacked> source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
ContrastProcessor<T, TP> processor = new ContrastProcessor<T, TP>(amount); ContrastProcessor<TColor, TPacked> processor = new ContrastProcessor<TColor, TPacked>(amount);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

102
src/ImageProcessorCore/Filters/DetectEdges.cs

@ -8,58 +8,58 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Detects any edges within the image. Uses the <see cref="SobelProcessor{T,TP}"/> filter /// Detects any edges within the image. Uses the <see cref="SobelProcessor{TColor, TPacked}"/> filter
/// operating in Grayscale mode. /// operating in Grayscale mode.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> DetectEdges<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> DetectEdges<TColor, TPacked>(this Image<TColor, TPacked> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return DetectEdges(source, source.Bounds, new SobelProcessor<T, TP> { Grayscale = true }, progressHandler); return DetectEdges(source, source.Bounds, new SobelProcessor<TColor, TPacked> { Grayscale = true }, progressHandler);
} }
/// <summary> /// <summary>
/// Detects any edges within the image. Uses the <see cref="SobelProcessor{T,TP}"/> filter /// Detects any edges within the image. Uses the <see cref="SobelProcessor{TColor, TPacked}"/> filter
/// operating in Grayscale mode. /// operating in Grayscale mode.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> DetectEdges<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> DetectEdges<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return DetectEdges(source, rectangle, new SobelProcessor<T, TP> { Grayscale = true }, progressHandler); return DetectEdges(source, rectangle, new SobelProcessor<TColor, TPacked> { Grayscale = true }, progressHandler);
} }
/// <summary> /// <summary>
/// Detects any edges within the image. /// Detects any edges within the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="filter">The filter for detecting edges.</param> /// <param name="filter">The filter for detecting edges.</param>
/// <param name="grayscale">Whether to convert the image to Grayscale first. Defaults to true.</param> /// <param name="grayscale">Whether to convert the image to Grayscale first. Defaults to true.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> DetectEdges<T, TP>(this Image<T, TP> source, EdgeDetection filter, bool grayscale = true, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> DetectEdges<TColor, TPacked>(this Image<TColor, TPacked> source, EdgeDetection filter, bool grayscale = true, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return DetectEdges(source, filter, source.Bounds, grayscale, progressHandler); return DetectEdges(source, filter, source.Bounds, grayscale, progressHandler);
} }
@ -67,8 +67,8 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Detects any edges within the image. /// Detects any edges within the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="filter">The filter for detecting edges.</param> /// <param name="filter">The filter for detecting edges.</param>
/// <param name="rectangle"> /// <param name="rectangle">
@ -76,49 +76,49 @@ namespace ImageProcessorCore
/// </param> /// </param>
/// <param name="grayscale">Whether to convert the image to Grayscale first. Defaults to true.</param> /// <param name="grayscale">Whether to convert the image to Grayscale first. Defaults to true.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> DetectEdges<T, TP>(this Image<T, TP> source, EdgeDetection filter, Rectangle rectangle, bool grayscale = true, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> DetectEdges<TColor, TPacked>(this Image<TColor, TPacked> source, EdgeDetection filter, Rectangle rectangle, bool grayscale = true, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
IEdgeDetectorFilter<T, TP> processor; IEdgeDetectorFilter<TColor, TPacked> processor;
switch (filter) switch (filter)
{ {
case EdgeDetection.Kayyali: case EdgeDetection.Kayyali:
processor = new KayyaliProcessor<T, TP> { Grayscale = grayscale }; processor = new KayyaliProcessor<TColor, TPacked> { Grayscale = grayscale };
break; break;
case EdgeDetection.Kirsch: case EdgeDetection.Kirsch:
processor = new KirschProcessor<T, TP> { Grayscale = grayscale }; processor = new KirschProcessor<TColor, TPacked> { Grayscale = grayscale };
break; break;
case EdgeDetection.Lapacian3X3: case EdgeDetection.Lapacian3X3:
processor = new Laplacian3X3Processor<T, TP> { Grayscale = grayscale }; processor = new Laplacian3X3Processor<TColor, TPacked> { Grayscale = grayscale };
break; break;
case EdgeDetection.Lapacian5X5: case EdgeDetection.Lapacian5X5:
processor = new Laplacian5X5Processor<T, TP> { Grayscale = grayscale }; processor = new Laplacian5X5Processor<TColor, TPacked> { Grayscale = grayscale };
break; break;
case EdgeDetection.LaplacianOfGaussian: case EdgeDetection.LaplacianOfGaussian:
processor = new LaplacianOfGaussianProcessor<T, TP> { Grayscale = grayscale }; processor = new LaplacianOfGaussianProcessor<TColor, TPacked> { Grayscale = grayscale };
break; break;
case EdgeDetection.Prewitt: case EdgeDetection.Prewitt:
processor = new PrewittProcessor<T, TP> { Grayscale = grayscale }; processor = new PrewittProcessor<TColor, TPacked> { Grayscale = grayscale };
break; break;
case EdgeDetection.RobertsCross: case EdgeDetection.RobertsCross:
processor = new RobertsCrossProcessor<T, TP> { Grayscale = grayscale }; processor = new RobertsCrossProcessor<TColor, TPacked> { Grayscale = grayscale };
break; break;
case EdgeDetection.Scharr: case EdgeDetection.Scharr:
processor = new ScharrProcessor<T, TP> { Grayscale = grayscale }; processor = new ScharrProcessor<TColor, TPacked> { Grayscale = grayscale };
break; break;
default: default:
processor = new ScharrProcessor<T, TP> { Grayscale = grayscale }; processor = new ScharrProcessor<TColor, TPacked> { Grayscale = grayscale };
break; break;
} }
@ -128,15 +128,15 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Detects any edges within the image. /// Detects any edges within the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="filter">The filter for detecting edges.</param> /// <param name="filter">The filter for detecting edges.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> DetectEdges<T, TP>(this Image<T, TP> source, IEdgeDetectorFilter<T, TP> filter, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> DetectEdges<TColor, TPacked>(this Image<TColor, TPacked> source, IEdgeDetectorFilter<TColor, TPacked> filter, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return DetectEdges(source, source.Bounds, filter, progressHandler); return DetectEdges(source, source.Bounds, filter, progressHandler);
} }
@ -144,18 +144,18 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Detects any edges within the image. /// Detects any edges within the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="filter">The filter for detecting edges.</param> /// <param name="filter">The filter for detecting edges.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> DetectEdges<T, TP>(this Image<T, TP> source, Rectangle rectangle, IEdgeDetectorFilter<T, TP> filter, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> DetectEdges<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, IEdgeDetectorFilter<TColor, TPacked> filter, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
filter.OnProgress += progressHandler; filter.OnProgress += progressHandler;

72
src/ImageProcessorCore/Filters/Glow.cs

@ -8,37 +8,37 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies a radial glow effect to an image. /// Applies a radial glow effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Glow<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Glow<TColor, TPacked>(this Image<TColor, TPacked> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Glow(source, default(T), source.Bounds.Width * .5F, source.Bounds, progressHandler); return Glow(source, default(TColor), source.Bounds.Width * .5F, source.Bounds, progressHandler);
} }
/// <summary> /// <summary>
/// Applies a radial glow effect to an image. /// Applies a radial glow effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the glow.</param> /// <param name="color">The color to set as the glow.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Glow<T, TP>(this Image<T, TP> source, T color, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Glow<TColor, TPacked>(this Image<TColor, TPacked> source, TColor color, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Glow(source, color, source.Bounds.Width * .5F, source.Bounds, progressHandler); return Glow(source, color, source.Bounds.Width * .5F, source.Bounds, progressHandler);
} }
@ -46,42 +46,42 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies a radial glow effect to an image. /// Applies a radial glow effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="radius">The the radius.</param> /// <param name="radius">The the radius.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Glow<T, TP>(this Image<T, TP> source, float radius, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Glow<TColor, TPacked>(this Image<TColor, TPacked> source, float radius, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Glow(source, default(T), radius, source.Bounds, progressHandler); return Glow(source, default(TColor), radius, source.Bounds, progressHandler);
} }
/// <summary> /// <summary>
/// Applies a radial glow effect to an image. /// Applies a radial glow effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Glow<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Glow<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Glow(source, default(T), 0, rectangle, progressHandler); return Glow(source, default(TColor), 0, rectangle, progressHandler);
} }
/// <summary> /// <summary>
/// Applies a radial glow effect to an image. /// Applies a radial glow effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the glow.</param> /// <param name="color">The color to set as the glow.</param>
/// <param name="radius">The the radius.</param> /// <param name="radius">The the radius.</param>
@ -89,14 +89,14 @@ namespace ImageProcessorCore
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Glow<T, TP>(this Image<T, TP> source, T color, float radius, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Glow<TColor, TPacked>(this Image<TColor, TPacked> source, TColor color, float radius, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
GlowProcessor<T, TP> processor = new GlowProcessor<T, TP> { Radius = radius, }; GlowProcessor<TColor, TPacked> processor = new GlowProcessor<TColor, TPacked> { Radius = radius, };
if (!color.Equals(default(T))) if (!color.Equals(default(TColor)))
{ {
processor.GlowColor = color; processor.GlowColor = color;
} }

32
src/ImageProcessorCore/Filters/Grayscale.cs

@ -8,22 +8,22 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies Grayscale toning to the image. /// Applies Grayscale toning to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="mode">The formula to apply to perform the operation.</param> /// <param name="mode">The formula to apply to perform the operation.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Grayscale<T, TP>(this Image<T, TP> source, GrayscaleMode mode = GrayscaleMode.Bt709, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Grayscale<TColor, TPacked>(this Image<TColor, TPacked> source, GrayscaleMode mode = GrayscaleMode.Bt709, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Grayscale(source, source.Bounds, mode, progressHandler); return Grayscale(source, source.Bounds, mode, progressHandler);
} }
@ -31,22 +31,22 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies Grayscale toning to the image. /// Applies Grayscale toning to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="mode">The formula to apply to perform the operation.</param> /// <param name="mode">The formula to apply to perform the operation.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Grayscale<T, TP>(this Image<T, TP> source, Rectangle rectangle, GrayscaleMode mode = GrayscaleMode.Bt709, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Grayscale<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, GrayscaleMode mode = GrayscaleMode.Bt709, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
IImageProcessor<T, TP> processor = mode == GrayscaleMode.Bt709 IImageProcessor<TColor, TPacked> processor = mode == GrayscaleMode.Bt709
? (IImageProcessor<T, TP>)new GrayscaleBt709Processor<T, TP>() ? (IImageProcessor<TColor, TPacked>)new GrayscaleBt709Processor<TColor, TPacked>()
: new GrayscaleBt601Processor<T, TP>(); : new GrayscaleBt601Processor<TColor, TPacked>();
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;

28
src/ImageProcessorCore/Filters/GuassianBlur.cs

@ -8,22 +8,22 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies a Guassian blur to the image. /// Applies a Guassian blur to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param> /// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> GuassianBlur<T, TP>(this Image<T, TP> source, float sigma = 3f, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> GuassianBlur<TColor, TPacked>(this Image<TColor, TPacked> source, float sigma = 3f, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return GuassianBlur(source, sigma, source.Bounds, progressHandler); return GuassianBlur(source, sigma, source.Bounds, progressHandler);
} }
@ -31,20 +31,20 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies a Guassian blur to the image. /// Applies a Guassian blur to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param> /// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> GuassianBlur<T, TP>(this Image<T, TP> source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> GuassianBlur<TColor, TPacked>(this Image<TColor, TPacked> source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
GuassianBlurProcessor<T, TP> processor = new GuassianBlurProcessor<T, TP>(sigma); GuassianBlurProcessor<TColor, TPacked> processor = new GuassianBlurProcessor<TColor, TPacked>(sigma);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

28
src/ImageProcessorCore/Filters/GuassianSharpen.cs

@ -8,22 +8,22 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies a Guassian sharpening filter to the image. /// Applies a Guassian sharpening filter to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param> /// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> GuassianSharpen<T, TP>(this Image<T, TP> source, float sigma = 3f, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> GuassianSharpen<TColor, TPacked>(this Image<TColor, TPacked> source, float sigma = 3f, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return GuassianSharpen(source, sigma, source.Bounds, progressHandler); return GuassianSharpen(source, sigma, source.Bounds, progressHandler);
} }
@ -31,20 +31,20 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies a Guassian sharpening filter to the image. /// Applies a Guassian sharpening filter to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="sigma">The 'sigma' value representing the weight of the blur.</param> /// <param name="sigma">The 'sigma' value representing the weight of the blur.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> GuassianSharpen<T, TP>(this Image<T, TP> source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> GuassianSharpen<TColor, TPacked>(this Image<TColor, TPacked> source, float sigma, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
GuassianSharpenProcessor<T, TP> processor = new GuassianSharpenProcessor<T, TP>(sigma); GuassianSharpenProcessor<TColor, TPacked> processor = new GuassianSharpenProcessor<TColor, TPacked>(sigma);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

28
src/ImageProcessorCore/Filters/Hue.cs

@ -8,22 +8,22 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Alters the hue component of the image. /// Alters the hue component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="degrees">The angle in degrees to adjust the image.</param> /// <param name="degrees">The angle in degrees to adjust the image.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Hue<T, TP>(this Image<T, TP> source, float degrees, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Hue<TColor, TPacked>(this Image<TColor, TPacked> source, float degrees, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Hue(source, degrees, source.Bounds, progressHandler); return Hue(source, degrees, source.Bounds, progressHandler);
} }
@ -31,20 +31,20 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Alters the hue component of the image. /// Alters the hue component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="degrees">The angle in degrees to adjust the image.</param> /// <param name="degrees">The angle in degrees to adjust the image.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Hue<T, TP>(this Image<T, TP> source, float degrees, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Hue<TColor, TPacked>(this Image<TColor, TPacked> source, float degrees, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
HueProcessor<T, TP> processor = new HueProcessor<T, TP>(degrees); HueProcessor<TColor, TPacked> processor = new HueProcessor<TColor, TPacked>(degrees);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

14
src/ImageProcessorCore/Filters/Invert.cs

@ -18,9 +18,9 @@ namespace ImageProcessorCore
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image<T, TP> Invert<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Invert<TColor, TPacked>(this Image<TColor, TPacked> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Invert(source, source.Bounds, progressHandler); return Invert(source, source.Bounds, progressHandler);
} }
@ -34,11 +34,11 @@ namespace ImageProcessorCore
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image<T, TP> Invert<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Invert<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
InvertProcessor<T, TP> processor = new InvertProcessor<T, TP>(); InvertProcessor<TColor, TPacked> processor = new InvertProcessor<TColor, TPacked>();
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

28
src/ImageProcessorCore/Filters/Kodachrome.cs

@ -8,21 +8,21 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Alters the colors of the image recreating an old Kodachrome camera effect. /// Alters the colors of the image recreating an old Kodachrome camera effect.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Kodachrome<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Kodachrome<TColor, TPacked>(this Image<TColor, TPacked> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Kodachrome(source, source.Bounds, progressHandler); return Kodachrome(source, source.Bounds, progressHandler);
} }
@ -30,19 +30,19 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Alters the colors of the image recreating an old Kodachrome camera effect. /// Alters the colors of the image recreating an old Kodachrome camera effect.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Kodachrome<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Kodachrome<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
KodachromeProcessor<T, TP> processor = new KodachromeProcessor<T, TP>(); KodachromeProcessor<TColor, TPacked> processor = new KodachromeProcessor<TColor, TPacked>();
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

28
src/ImageProcessorCore/Filters/Lomograph.cs

@ -8,21 +8,21 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Alters the colors of the image recreating an old Lomograph camera effect. /// Alters the colors of the image recreating an old Lomograph camera effect.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Lomograph<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Lomograph<TColor, TPacked>(this Image<TColor, TPacked> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Lomograph(source, source.Bounds, progressHandler); return Lomograph(source, source.Bounds, progressHandler);
} }
@ -30,19 +30,19 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Alters the colors of the image recreating an old Lomograph camera effect. /// Alters the colors of the image recreating an old Lomograph camera effect.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Lomograph<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Lomograph<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
LomographProcessor<T, TP> processor = new LomographProcessor<T, TP>(); LomographProcessor<TColor, TPacked> processor = new LomographProcessor<TColor, TPacked>();
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

24
src/ImageProcessorCore/Filters/Pixelate.cs

@ -9,10 +9,10 @@ namespace ImageProcessorCore
using System; using System;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
@ -21,10 +21,10 @@ namespace ImageProcessorCore
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="size">The size of the pixels.</param> /// <param name="size">The size of the pixels.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Pixelate<T, TP>(this Image<T, TP> source, int size = 4, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Pixelate<TColor, TPacked>(this Image<TColor, TPacked> source, int size = 4, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Pixelate(source, size, source.Bounds, progressHandler); return Pixelate(source, size, source.Bounds, progressHandler);
} }
@ -38,17 +38,17 @@ namespace ImageProcessorCore
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Pixelate<T, TP>(this Image<T, TP> source, int size, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Pixelate<TColor, TPacked>(this Image<TColor, TPacked> source, int size, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
if (size <= 0 || size > source.Height || size > source.Width) if (size <= 0 || size > source.Height || size > source.Width)
{ {
throw new ArgumentOutOfRangeException(nameof(size)); throw new ArgumentOutOfRangeException(nameof(size));
} }
PixelateProcessor<T, TP> processor = new PixelateProcessor<T, TP>(size); PixelateProcessor<TColor, TPacked> processor = new PixelateProcessor<TColor, TPacked>(size);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

28
src/ImageProcessorCore/Filters/Polaroid.cs

@ -8,21 +8,21 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Alters the colors of the image recreating an old Polaroid camera effect. /// Alters the colors of the image recreating an old Polaroid camera effect.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Polaroid<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Polaroid<TColor, TPacked>(this Image<TColor, TPacked> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Polaroid(source, source.Bounds, progressHandler); return Polaroid(source, source.Bounds, progressHandler);
} }
@ -30,19 +30,19 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Alters the colors of the image recreating an old Polaroid camera effect. /// Alters the colors of the image recreating an old Polaroid camera effect.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Polaroid<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Polaroid<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
PolaroidProcessor<T, TP> processor = new PolaroidProcessor<T, TP>(); PolaroidProcessor<TColor, TPacked> processor = new PolaroidProcessor<TColor, TPacked>();
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

22
src/ImageProcessorCore/Filters/Processors/AlphaProcessor.cs

@ -10,16 +10,16 @@ namespace ImageProcessorCore.Processors
using System.Threading.Tasks; using System.Threading.Tasks;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> to change the alpha component of an <see cref="Image{T,TP}"/>. /// An <see cref="IImageProcessor{TColor, TPacked}"/> to change the alpha component of an <see cref="Image{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class AlphaProcessor<T, TP> : ImageProcessor<T, TP> public class AlphaProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="AlphaProcessor{T,TP}"/> class. /// Initializes a new instance of the <see cref="AlphaProcessor{TColor, TPacked}"/> class.
/// </summary> /// </summary>
/// <param name="percent">The percentage to adjust the opacity of the image. Must be between 0 and 100.</param> /// <param name="percent">The percentage to adjust the opacity of the image. Must be between 0 and 100.</param>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
@ -37,7 +37,7 @@ namespace ImageProcessorCore.Processors
public int Value { get; } public int Value { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
float alpha = this.Value / 100F; float alpha = this.Value / 100F;
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
@ -62,8 +62,8 @@ namespace ImageProcessorCore.Processors
Vector4 alphaVector = new Vector4(1, 1, 1, alpha); Vector4 alphaVector = new Vector4(1, 1, 1, alpha);
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -75,7 +75,7 @@ namespace ImageProcessorCore.Processors
for (int x = minX; x < maxX; x++) for (int x = minX; x < maxX; x++)
{ {
int offsetX = x - startX; int offsetX = x - startX;
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(sourcePixels[offsetX, offsetY].ToVector4() * alphaVector); packed.PackFromVector4(sourcePixels[offsetX, offsetY].ToVector4() * alphaVector);
targetPixels[offsetX, offsetY] = packed; targetPixels[offsetX, offsetY] = packed;
} }

20
src/ImageProcessorCore/Filters/Processors/BackgroundColorProcessor.cs

@ -12,9 +12,9 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Sets the background color of the image. /// Sets the background color of the image.
/// </summary> /// </summary>
public class BackgroundColorProcessor<T, TP> : ImageProcessor<T, TP> public class BackgroundColorProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// The epsilon for comparing floating point numbers. /// The epsilon for comparing floating point numbers.
@ -22,10 +22,10 @@ namespace ImageProcessorCore.Processors
private const float Epsilon = 0.001f; private const float Epsilon = 0.001f;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="BackgroundColorProcessor{T,TP}"/> class. /// Initializes a new instance of the <see cref="BackgroundColorProcessor{TColor, TPacked}"/> class.
/// </summary> /// </summary>
/// <param name="color">The <see cref="T"/> to set the background color to.</param> /// <param name="color">The <see cref="T"/> to set the background color to.</param>
public BackgroundColorProcessor(T color) public BackgroundColorProcessor(TColor color)
{ {
this.Value = color; this.Value = color;
} }
@ -33,10 +33,10 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Gets the background color value. /// Gets the background color value.
/// </summary> /// </summary>
public T Value { get; } public TColor Value { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
int endX = sourceRectangle.Right; int endX = sourceRectangle.Right;
@ -60,8 +60,8 @@ namespace ImageProcessorCore.Processors
Vector4 backgroundColor = this.Value.ToVector4(); Vector4 backgroundColor = this.Value.ToVector4();
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -86,7 +86,7 @@ namespace ImageProcessorCore.Processors
color = backgroundColor; color = backgroundColor;
} }
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(color); packed.PackFromVector4(color);
targetPixels[offsetX, offsetY] = packed; targetPixels[offsetX, offsetY] = packed;
} }

40
src/ImageProcessorCore/Filters/Processors/Binarization/BinaryThresholdProcessor.cs

@ -9,17 +9,17 @@ namespace ImageProcessorCore.Processors
using System.Threading.Tasks; using System.Threading.Tasks;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> to perform binary threshold filtering against an /// An <see cref="IImageProcessor{TColor, TPacked}"/> to perform binary threshold filtering against an
/// <see cref="Image"/>. The image will be converted to grayscale before thresholding occurs. /// <see cref="Image"/>. The image will be converted to grayscale before thresholding occurs.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class BinaryThresholdProcessor<T, TP> : ImageProcessor<T, TP> public class BinaryThresholdProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="BinaryThresholdProcessor{T,TP}"/> class. /// Initializes a new instance of the <see cref="BinaryThresholdProcessor{TColor, TPacked}"/> class.
/// </summary> /// </summary>
/// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param> /// <param name="threshold">The threshold to split the image. Must be between 0 and 1.</param>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
@ -31,11 +31,11 @@ namespace ImageProcessorCore.Processors
Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold)); Guard.MustBeBetweenOrEqualTo(threshold, 0, 1, nameof(threshold));
this.Value = threshold; this.Value = threshold;
T upper = default(T); TColor upper = default(TColor);
upper.PackFromVector4(Color.White.ToVector4()); upper.PackFromVector4(Color.White.ToVector4());
this.UpperColor = upper; this.UpperColor = upper;
T lower = default(T); TColor lower = default(TColor);
lower.PackFromVector4(Color.Black.ToVector4()); lower.PackFromVector4(Color.Black.ToVector4());
this.LowerColor = lower; this.LowerColor = lower;
} }
@ -48,25 +48,25 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Gets or sets the color to use for pixels that are above the threshold. /// Gets or sets the color to use for pixels that are above the threshold.
/// </summary> /// </summary>
public T UpperColor { get; set; } public TColor UpperColor { get; set; }
/// <summary> /// <summary>
/// Gets or sets the color to use for pixels that fall below the threshold. /// Gets or sets the color to use for pixels that fall below the threshold.
/// </summary> /// </summary>
public T LowerColor { get; set; } public TColor LowerColor { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnApply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle) protected override void OnApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{ {
new GrayscaleBt709Processor<T, TP>().Apply(source, source, sourceRectangle); new GrayscaleBt709Processor<TColor, TPacked>().Apply(source, source, sourceRectangle);
} }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
float threshold = this.Value; float threshold = this.Value;
T upper = this.UpperColor; TColor upper = this.UpperColor;
T lower = this.LowerColor; TColor lower = this.LowerColor;
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
int endX = sourceRectangle.Right; int endX = sourceRectangle.Right;
@ -87,8 +87,8 @@ namespace ImageProcessorCore.Processors
startY = 0; startY = 0;
} }
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -100,7 +100,7 @@ namespace ImageProcessorCore.Processors
for (int x = minX; x < maxX; x++) for (int x = minX; x < maxX; x++)
{ {
int offsetX = x - startX; int offsetX = x - startX;
T color = sourcePixels[offsetX, offsetY]; TColor color = sourcePixels[offsetX, offsetY];
// Any channel will do since it's Grayscale. // Any channel will do since it's Grayscale.
targetPixels[offsetX, offsetY] = color.ToVector4().X >= threshold ? upper : lower; targetPixels[offsetX, offsetY] = color.ToVector4().X >= threshold ? upper : lower;
@ -111,4 +111,4 @@ namespace ImageProcessorCore.Processors
} }
} }
} }
} }

26
src/ImageProcessorCore/Filters/Processors/BlendProcessor.cs

@ -12,26 +12,26 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Combines two images together by blending the pixels. /// Combines two images together by blending the pixels.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class BlendProcessor<T, TP> : ImageProcessor<T, TP> public class BlendProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// The image to blend. /// The image to blend.
/// </summary> /// </summary>
private readonly ImageBase<T, TP> blend; private readonly ImageBase<TColor, TPacked> blend;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="BlendProcessor{T,TP}"/> class. /// Initializes a new instance of the <see cref="BlendProcessor{TColor, TPacked}"/> class.
/// </summary> /// </summary>
/// <param name="image"> /// <param name="image">
/// The image to blend with the currently processing image. /// The image to blend with the currently processing image.
/// Disposal of this image is the responsibility of the developer. /// Disposal of this image is the responsibility of the developer.
/// </param> /// </param>
/// <param name="alpha">The opacity of the image to blend. Between 0 and 100.</param> /// <param name="alpha">The opacity of the image to blend. Between 0 and 100.</param>
public BlendProcessor(ImageBase<T, TP> image, int alpha = 100) public BlendProcessor(ImageBase<TColor, TPacked> image, int alpha = 100)
{ {
Guard.MustBeBetweenOrEqualTo(alpha, 0, 100, nameof(alpha)); Guard.MustBeBetweenOrEqualTo(alpha, 0, 100, nameof(alpha));
this.blend = image; this.blend = image;
@ -44,7 +44,7 @@ namespace ImageProcessorCore.Processors
public int Value { get; } public int Value { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
int endX = sourceRectangle.Right; int endX = sourceRectangle.Right;
@ -69,9 +69,9 @@ namespace ImageProcessorCore.Processors
float alpha = this.Value / 100F; float alpha = this.Value / 100F;
using (IPixelAccessor<T, TP> toBlendPixels = this.blend.Lock()) using (PixelAccessor<TColor, TPacked> toBlendPixels = this.blend.Lock())
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -96,7 +96,7 @@ namespace ImageProcessorCore.Processors
} }
} }
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(color); packed.PackFromVector4(color);
targetPixels[offsetX, offsetY] = packed; targetPixels[offsetX, offsetY] = packed;
} }

22
src/ImageProcessorCore/Filters/Processors/BrightnessProcessor.cs

@ -10,16 +10,16 @@ namespace ImageProcessorCore.Processors
using System.Threading.Tasks; using System.Threading.Tasks;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> to change the brightness of an <see cref="Image{T,TP}"/>. /// An <see cref="IImageProcessor{TColor, TPacked}"/> to change the brightness of an <see cref="Image{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class BrightnessProcessor<T, TP> : ImageProcessor<T, TP> public class BrightnessProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="BrightnessProcessor{T,TP}"/> class. /// Initializes a new instance of the <see cref="BrightnessProcessor{TColor, TPacked}"/> class.
/// </summary> /// </summary>
/// <param name="brightness">The new brightness of the image. Must be between -100 and 100.</param> /// <param name="brightness">The new brightness of the image. Must be between -100 and 100.</param>
/// <exception cref="ArgumentException"> /// <exception cref="ArgumentException">
@ -37,7 +37,7 @@ namespace ImageProcessorCore.Processors
public int Value { get; } public int Value { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
float brightness = this.Value / 100F; float brightness = this.Value / 100F;
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
@ -60,8 +60,8 @@ namespace ImageProcessorCore.Processors
startY = 0; startY = 0;
} }
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -79,7 +79,7 @@ namespace ImageProcessorCore.Processors
Vector3 transformed = new Vector3(vector.X, vector.Y, vector.Z) + new Vector3(brightness); Vector3 transformed = new Vector3(vector.X, vector.Y, vector.Z) + new Vector3(brightness);
vector = new Vector4(transformed, vector.W); vector = new Vector4(transformed, vector.W);
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(vector.Compress()); packed.PackFromVector4(vector.Compress());
targetPixels[offsetX, offsetY] = packed; targetPixels[offsetX, offsetY] = packed;

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/BlackWhiteProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image to their black and white equivalent. /// Converts the colors of the image to their black and white equivalent.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class BlackWhiteProcessor<T, TP> : ColorMatrixFilter<T, TP> public class BlackWhiteProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatomalyProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating Achromatomaly (Color desensitivity) color blindness. /// Converts the colors of the image recreating Achromatomaly (Color desensitivity) color blindness.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class AchromatomalyProcessor<T, TP> : ColorMatrixFilter<T, TP> public class AchromatomalyProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/AchromatopsiaProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating Achromatopsia (Monochrome) color blindness. /// Converts the colors of the image recreating Achromatopsia (Monochrome) color blindness.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class AchromatopsiaProcessor<T, TP> : ColorMatrixFilter<T, TP> public class AchromatopsiaProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranomalyProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating Deuteranomaly (Green-Weak) color blindness. /// Converts the colors of the image recreating Deuteranomaly (Green-Weak) color blindness.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class DeuteranomalyProcessor<T, TP> : ColorMatrixFilter<T, TP> public class DeuteranomalyProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/DeuteranopiaProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating Deuteranopia (Green-Blind) color blindness. /// Converts the colors of the image recreating Deuteranopia (Green-Blind) color blindness.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class DeuteranopiaProcessor<T, TP> : ColorMatrixFilter<T, TP> public class DeuteranopiaProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanomalyProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating Protanopia (Red-Weak) color blindness. /// Converts the colors of the image recreating Protanopia (Red-Weak) color blindness.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class ProtanomalyProcessor<T, TP> : ColorMatrixFilter<T, TP> public class ProtanomalyProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/ProtanopiaProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating Protanopia (Red-Blind) color blindness. /// Converts the colors of the image recreating Protanopia (Red-Blind) color blindness.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class ProtanopiaProcessor<T, TP> : ColorMatrixFilter<T, TP> public class ProtanopiaProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanomalyProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating Tritanomaly (Blue-Weak) color blindness. /// Converts the colors of the image recreating Tritanomaly (Blue-Weak) color blindness.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class TritanomalyProcessor<T, TP> : ColorMatrixFilter<T, TP> public class TritanomalyProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorBlindness/TritanopiaProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating Tritanopia (Blue-Blind) color blindness. /// Converts the colors of the image recreating Tritanopia (Blue-Blind) color blindness.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class TritanopiaProcessor<T, TP> : ColorMatrixFilter<T, TP> public class TritanopiaProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

20
src/ImageProcessorCore/Filters/Processors/ColorMatrix/ColorMatrixFilter.cs

@ -12,11 +12,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// The color matrix filter. Inherit from this class to perform operation involving color matrices. /// The color matrix filter. Inherit from this class to perform operation involving color matrices.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public abstract class ColorMatrixFilter<T, TP> : ImageProcessor<T, TP>, IColorMatrixFilter<T, TP> public abstract class ColorMatrixFilter<TColor, TPacked> : ImageProcessor<TColor, TPacked>, IColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public abstract Matrix4x4 Matrix { get; } public abstract Matrix4x4 Matrix { get; }
@ -25,7 +25,7 @@ namespace ImageProcessorCore.Processors
public override bool Compand { get; set; } = true; public override bool Compand { get; set; } = true;
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
int endX = sourceRectangle.Right; int endX = sourceRectangle.Right;
@ -50,8 +50,8 @@ namespace ImageProcessorCore.Processors
Matrix4x4 matrix = this.Matrix; Matrix4x4 matrix = this.Matrix;
bool compand = this.Compand; bool compand = this.Compand;
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -80,7 +80,7 @@ namespace ImageProcessorCore.Processors
/// <returns> /// <returns>
/// The <see cref="Color"/>. /// The <see cref="Color"/>.
/// </returns> /// </returns>
private T ApplyMatrix(T color, Matrix4x4 matrix, bool compand) private TColor ApplyMatrix(TColor color, Matrix4x4 matrix, bool compand)
{ {
Vector4 vector = color.ToVector4(); Vector4 vector = color.ToVector4();
@ -91,7 +91,7 @@ namespace ImageProcessorCore.Processors
Vector3 transformed = Vector3.Transform(new Vector3(vector.X, vector.Y, vector.Z), matrix); Vector3 transformed = Vector3.Transform(new Vector3(vector.X, vector.Y, vector.Z), matrix);
vector = new Vector4(transformed, vector.W); vector = new Vector4(transformed, vector.W);
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(compand ? vector.Compress() : vector); packed.PackFromVector4(compand ? vector.Compress() : vector);
return packed; return packed;
} }

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/GrayscaleBt601Processor.cs

@ -11,11 +11,11 @@ namespace ImageProcessorCore.Processors
/// Converts the colors of the image to Grayscale applying the formula as specified by /// Converts the colors of the image to Grayscale applying the formula as specified by
/// ITU-R Recommendation BT.601 <see href="https://en.wikipedia.org/wiki/Luma_%28video%29#Rec._601_luma_versus_Rec._709_luma_coefficients"/>. /// ITU-R Recommendation BT.601 <see href="https://en.wikipedia.org/wiki/Luma_%28video%29#Rec._601_luma_versus_Rec._709_luma_coefficients"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class GrayscaleBt601Processor<T, TP> : ColorMatrixFilter<T, TP> public class GrayscaleBt601Processor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

6
src/ImageProcessorCore/Filters/Processors/ColorMatrix/GrayscaleBt709Processor.cs

@ -11,9 +11,9 @@ namespace ImageProcessorCore.Processors
/// Converts the colors of the image to Grayscale applying the formula as specified by /// Converts the colors of the image to Grayscale applying the formula as specified by
/// ITU-R Recommendation BT.709 <see href="https://en.wikipedia.org/wiki/Rec._709#Luma_coefficients"/>. /// ITU-R Recommendation BT.709 <see href="https://en.wikipedia.org/wiki/Rec._709#Luma_coefficients"/>.
/// </summary> /// </summary>
public class GrayscaleBt709Processor<T, TP> : ColorMatrixFilter<T, TP> public class GrayscaleBt709Processor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

12
src/ImageProcessorCore/Filters/Processors/ColorMatrix/HueProcessor.cs

@ -9,13 +9,13 @@ namespace ImageProcessorCore.Processors
using System.Numerics; using System.Numerics;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> to change the hue of an <see cref="Image"/>. /// An <see cref="IImageProcessor{TColor, TPacked}"/> to change the hue of an <see cref="Image"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class HueProcessor<T, TP> : ColorMatrixFilter<T, TP> public class HueProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// The <see cref="Matrix4x4"/> used to alter the image. /// The <see cref="Matrix4x4"/> used to alter the image.

6
src/ImageProcessorCore/Filters/Processors/ColorMatrix/IColorMatrixFilter.cs

@ -11,9 +11,9 @@ namespace ImageProcessorCore.Processors
/// Encapsulates properties and methods for creating processors that utilize a matrix to /// Encapsulates properties and methods for creating processors that utilize a matrix to
/// alter the image pixels. /// alter the image pixels.
/// </summary> /// </summary>
public interface IColorMatrixFilter<T, TP> : IImageProcessor<T, TP> public interface IColorMatrixFilter<TColor, TPacked> : IImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Gets the <see cref="Matrix4x4"/> used to alter the image. /// Gets the <see cref="Matrix4x4"/> used to alter the image.

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/KodachromeProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating an old Kodachrome camera effect. /// Converts the colors of the image recreating an old Kodachrome camera effect.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class KodachromeProcessor<T, TP> : ColorMatrixFilter<T, TP> public class KodachromeProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

16
src/ImageProcessorCore/Filters/Processors/ColorMatrix/LomographProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating an old Lomograph effect. /// Converts the colors of the image recreating an old Lomograph effect.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class LomographProcessor<T, TP> : ColorMatrixFilter<T, TP> public class LomographProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()
@ -28,11 +28,11 @@ namespace ImageProcessorCore.Processors
}; };
/// <inheritdoc/> /// <inheritdoc/>
protected override void AfterApply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle) protected override void AfterApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{ {
T packed = default(T); TColor packed = default(TColor);
packed.PackFromBytes(0, 10, 0, 255); // Very dark (mostly black) lime green. packed.PackFromBytes(0, 10, 0, 255); // Very dark (mostly black) lime green.
new VignetteProcessor<T, TP> { VignetteColor = packed }.Apply(target, target, sourceRectangle); new VignetteProcessor<TColor, TPacked> { VignetteColor = packed }.Apply(target, target, sourceRectangle);
} }
} }
} }

20
src/ImageProcessorCore/Filters/Processors/ColorMatrix/PolaroidProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Converts the colors of the image recreating an old Polaroid effect. /// Converts the colors of the image recreating an old Polaroid effect.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class PolaroidProcessor<T, TP> : ColorMatrixFilter<T, TP> public class PolaroidProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()
@ -34,15 +34,15 @@ namespace ImageProcessorCore.Processors
}; };
/// <inheritdoc/> /// <inheritdoc/>
protected override void AfterApply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle) protected override void AfterApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{ {
T packedV = default(T); TColor packedV = default(TColor);
packedV.PackFromBytes(102, 34, 0, 255); // Very dark orange [Brown tone] packedV.PackFromBytes(102, 34, 0, 255); // Very dark orange [Brown tone]
new VignetteProcessor<T, TP> { VignetteColor = packedV }.Apply(target, target, sourceRectangle); new VignetteProcessor<TColor, TPacked> { VignetteColor = packedV }.Apply(target, target, sourceRectangle);
T packedG = default(T); TColor packedG = default(TColor);
packedG.PackFromBytes(255, 153, 102, 178); // Light orange packedG.PackFromBytes(255, 153, 102, 178); // Light orange
new GlowProcessor<T, TP> { GlowColor = packedG, Radius = target.Width / 4F }.Apply(target, target, sourceRectangle); new GlowProcessor<TColor, TPacked> { GlowColor = packedG, Radius = target.Width / 4F }.Apply(target, target, sourceRectangle);
} }
} }
} }

12
src/ImageProcessorCore/Filters/Processors/ColorMatrix/SaturationProcessor.cs

@ -8,13 +8,13 @@ namespace ImageProcessorCore.Processors
using System.Numerics; using System.Numerics;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> to change the saturation of an <see cref="Image"/>. /// An <see cref="IImageProcessor{TColor, TPacked}"/> to change the saturation of an <see cref="Image"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class SaturationProcessor<T, TP> : ColorMatrixFilter<T, TP> public class SaturationProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// The saturation to be applied to the image. /// The saturation to be applied to the image.

10
src/ImageProcessorCore/Filters/Processors/ColorMatrix/SepiaProcessor.cs

@ -11,11 +11,11 @@ namespace ImageProcessorCore.Processors
/// Converts the colors of the image to their sepia equivalent. /// Converts the colors of the image to their sepia equivalent.
/// The formula used matches the svg specification. <see href="http://www.w3.org/TR/filter-effects/#sepiaEquivalent"/> /// The formula used matches the svg specification. <see href="http://www.w3.org/TR/filter-effects/#sepiaEquivalent"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class SepiaProcessor<T, TP> : ColorMatrixFilter<T, TP> public class SepiaProcessor<TColor, TPacked> : ColorMatrixFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override Matrix4x4 Matrix => new Matrix4x4() public override Matrix4x4 Matrix => new Matrix4x4()

20
src/ImageProcessorCore/Filters/Processors/ContrastProcessor.cs

@ -10,13 +10,13 @@ namespace ImageProcessorCore.Processors
using System.Threading.Tasks; using System.Threading.Tasks;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> to change the contrast of an <see cref="Image{T,TP}"/>. /// An <see cref="IImageProcessor{TColor, TPacked}"/> to change the contrast of an <see cref="Image{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class ContrastProcessor<T, TP> : ImageProcessor<T, TP> public class ContrastProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ContrastProcessor"/> class. /// Initializes a new instance of the <see cref="ContrastProcessor"/> class.
@ -37,7 +37,7 @@ namespace ImageProcessorCore.Processors
public int Value { get; } public int Value { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
float contrast = (100F + this.Value) / 100F; float contrast = (100F + this.Value) / 100F;
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
@ -62,8 +62,8 @@ namespace ImageProcessorCore.Processors
startY = 0; startY = 0;
} }
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -80,7 +80,7 @@ namespace ImageProcessorCore.Processors
vector -= shiftVector; vector -= shiftVector;
vector *= contrastVector; vector *= contrastVector;
vector += shiftVector; vector += shiftVector;
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(vector.Compress()); packed.PackFromVector4(vector.Compress());
targetPixels[offsetX, offsetY] = packed; targetPixels[offsetX, offsetY] = packed;
} }

12
src/ImageProcessorCore/Filters/Processors/Convolution/BoxBlurProcessor.cs

@ -8,11 +8,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Applies a Box blur filter to the image. /// Applies a Box blur filter to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class BoxBlurProcessor<T, TP> : Convolution2PassFilter<T, TP> public class BoxBlurProcessor<TColor, TPacked> : Convolution2PassFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// The maximum size of the kernal in either direction. /// The maximum size of the kernal in either direction.
@ -47,7 +47,7 @@ namespace ImageProcessorCore.Processors
public override float[,] KernelY => this.kernelY; public override float[,] KernelY => this.kernelY;
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnApply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle) protected override void OnApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{ {
if (this.kernelY == null) if (this.kernelY == null)
{ {

18
src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2DFilter.cs

@ -12,11 +12,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Defines a filter that uses two one-dimensional matrices to perform convolution against an image. /// Defines a filter that uses two one-dimensional matrices to perform convolution against an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public abstract class Convolution2DFilter<T, TP> : ImageProcessor<T, TP> public abstract class Convolution2DFilter<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Gets the horizontal gradient operator. /// Gets the horizontal gradient operator.
@ -29,7 +29,7 @@ namespace ImageProcessorCore.Processors
public abstract float[,] KernelY { get; } public abstract float[,] KernelY { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
float[,] kernelX = this.KernelX; float[,] kernelX = this.KernelX;
float[,] kernelY = this.KernelY; float[,] kernelY = this.KernelY;
@ -47,8 +47,8 @@ namespace ImageProcessorCore.Processors
int maxY = sourceBottom - 1; int maxY = sourceBottom - 1;
int maxX = endX - 1; int maxX = endX - 1;
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
startY, startY,
@ -108,7 +108,7 @@ namespace ImageProcessorCore.Processors
float blue = (float)Math.Sqrt((bX * bX) + (bY * bY)); float blue = (float)Math.Sqrt((bX * bX) + (bY * bY));
Vector4 targetColor = targetPixels[x, y].ToVector4(); Vector4 targetColor = targetPixels[x, y].ToVector4();
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(new Vector4(red, green, blue, targetColor.Z)); packed.PackFromVector4(new Vector4(red, green, blue, targetColor.Z));
targetPixels[x, y] = packed; targetPixels[x, y] = packed;
} }

24
src/ImageProcessorCore/Filters/Processors/Convolution/Convolution2PassFilter.cs

@ -11,11 +11,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Defines a filter that uses two one-dimensional matrices to perform two-pass convolution against an image. /// Defines a filter that uses two one-dimensional matrices to perform two-pass convolution against an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public abstract class Convolution2PassFilter<T, TP> : ImageProcessor<T, TP> public abstract class Convolution2PassFilter<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Gets the horizontal gradient operator. /// Gets the horizontal gradient operator.
@ -28,18 +28,18 @@ namespace ImageProcessorCore.Processors
public abstract float[,] KernelY { get; } public abstract float[,] KernelY { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
float[,] kernelX = this.KernelX; float[,] kernelX = this.KernelX;
float[,] kernelY = this.KernelY; float[,] kernelY = this.KernelY;
ImageBase<T, TP> firstPass = new Image<T, TP>(source.Width, source.Height); ImageBase<TColor, TPacked> firstPass = new Image<TColor, TPacked>(source.Width, source.Height);
this.ApplyConvolution(firstPass, source, sourceRectangle, startY, endY, kernelX); this.ApplyConvolution(firstPass, source, sourceRectangle, startY, endY, kernelX);
this.ApplyConvolution(target, firstPass, sourceRectangle, startY, endY, kernelY); this.ApplyConvolution(target, firstPass, sourceRectangle, startY, endY, kernelY);
} }
/// <summary> /// <summary>
/// Applies the process to the specified portion of the specified <see cref="ImageBase{T,TP}"/> at the specified location /// Applies the process to the specified portion of the specified <see cref="ImageBase{TColor, TPacked}"/> at the specified location
/// and with the specified size. /// and with the specified size.
/// </summary> /// </summary>
/// <param name="target">Target image to apply the process to.</param> /// <param name="target">Target image to apply the process to.</param>
@ -50,7 +50,7 @@ namespace ImageProcessorCore.Processors
/// <param name="startY">The index of the row within the source image to start processing.</param> /// <param name="startY">The index of the row within the source image to start processing.</param>
/// <param name="endY">The index of the row within the source image to end processing.</param> /// <param name="endY">The index of the row within the source image to end processing.</param>
/// <param name="kernel">The kernel operator.</param> /// <param name="kernel">The kernel operator.</param>
private void ApplyConvolution(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle sourceRectangle, int startY, int endY, float[,] kernel) private void ApplyConvolution(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY, float[,] kernel)
{ {
int kernelHeight = kernel.GetLength(0); int kernelHeight = kernel.GetLength(0);
int kernelWidth = kernel.GetLength(1); int kernelWidth = kernel.GetLength(1);
@ -63,8 +63,8 @@ namespace ImageProcessorCore.Processors
int maxY = sourceBottom - 1; int maxY = sourceBottom - 1;
int maxX = endX - 1; int maxX = endX - 1;
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
startY, startY,
@ -96,7 +96,7 @@ namespace ImageProcessorCore.Processors
} }
} }
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(destination); packed.PackFromVector4(destination);
targetPixels[x, y] = packed; targetPixels[x, y] = packed;
} }

14
src/ImageProcessorCore/Filters/Processors/Convolution/ConvolutionFilter.cs

@ -11,9 +11,9 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Defines a filter that uses a 2 dimensional matrix to perform convolution against an image. /// Defines a filter that uses a 2 dimensional matrix to perform convolution against an image.
/// </summary> /// </summary>
public abstract class ConvolutionFilter<T, TP> : ImageProcessor<T, TP> public abstract class ConvolutionFilter<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Gets the 2d gradient operator. /// Gets the 2d gradient operator.
@ -21,7 +21,7 @@ namespace ImageProcessorCore.Processors
public abstract float[,] KernelXY { get; } public abstract float[,] KernelXY { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
float[,] kernelX = this.KernelXY; float[,] kernelX = this.KernelXY;
int kernelLength = kernelX.GetLength(0); int kernelLength = kernelX.GetLength(0);
@ -34,8 +34,8 @@ namespace ImageProcessorCore.Processors
int maxY = sourceBottom - 1; int maxY = sourceBottom - 1;
int maxX = endX - 1; int maxX = endX - 1;
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
startY, startY,
@ -82,7 +82,7 @@ namespace ImageProcessorCore.Processors
float blue = bX; float blue = bX;
Vector4 targetColor = targetPixels[x, y].ToVector4(); Vector4 targetColor = targetPixels[x, y].ToVector4();
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(new Vector4(red, green, blue, targetColor.Z)); packed.PackFromVector4(new Vector4(red, green, blue, targetColor.Z));
targetPixels[x, y] = packed; targetPixels[x, y] = packed;

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetector2DFilter.cs

@ -9,19 +9,19 @@ namespace ImageProcessorCore.Processors
/// Defines a filter that detects edges within an image using two /// Defines a filter that detects edges within an image using two
/// one-dimensional matrices. /// one-dimensional matrices.
/// </summary> /// </summary>
public abstract class EdgeDetector2DFilter<T, TP> : Convolution2DFilter<T, TP>, IEdgeDetectorFilter<T, TP> public abstract class EdgeDetector2DFilter<TColor, TPacked> : Convolution2DFilter<TColor, TPacked>, IEdgeDetectorFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public bool Grayscale { get; set; } public bool Grayscale { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnApply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle) protected override void OnApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{ {
if (this.Grayscale) if (this.Grayscale)
{ {
new GrayscaleBt709Processor<T, TP>().Apply(source, source, sourceRectangle); new GrayscaleBt709Processor<TColor, TPacked>().Apply(source, source, sourceRectangle);
} }
} }
} }

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/EdgeDetectorFilter.cs

@ -9,19 +9,19 @@ namespace ImageProcessorCore.Processors
/// Defines a filter that detects edges within an image using a single /// Defines a filter that detects edges within an image using a single
/// two dimensional matrix. /// two dimensional matrix.
/// </summary> /// </summary>
public abstract class EdgeDetectorFilter<T, TP> : ConvolutionFilter<T, TP>, IEdgeDetectorFilter<T, TP> public abstract class EdgeDetectorFilter<TColor, TPacked> : ConvolutionFilter<TColor, TPacked>, IEdgeDetectorFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public bool Grayscale { get; set; } public bool Grayscale { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnApply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle) protected override void OnApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{ {
if (this.Grayscale) if (this.Grayscale)
{ {
new GrayscaleBt709Processor<T, TP>().Apply(source, source, sourceRectangle); new GrayscaleBt709Processor<TColor, TPacked>().Apply(source, source, sourceRectangle);
} }
} }
} }

6
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/IEdgeDetectorFilter.cs

@ -8,9 +8,9 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Provides properties and methods allowing the detection of edges within an image. /// Provides properties and methods allowing the detection of edges within an image.
/// </summary> /// </summary>
public interface IEdgeDetectorFilter<T, TP> : IImageProcessor<T, TP>, IEdgeDetectorFilter public interface IEdgeDetectorFilter<TColor, TPacked> : IImageProcessor<TColor, TPacked>, IEdgeDetectorFilter
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
} }

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KayyaliProcessor.cs

@ -9,11 +9,11 @@ namespace ImageProcessorCore.Processors
/// The Kayyali operator filter. /// The Kayyali operator filter.
/// <see href="http://edgedetection.webs.com/"/> /// <see href="http://edgedetection.webs.com/"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class KayyaliProcessor<T, TP> : EdgeDetector2DFilter<T, TP> public class KayyaliProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override float[,] KernelX => new float[,] public override float[,] KernelX => new float[,]

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/KirschProcessor.cs

@ -9,11 +9,11 @@ namespace ImageProcessorCore.Processors
/// The Kirsch operator filter. /// The Kirsch operator filter.
/// <see href="http://en.wikipedia.org/wiki/Kirsch_operator"/> /// <see href="http://en.wikipedia.org/wiki/Kirsch_operator"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class KirschProcessor<T, TP> : EdgeDetector2DFilter<T, TP> public class KirschProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override float[,] KernelX => new float[,] public override float[,] KernelX => new float[,]

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian3X3Processor.cs

@ -9,11 +9,11 @@ namespace ImageProcessorCore.Processors
/// The Laplacian 3 x 3 operator filter. /// The Laplacian 3 x 3 operator filter.
/// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/> /// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class Laplacian3X3Processor<T, TP> : EdgeDetectorFilter<T, TP> public class Laplacian3X3Processor<TColor, TPacked> : EdgeDetectorFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override float[,] KernelXY => new float[,] public override float[,] KernelXY => new float[,]

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/Laplacian5X5Processor.cs

@ -9,11 +9,11 @@ namespace ImageProcessorCore.Processors
/// The Laplacian 5 x 5 operator filter. /// The Laplacian 5 x 5 operator filter.
/// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/> /// <see href="http://en.wikipedia.org/wiki/Discrete_Laplace_operator"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class Laplacian5X5Processor<T, TP> : EdgeDetectorFilter<T, TP> public class Laplacian5X5Processor<TColor, TPacked> : EdgeDetectorFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override float[,] KernelXY => new float[,] public override float[,] KernelXY => new float[,]

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/LaplacianOfGaussianProcessor.cs

@ -9,11 +9,11 @@ namespace ImageProcessorCore.Processors
/// The Laplacian of Gaussian operator filter. /// The Laplacian of Gaussian operator filter.
/// <see href="http://fourier.eng.hmc.edu/e161/lectures/gradient/node8.html"/> /// <see href="http://fourier.eng.hmc.edu/e161/lectures/gradient/node8.html"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class LaplacianOfGaussianProcessor<T, TP> : EdgeDetectorFilter<T, TP> public class LaplacianOfGaussianProcessor<TColor, TPacked> : EdgeDetectorFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override float[,] KernelXY => new float[,] public override float[,] KernelXY => new float[,]

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/PrewittProcessor.cs

@ -9,11 +9,11 @@ namespace ImageProcessorCore.Processors
/// The Prewitt operator filter. /// The Prewitt operator filter.
/// <see href="http://en.wikipedia.org/wiki/Prewitt_operator"/> /// <see href="http://en.wikipedia.org/wiki/Prewitt_operator"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class PrewittProcessor<T, TP> : EdgeDetector2DFilter<T, TP> public class PrewittProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override float[,] KernelX => new float[,] public override float[,] KernelX => new float[,]

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/RobertsCrossProcessor.cs

@ -9,11 +9,11 @@ namespace ImageProcessorCore.Processors
/// The Roberts Cross operator filter. /// The Roberts Cross operator filter.
/// <see href="http://en.wikipedia.org/wiki/Roberts_cross"/> /// <see href="http://en.wikipedia.org/wiki/Roberts_cross"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class RobertsCrossProcessor<T, TP> : EdgeDetector2DFilter<T, TP> public class RobertsCrossProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override float[,] KernelX => new float[,] public override float[,] KernelX => new float[,]

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/ScharrProcessor.cs

@ -9,11 +9,11 @@ namespace ImageProcessorCore.Processors
/// The Scharr operator filter. /// The Scharr operator filter.
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator#Alternative_operators"/> /// <see href="http://en.wikipedia.org/wiki/Sobel_operator#Alternative_operators"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class ScharrProcessor<T, TP> : EdgeDetector2DFilter<T, TP> public class ScharrProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override float[,] KernelX => new float[,] public override float[,] KernelX => new float[,]

10
src/ImageProcessorCore/Filters/Processors/Convolution/EdgeDetection/SobelProcessor.cs

@ -9,11 +9,11 @@ namespace ImageProcessorCore.Processors
/// The Sobel operator filter. /// The Sobel operator filter.
/// <see href="http://en.wikipedia.org/wiki/Sobel_operator"/> /// <see href="http://en.wikipedia.org/wiki/Sobel_operator"/>
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class SobelProcessor<T, TP> : EdgeDetector2DFilter<T, TP> public class SobelProcessor<TColor, TPacked> : EdgeDetector2DFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
public override float[,] KernelX => new float[,] public override float[,] KernelX => new float[,]

12
src/ImageProcessorCore/Filters/Processors/Convolution/GuassianBlurProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Applies a Gaussian blur filter to the image. /// Applies a Gaussian blur filter to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class GuassianBlurProcessor<T, TP> : Convolution2PassFilter<T, TP> public class GuassianBlurProcessor<TColor, TPacked> : Convolution2PassFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// The maximum size of the kernal in either direction. /// The maximum size of the kernal in either direction.
@ -81,7 +81,7 @@ namespace ImageProcessorCore.Processors
public override float[,] KernelY => this.kernelY; public override float[,] KernelY => this.kernelY;
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnApply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle) protected override void OnApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{ {
if (this.kernelY == null) if (this.kernelY == null)
{ {

12
src/ImageProcessorCore/Filters/Processors/Convolution/GuassianSharpenProcessor.cs

@ -10,11 +10,11 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Applies a Gaussian sharpening filter to the image. /// Applies a Gaussian sharpening filter to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class GuassianSharpenProcessor<T, TP> : Convolution2PassFilter<T, TP> public class GuassianSharpenProcessor<TColor, TPacked> : Convolution2PassFilter<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// The maximum size of the kernal in either direction. /// The maximum size of the kernal in either direction.
@ -83,7 +83,7 @@ namespace ImageProcessorCore.Processors
public override float[,] KernelY => this.kernelY; public override float[,] KernelY => this.kernelY;
/// <inheritdoc/> /// <inheritdoc/>
protected override void OnApply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle) protected override void OnApply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle)
{ {
if (this.kernelY == null) if (this.kernelY == null)
{ {

28
src/ImageProcessorCore/Filters/Processors/GlowProcessor.cs

@ -10,20 +10,20 @@ namespace ImageProcessorCore.Processors
using System.Threading.Tasks; using System.Threading.Tasks;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> that applies a radial glow effect an <see cref="Image{T,TP}"/>. /// An <see cref="IImageProcessor{TColor, TPacked}"/> that applies a radial glow effect an <see cref="Image{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class GlowProcessor<T, TP> : ImageProcessor<T, TP> public class GlowProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="GlowProcessor{T,TP}"/> class. /// Initializes a new instance of the <see cref="GlowProcessor{TColor, TPacked}"/> class.
/// </summary> /// </summary>
public GlowProcessor() public GlowProcessor()
{ {
T color = default(T); TColor color = default(TColor);
color.PackFromVector4(Color.Black.ToVector4()); color.PackFromVector4(Color.Black.ToVector4());
this.GlowColor = color; this.GlowColor = color;
} }
@ -31,7 +31,7 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Gets or sets the glow color to apply. /// Gets or sets the glow color to apply.
/// </summary> /// </summary>
public T GlowColor { get; set; } public TColor GlowColor { get; set; }
/// <summary> /// <summary>
/// Gets or sets the the radius. /// Gets or sets the the radius.
@ -39,11 +39,11 @@ namespace ImageProcessorCore.Processors
public float Radius { get; set; } public float Radius { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
int endX = sourceRectangle.Right; int endX = sourceRectangle.Right;
T glowColor = this.GlowColor; TColor glowColor = this.GlowColor;
Vector2 centre = Rectangle.Center(sourceRectangle).ToVector2(); Vector2 centre = Rectangle.Center(sourceRectangle).ToVector2();
float maxDistance = this.Radius > 0 ? Math.Min(this.Radius, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F; float maxDistance = this.Radius > 0 ? Math.Min(this.Radius, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F;
Ellipse ellipse = new Ellipse(new Point(centre), maxDistance, maxDistance); Ellipse ellipse = new Ellipse(new Point(centre), maxDistance, maxDistance);
@ -65,8 +65,8 @@ namespace ImageProcessorCore.Processors
startY = 0; startY = 0;
} }
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -83,7 +83,7 @@ namespace ImageProcessorCore.Processors
// TODO: Premultiply? // TODO: Premultiply?
float distance = Vector2.Distance(centre, new Vector2(offsetX, offsetY)); float distance = Vector2.Distance(centre, new Vector2(offsetX, offsetY));
Vector4 sourceColor = sourcePixels[offsetX, offsetY].ToVector4(); Vector4 sourceColor = sourcePixels[offsetX, offsetY].ToVector4();
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(Vector4.Lerp(glowColor.ToVector4(), sourceColor, distance / maxDistance)); packed.PackFromVector4(Vector4.Lerp(glowColor.ToVector4(), sourceColor, distance / maxDistance));
targetPixels[offsetX, offsetY] = packed; targetPixels[offsetX, offsetY] = packed;
} }

20
src/ImageProcessorCore/Filters/Processors/InvertProcessor.cs

@ -10,16 +10,16 @@ namespace ImageProcessorCore.Processors
using System.Threading.Tasks; using System.Threading.Tasks;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> to invert the colors of an <see cref="Image{T,TP}"/>. /// An <see cref="IImageProcessor{TColor, TPacked}"/> to invert the colors of an <see cref="Image{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class InvertProcessor<T, TP> : ImageProcessor<T, TP> public class InvertProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
int endX = sourceRectangle.Right; int endX = sourceRectangle.Right;
@ -42,8 +42,8 @@ namespace ImageProcessorCore.Processors
startY = 0; startY = 0;
} }
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -58,7 +58,7 @@ namespace ImageProcessorCore.Processors
Vector4 color = sourcePixels[offsetX, offsetY].ToVector4(); Vector4 color = sourcePixels[offsetX, offsetY].ToVector4();
Vector3 vector = inverseVector - new Vector3(color.X, color.Y, color.Z); Vector3 vector = inverseVector - new Vector3(color.X, color.Y, color.Z);
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(new Vector4(vector, color.W)); packed.PackFromVector4(new Vector4(vector, color.W));
targetPixels[offsetX, offsetY] = packed; targetPixels[offsetX, offsetY] = packed;
} }

22
src/ImageProcessorCore/Filters/Processors/PixelateProcessor.cs

@ -10,16 +10,16 @@ namespace ImageProcessorCore.Processors
using System.Threading.Tasks; using System.Threading.Tasks;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> to pixelate the colors of an <see cref="Image{T,TP}"/>. /// An <see cref="IImageProcessor{TColor, TPacked}"/> to pixelate the colors of an <see cref="Image{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class PixelateProcessor<T, TP> : ImageProcessor<T, TP> public class PixelateProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PixelateProcessor{T,TP}"/> class. /// Initializes a new instance of the <see cref="PixelateProcessor{TColor, TPacked}"/> class.
/// </summary> /// </summary>
/// <param name="size">The size of the pixels. Must be greater than 0.</param> /// <param name="size">The size of the pixels. Must be greater than 0.</param>
/// <exception cref="System.ArgumentException"> /// <exception cref="System.ArgumentException">
@ -37,7 +37,7 @@ namespace ImageProcessorCore.Processors
public int Value { get; } public int Value { get; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
int endX = sourceRectangle.Right; int endX = sourceRectangle.Right;
@ -64,8 +64,8 @@ namespace ImageProcessorCore.Processors
// Get the range on the y-plane to choose from. // Get the range on the y-plane to choose from.
IEnumerable<int> range = EnumerableExtensions.SteppedRange(minY, i => i < maxY, size); IEnumerable<int> range = EnumerableExtensions.SteppedRange(minY, i => i < maxY, size);
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.ForEach( Parallel.ForEach(
range, range,
@ -93,7 +93,7 @@ namespace ImageProcessorCore.Processors
// Get the pixel color in the centre of the soon to be pixelated area. // Get the pixel color in the centre of the soon to be pixelated area.
// ReSharper disable AccessToDisposedClosure // ReSharper disable AccessToDisposedClosure
T pixel = sourcePixels[offsetX + offsetPx, offsetY + offsetPy]; TColor pixel = sourcePixels[offsetX + offsetPx, offsetY + offsetPy];
// For each pixel in the pixelate size, set it to the centre color. // For each pixel in the pixelate size, set it to the centre color.
for (int l = offsetY; l < offsetY + size && l < maxY; l++) for (int l = offsetY; l < offsetY + size && l < maxY; l++)

28
src/ImageProcessorCore/Filters/Processors/VignetteProcessor.cs

@ -10,20 +10,20 @@ namespace ImageProcessorCore.Processors
using System.Threading.Tasks; using System.Threading.Tasks;
/// <summary> /// <summary>
/// An <see cref="IImageProcessor{T,TP}"/> that applies a radial vignette effect to an <see cref="Image{T,TP}"/>. /// An <see cref="IImageProcessor{TColor, TPacked}"/> that applies a radial vignette effect to an <see cref="Image{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
public class VignetteProcessor<T, TP> : ImageProcessor<T, TP> public class VignetteProcessor<TColor, TPacked> : ImageProcessor<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="VignetteProcessor{T,TP}"/> class. /// Initializes a new instance of the <see cref="VignetteProcessor{TColor, TPacked}"/> class.
/// </summary> /// </summary>
public VignetteProcessor() public VignetteProcessor()
{ {
T color = default(T); TColor color = default(TColor);
color.PackFromVector4(Color.Black.ToVector4()); color.PackFromVector4(Color.Black.ToVector4());
this.VignetteColor = color; this.VignetteColor = color;
} }
@ -31,7 +31,7 @@ namespace ImageProcessorCore.Processors
/// <summary> /// <summary>
/// Gets or sets the vignette color to apply. /// Gets or sets the vignette color to apply.
/// </summary> /// </summary>
public T VignetteColor { get; set; } public TColor VignetteColor { get; set; }
/// <summary> /// <summary>
/// Gets or sets the the x-radius. /// Gets or sets the the x-radius.
@ -44,11 +44,11 @@ namespace ImageProcessorCore.Processors
public float RadiusY { get; set; } public float RadiusY { get; set; }
/// <inheritdoc/> /// <inheritdoc/>
protected override void Apply(ImageBase<T, TP> target, ImageBase<T, TP> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) protected override void Apply(ImageBase<TColor, TPacked> target, ImageBase<TColor, TPacked> source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY)
{ {
int startX = sourceRectangle.X; int startX = sourceRectangle.X;
int endX = sourceRectangle.Right; int endX = sourceRectangle.Right;
T vignetteColor = this.VignetteColor; TColor vignetteColor = this.VignetteColor;
Vector2 centre = Rectangle.Center(sourceRectangle).ToVector2(); Vector2 centre = Rectangle.Center(sourceRectangle).ToVector2();
float rX = this.RadiusX > 0 ? Math.Min(this.RadiusX, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F; float rX = this.RadiusX > 0 ? Math.Min(this.RadiusX, sourceRectangle.Width * .5F) : sourceRectangle.Width * .5F;
float rY = this.RadiusY > 0 ? Math.Min(this.RadiusY, sourceRectangle.Height * .5F) : sourceRectangle.Height * .5F; float rY = this.RadiusY > 0 ? Math.Min(this.RadiusY, sourceRectangle.Height * .5F) : sourceRectangle.Height * .5F;
@ -71,8 +71,8 @@ namespace ImageProcessorCore.Processors
startY = 0; startY = 0;
} }
using (IPixelAccessor<T, TP> sourcePixels = source.Lock()) using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (IPixelAccessor<T, TP> targetPixels = target.Lock()) using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock())
{ {
Parallel.For( Parallel.For(
minY, minY,
@ -86,7 +86,7 @@ namespace ImageProcessorCore.Processors
int offsetX = x - startX; int offsetX = x - startX;
float distance = Vector2.Distance(centre, new Vector2(offsetX, offsetY)); float distance = Vector2.Distance(centre, new Vector2(offsetX, offsetY));
Vector4 sourceColor = sourcePixels[offsetX, offsetY].ToVector4(); Vector4 sourceColor = sourcePixels[offsetX, offsetY].ToVector4();
T packed = default(T); TColor packed = default(TColor);
packed.PackFromVector4(Vector4.Lerp(vignetteColor.ToVector4(), sourceColor, 1 - (.9F * (distance / maxDistance)))); packed.PackFromVector4(Vector4.Lerp(vignetteColor.ToVector4(), sourceColor, 1 - (.9F * (distance / maxDistance))));
targetPixels[offsetX, offsetY] = packed; targetPixels[offsetX, offsetY] = packed;
} }

28
src/ImageProcessorCore/Filters/Saturation.cs

@ -8,22 +8,22 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Alters the saturation component of the image. /// Alters the saturation component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param> /// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Saturation<T, TP>(this Image<T, TP> source, int amount, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Saturation<TColor, TPacked>(this Image<TColor, TPacked> source, int amount, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Saturation(source, amount, source.Bounds, progressHandler); return Saturation(source, amount, source.Bounds, progressHandler);
} }
@ -31,20 +31,20 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Alters the saturation component of the image. /// Alters the saturation component of the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param> /// <param name="amount">The new saturation of the image. Must be between -100 and 100.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Saturation<T, TP>(this Image<T, TP> source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Saturation<TColor, TPacked>(this Image<TColor, TPacked> source, int amount, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
SaturationProcessor<T, TP> processor = new SaturationProcessor<T, TP>(amount); SaturationProcessor<TColor, TPacked> processor = new SaturationProcessor<TColor, TPacked>(amount);
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

24
src/ImageProcessorCore/Filters/Sepia.cs

@ -8,21 +8,21 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies sepia toning to the image. /// Applies sepia toning to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image<T, TP> Sepia<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Sepia<TColor, TPacked>(this Image<TColor, TPacked> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Sepia(source, source.Bounds, progressHandler); return Sepia(source, source.Bounds, progressHandler);
} }
@ -30,19 +30,19 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies sepia toning to the image. /// Applies sepia toning to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image"/>.</returns> /// <returns>The <see cref="Image"/>.</returns>
public static Image<T, TP> Sepia<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Sepia<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
SepiaProcessor<T, TP> processor = new SepiaProcessor<T, TP>(); SepiaProcessor<TColor, TPacked> processor = new SepiaProcessor<TColor, TPacked>();
processor.OnProgress += progressHandler; processor.OnProgress += progressHandler;
try try

72
src/ImageProcessorCore/Filters/Vignette.cs

@ -8,37 +8,37 @@ namespace ImageProcessorCore
using Processors; using Processors;
/// <summary> /// <summary>
/// Extension methods for the <see cref="Image{T,TP}"/> type. /// Extension methods for the <see cref="Image{TColor, TPacked}"/> type.
/// </summary> /// </summary>
public static partial class ImageExtensions public static partial class ImageExtensions
{ {
/// <summary> /// <summary>
/// Applies a radial vignette effect to an image. /// Applies a radial vignette effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Vignette<T, TP>(this Image<T, TP> source, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Vignette<TColor, TPacked>(this Image<TColor, TPacked> source, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Vignette(source, default(T), source.Bounds.Width * .5F, source.Bounds.Height * .5F, source.Bounds, progressHandler); return Vignette(source, default(TColor), source.Bounds.Width * .5F, source.Bounds.Height * .5F, source.Bounds, progressHandler);
} }
/// <summary> /// <summary>
/// Applies a radial vignette effect to an image. /// Applies a radial vignette effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the vignette.</param> /// <param name="color">The color to set as the vignette.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Vignette<T, TP>(this Image<T, TP> source, T color, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Vignette<TColor, TPacked>(this Image<TColor, TPacked> source, TColor color, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Vignette(source, color, source.Bounds.Width * .5F, source.Bounds.Height * .5F, source.Bounds, progressHandler); return Vignette(source, color, source.Bounds.Width * .5F, source.Bounds.Height * .5F, source.Bounds, progressHandler);
} }
@ -46,43 +46,43 @@ namespace ImageProcessorCore
/// <summary> /// <summary>
/// Applies a radial vignette effect to an image. /// Applies a radial vignette effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="radiusX">The the x-radius.</param> /// <param name="radiusX">The the x-radius.</param>
/// <param name="radiusY">The the y-radius.</param> /// <param name="radiusY">The the y-radius.</param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Vignette<T, TP>(this Image<T, TP> source, float radiusX, float radiusY, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Vignette<TColor, TPacked>(this Image<TColor, TPacked> source, float radiusX, float radiusY, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Vignette(source, default(T), radiusX, radiusY, source.Bounds, progressHandler); return Vignette(source, default(TColor), radiusX, radiusY, source.Bounds, progressHandler);
} }
/// <summary> /// <summary>
/// Applies a radial vignette effect to an image. /// Applies a radial vignette effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="rectangle"> /// <param name="rectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Vignette<T, TP>(this Image<T, TP> source, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Vignette<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
return Vignette(source, default(T), 0, 0, rectangle, progressHandler); return Vignette(source, default(TColor), 0, 0, rectangle, progressHandler);
} }
/// <summary> /// <summary>
/// Applies a radial vignette effect to an image. /// Applies a radial vignette effect to an image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image this method extends.</param> /// <param name="source">The image this method extends.</param>
/// <param name="color">The color to set as the vignette.</param> /// <param name="color">The color to set as the vignette.</param>
/// <param name="radiusX">The the x-radius.</param> /// <param name="radiusX">The the x-radius.</param>
@ -91,14 +91,14 @@ namespace ImageProcessorCore
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter. /// The <see cref="Rectangle"/> structure that specifies the portion of the image object to alter.
/// </param> /// </param>
/// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param> /// <param name="progressHandler">A delegate which is called as progress is made processing the image.</param>
/// <returns>The <see cref="Image{T,TP}"/>.</returns> /// <returns>The <see cref="Image{TColor, TPacked}"/>.</returns>
public static Image<T, TP> Vignette<T, TP>(this Image<T, TP> source, T color, float radiusX, float radiusY, Rectangle rectangle, ProgressEventHandler progressHandler = null) public static Image<TColor, TPacked> Vignette<TColor, TPacked>(this Image<TColor, TPacked> source, TColor color, float radiusX, float radiusY, Rectangle rectangle, ProgressEventHandler progressHandler = null)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
VignetteProcessor<T, TP> processor = new VignetteProcessor<T, TP> { RadiusX = radiusX, RadiusY = radiusY }; VignetteProcessor<TColor, TPacked> processor = new VignetteProcessor<TColor, TPacked> { RadiusX = radiusX, RadiusY = radiusY };
if (!color.Equals(default(T))) if (!color.Equals(default(TColor)))
{ {
processor.VignetteColor = color; processor.VignetteColor = color;
} }

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

@ -70,9 +70,9 @@ namespace ImageProcessorCore.Formats
} }
/// <inheritdoc/> /// <inheritdoc/>
public void Decode<T, TP>(Image<T, TP> image, Stream stream) public void Decode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Guard.NotNull(image, "image"); Guard.NotNull(image, "image");
Guard.NotNull(stream, "stream"); Guard.NotNull(stream, "stream");

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

@ -49,20 +49,20 @@ 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 pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, 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 stream, where the image should be /// <param name="stream">The stream, where the image should be
/// decoded from. Cannot be null (Nothing in Visual Basic).</param> /// decoded from. Cannot be null (Nothing in Visual Basic).</param>
/// <exception cref="ArgumentNullException"> /// <exception cref="System.ArgumentNullException">
/// <para><paramref name="image"/> is null.</para> /// <para><paramref name="image"/> is null.</para>
/// <para>- or -</para> /// <para>- or -</para>
/// <para><paramref name="stream"/> is null.</para> /// <para><paramref name="stream"/> is null.</para>
/// </exception> /// </exception>
public void Decode<T, TP>(Image<T, TP> image, Stream stream) public void Decode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
this.currentStream = stream; this.currentStream = stream;
@ -121,7 +121,7 @@ namespace ImageProcessorCore.Formats
+ $"bigger then the max allowed size '{image.MaxWidth}x{image.MaxHeight}'"); + $"bigger then the max allowed size '{image.MaxWidth}x{image.MaxHeight}'");
} }
T[] imageData = new T[this.infoHeader.Width * this.infoHeader.Height]; TColor[] imageData = new TColor[this.infoHeader.Width * this.infoHeader.Height];
switch (this.infoHeader.Compression) switch (this.infoHeader.Compression)
{ {
@ -134,19 +134,19 @@ namespace ImageProcessorCore.Formats
if (this.infoHeader.BitsPerPixel == 32) if (this.infoHeader.BitsPerPixel == 32)
{ {
this.ReadRgb32<T, TP>(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted); this.ReadRgb32<TColor, TPacked>(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted);
} }
else if (this.infoHeader.BitsPerPixel == 24) else if (this.infoHeader.BitsPerPixel == 24)
{ {
this.ReadRgb24<T, TP>(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted); this.ReadRgb24<TColor, TPacked>(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted);
} }
else if (this.infoHeader.BitsPerPixel == 16) else if (this.infoHeader.BitsPerPixel == 16)
{ {
this.ReadRgb16<T, TP>(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted); this.ReadRgb16<TColor, TPacked>(imageData, this.infoHeader.Width, this.infoHeader.Height, inverted);
} }
else if (this.infoHeader.BitsPerPixel <= 8) else if (this.infoHeader.BitsPerPixel <= 8)
{ {
this.ReadRgbPalette<T, TP>(imageData, palette, this.infoHeader.Width, this.infoHeader.Height, this.infoHeader.BitsPerPixel, inverted); this.ReadRgbPalette<TColor, TPacked>(imageData, palette, this.infoHeader.Width, this.infoHeader.Height, this.infoHeader.BitsPerPixel, inverted);
} }
break; break;
@ -188,17 +188,17 @@ 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 pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, 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:TColor[]"/> 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>
/// <param name="height">The height 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="bits">The number of bits per pixel.</param>
/// <param name="inverted">Whether the bitmap is inverted.</param> /// <param name="inverted">Whether the bitmap is inverted.</param>
private void ReadRgbPalette<T, TP>(T[] imageData, byte[] colors, int width, int height, int bits, bool inverted) private void ReadRgbPalette<TColor, TPacked>(TColor[] imageData, byte[] colors, int width, int height, int bits, bool inverted)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
// Pixels per byte (bits per pixel) // Pixels per byte (bits per pixel)
int ppb = 8 / bits; int ppb = 8 / bits;
@ -242,7 +242,7 @@ namespace ImageProcessorCore.Formats
int arrayOffset = (row * width) + (colOffset + shift); int arrayOffset = (row * width) + (colOffset + shift);
// Stored in b-> g-> r order. // Stored in b-> g-> r order.
T packed = default(T); TColor packed = default(TColor);
packed.PackFromBytes(colors[colorIndex + 2], colors[colorIndex + 1], colors[colorIndex], 255); packed.PackFromBytes(colors[colorIndex + 2], colors[colorIndex + 1], colors[colorIndex], 255);
imageData[arrayOffset] = packed; imageData[arrayOffset] = packed;
} }
@ -253,15 +253,15 @@ 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 pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, 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:TColor[]"/> 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>
/// <param name="inverted">Whether the bitmap is inverted.</param> /// <param name="inverted">Whether the bitmap is inverted.</param>
private void ReadRgb16<T, TP>(T[] imageData, int width, int height, bool inverted) private void ReadRgb16<TColor, TPacked>(TColor[] imageData, int width, int height, bool inverted)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
// We divide here as we will store the colors in our floating point format. // We divide here as we will store the colors in our floating point format.
const int ScaleR = 8; // 256/32 const int ScaleR = 8; // 256/32
@ -294,7 +294,7 @@ namespace ImageProcessorCore.Formats
int arrayOffset = ((row * width) + x); int arrayOffset = ((row * width) + x);
// Stored in b-> g-> r order. // Stored in b-> g-> r order.
T packed = default(T); TColor packed = default(TColor);
packed.PackFromBytes(r, g, b, 255); packed.PackFromBytes(r, g, b, 255);
imageData[arrayOffset] = packed; imageData[arrayOffset] = packed;
} }
@ -304,15 +304,15 @@ 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 pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, 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:TColor[]"/> 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>
/// <param name="inverted">Whether the bitmap is inverted.</param> /// <param name="inverted">Whether the bitmap is inverted.</param>
private void ReadRgb24<T, TP>(T[] imageData, int width, int height, bool inverted) private void ReadRgb24<TColor, TPacked>(TColor[] imageData, int width, int height, bool inverted)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
int alignment; int alignment;
byte[] data = this.GetImageArray(width, height, 3, out alignment); byte[] data = this.GetImageArray(width, height, 3, out alignment);
@ -335,7 +335,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); TColor packed = default(TColor);
packed.PackFromBytes(data[offset + 2], data[offset + 1], data[offset], 255); packed.PackFromBytes(data[offset + 2], data[offset + 1], data[offset], 255);
imageData[arrayOffset] = packed; imageData[arrayOffset] = packed;
} }
@ -345,15 +345,15 @@ 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 pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, 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:TColor[]"/> 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>
/// <param name="inverted">Whether the bitmap is inverted.</param> /// <param name="inverted">Whether the bitmap is inverted.</param>
private void ReadRgb32<T, TP>(T[] imageData, int width, int height, bool inverted) private void ReadRgb32<TColor, TPacked>(TColor[] imageData, int width, int height, bool inverted)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
int alignment; int alignment;
byte[] data = this.GetImageArray(width, height, 4, out alignment); byte[] data = this.GetImageArray(width, height, 4, out alignment);
@ -375,7 +375,7 @@ 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-> a order.
T packed = default(T); TColor packed = default(TColor);
packed.PackFromBytes(data[offset + 2], data[offset + 1], data[offset], data[offset + 3]); packed.PackFromBytes(data[offset + 2], data[offset + 1], data[offset], data[offset + 3]);
imageData[arrayOffset] = packed; imageData[arrayOffset] = packed;
} }

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

@ -43,9 +43,9 @@ namespace ImageProcessorCore.Formats
} }
/// <inheritdoc/> /// <inheritdoc/>
public void Encode<T,TP>(Image<T,TP> image, Stream stream) public void Encode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
BmpEncoderCore encoder = new BmpEncoderCore(); BmpEncoderCore encoder = new BmpEncoderCore();
encoder.Encode(image, stream, this.BitsPerPixel); encoder.Encode(image, stream, this.BitsPerPixel);

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

@ -25,16 +25,16 @@ namespace ImageProcessorCore.Formats
private int padding; private int padding;
/// <summary> /// <summary>
/// Encodes the image to the specified stream from the <see cref="ImageBase{T,TP}"/>. /// Encodes the image to the specified stream from the <see cref="ImageBase{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The <see cref="ImageBase{T,TP}"/> to encode from.</param> /// <param name="image">The <see cref="ImageBase{TColor, TPacked}"/> 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<TColor, TPacked>(ImageBase<TColor, TPacked> image, Stream stream, BmpBitsPerPixel bitsPerPixel)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Guard.NotNull(image, nameof(image)); Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
@ -119,17 +119,17 @@ 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 pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, 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="image"> /// <param name="image">
/// The <see cref="ImageBase{T,TP}"/> containing pixel data. /// The <see cref="ImageBase{TColor, TPacked}"/> containing pixel data.
/// </param> /// </param>
private void WriteImage<T, TP>(EndianBinaryWriter writer, ImageBase<T, TP> image) private void WriteImage<TColor, TPacked>(EndianBinaryWriter writer, ImageBase<TColor, TPacked> image)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
using (IPixelAccessor<T, TP> pixels = image.Lock()) using (PixelAccessor<TColor, TPacked> pixels = image.Lock())
{ {
switch (this.bmpBitsPerPixel) switch (this.bmpBitsPerPixel)
{ {
@ -147,13 +147,13 @@ 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 pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, 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>
private void Write32Bit<T, TP>(EndianBinaryWriter writer, IPixelAccessor<T, TP> pixels) private void Write32Bit<TColor, TPacked>(EndianBinaryWriter writer, PixelAccessor<TColor, TPacked> pixels)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
for (int y = pixels.Height - 1; y >= 0; y--) for (int y = pixels.Height - 1; y >= 0; y--)
{ {
@ -175,12 +175,12 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the 24bit color palette to the stream. /// Writes the 24bit color palette to the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">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> /// <typeparam name="TPacked">The packed format. <example>uint, 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>
private void Write24Bit<T, TP>(EndianBinaryWriter writer, IPixelAccessor<T, TP> pixels) private void Write24Bit<TColor, TPacked>(EndianBinaryWriter writer, PixelAccessor<TColor, TPacked> pixels)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
for (int y = pixels.Height - 1; y >= 0; y--) for (int y = pixels.Height - 1; y >= 0; y--)
{ {

8
src/ImageProcessorCore/Formats/Gif/GifDecoder.cs

@ -55,11 +55,11 @@ namespace ImageProcessorCore.Formats
} }
/// <inheritdoc/> /// <inheritdoc/>
public void Decode<T, TP>(Image<T, TP> image, Stream stream) public void Decode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
new GifDecoderCore<T, TP>().Decode(image, stream); new GifDecoderCore<TColor, TPacked>().Decode(image, stream);
} }
} }
} }

32
src/ImageProcessorCore/Formats/Gif/GifDecoderCore.cs

@ -11,16 +11,16 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Performs the gif decoding operation. /// Performs the gif decoding operation.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
internal class GifDecoderCore<T, TP> internal class GifDecoderCore<TColor, TPacked>
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
/// <summary> /// <summary>
/// The image to decode the information to. /// The image to decode the information to.
/// </summary> /// </summary>
private Image<T, TP> decodedImage; private Image<TColor, TPacked> decodedImage;
/// <summary> /// <summary>
/// The currently loaded stream. /// The currently loaded stream.
@ -35,7 +35,7 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// The current frame. /// The current frame.
/// </summary> /// </summary>
private T[] currentFrame; private TColor[] currentFrame;
/// <summary> /// <summary>
/// The logical screen descriptor. /// The logical screen descriptor.
@ -52,7 +52,7 @@ namespace ImageProcessorCore.Formats
/// </summary> /// </summary>
/// <param name="image">The image to decode to.</param> /// <param name="image">The image to decode to.</param>
/// <param name="stream">The stream containing image data. </param> /// <param name="stream">The stream containing image data. </param>
public void Decode(Image<T, TP> image, Stream stream) public void Decode(Image<TColor, TPacked> image, Stream stream)
{ {
this.decodedImage = image; this.decodedImage = image;
@ -292,15 +292,15 @@ namespace ImageProcessorCore.Formats
if (this.currentFrame == null) if (this.currentFrame == null)
{ {
this.currentFrame = new T[imageWidth * imageHeight]; this.currentFrame = new TColor[imageWidth * imageHeight];
} }
T[] lastFrame = null; TColor[] lastFrame = null;
if (this.graphicsControlExtension != null && if (this.graphicsControlExtension != null &&
this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToPrevious) this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToPrevious)
{ {
lastFrame = new T[imageWidth * imageHeight]; lastFrame = new TColor[imageWidth * imageHeight];
Array.Copy(this.currentFrame, lastFrame, lastFrame.Length); Array.Copy(this.currentFrame, lastFrame, lastFrame.Length);
} }
@ -359,7 +359,7 @@ namespace ImageProcessorCore.Formats
// Stored in r-> g-> b-> a order. // Stored in r-> g-> b-> a order.
int indexOffset = index * 3; int indexOffset = index * 3;
T pixel = default(T); TColor pixel = default(TColor);
pixel.PackFromBytes(colorTable[indexOffset], colorTable[indexOffset + 1], colorTable[indexOffset + 2], 255); pixel.PackFromBytes(colorTable[indexOffset], colorTable[indexOffset + 1], colorTable[indexOffset + 2], 255);
this.currentFrame[offset] = pixel; this.currentFrame[offset] = pixel;
} }
@ -368,11 +368,11 @@ namespace ImageProcessorCore.Formats
} }
} }
T[] pixels = new T[imageWidth * imageHeight]; TColor[] pixels = new TColor[imageWidth * imageHeight];
Array.Copy(this.currentFrame, pixels, pixels.Length); Array.Copy(this.currentFrame, pixels, pixels.Length);
ImageBase<T, TP> currentImage; ImageBase<TColor, TPacked> currentImage;
if (this.decodedImage.Pixels == null) if (this.decodedImage.Pixels == null)
{ {
@ -387,7 +387,7 @@ namespace ImageProcessorCore.Formats
} }
else else
{ {
ImageFrame<T, TP> frame = new ImageFrame<T, TP>(); ImageFrame<TColor, TPacked> frame = new ImageFrame<TColor, TPacked>();
currentImage = frame; currentImage = frame;
currentImage.SetPixels(imageWidth, imageHeight, pixels); currentImage.SetPixels(imageWidth, imageHeight, pixels);
@ -412,7 +412,7 @@ namespace ImageProcessorCore.Formats
offset = (y * imageWidth) + x; offset = (y * imageWidth) + x;
// Stored in r-> g-> b-> a order. // Stored in r-> g-> b-> a order.
this.currentFrame[offset] = default(T); this.currentFrame[offset] = default(TColor);
} }
} }
} }

6
src/ImageProcessorCore/Formats/Gif/GifEncoder.cs

@ -47,9 +47,9 @@ namespace ImageProcessorCore.Formats
} }
/// <inheritdoc/> /// <inheritdoc/>
public void Encode<T,TP>(Image<T,TP> image, Stream stream) public void Encode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
GifEncoderCore encoder = new GifEncoderCore GifEncoderCore encoder = new GifEncoderCore
{ {

82
src/ImageProcessorCore/Formats/Gif/GifEncoderCore.cs

@ -40,22 +40,22 @@ namespace ImageProcessorCore.Formats
public IQuantizer Quantizer { get; set; } public IQuantizer Quantizer { get; set; }
/// <summary> /// <summary>
/// Encodes the image to the specified stream from the <see cref="Image{T,TP}"/>. /// Encodes the image to the specified stream from the <see cref="Image{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The <see cref="Image{T,TP}"/> to encode from.</param> /// <param name="image">The <see cref="Image{TColor, TPacked}"/> 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>
public void Encode<T, TP>(Image<T, TP> image, Stream stream) public void Encode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Guard.NotNull(image, nameof(image)); Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
if (this.Quantizer == null) if (this.Quantizer == null)
{ {
this.Quantizer = new OctreeQuantizer<T, TP> { Threshold = this.Threshold }; this.Quantizer = new OctreeQuantizer<TColor, TPacked> { Threshold = this.Threshold };
} }
// Do not use IDisposable pattern here as we want to preserve the stream. // Do not use IDisposable pattern here as we want to preserve the stream.
@ -69,7 +69,7 @@ namespace ImageProcessorCore.Formats
this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(this.Quality); this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(this.Quality);
// Quantize the image returning a palette. // Quantize the image returning a palette.
QuantizedImage<T, TP> quantized = ((IQuantizer<T, TP>)this.Quantizer).Quantize(image, this.Quality); QuantizedImage<TColor, TPacked> quantized = ((IQuantizer<TColor, TPacked>)this.Quantizer).Quantize(image, this.Quality);
// Write the header. // Write the header.
this.WriteHeader(writer); this.WriteHeader(writer);
@ -87,9 +87,9 @@ namespace ImageProcessorCore.Formats
if (image.Frames.Any()) if (image.Frames.Any())
{ {
this.WriteApplicationExtension(writer, image.RepeatCount, image.Frames.Count); this.WriteApplicationExtension(writer, image.RepeatCount, image.Frames.Count);
foreach (ImageFrame<T, TP> frame in image.Frames) foreach (ImageFrame<TColor, TPacked> frame in image.Frames)
{ {
QuantizedImage<T, TP> quantizedFrame = ((IQuantizer<T, TP>)this.Quantizer).Quantize(frame, this.Quality); QuantizedImage<TColor, TPacked> quantizedFrame = ((IQuantizer<TColor, TPacked>)this.Quantizer).Quantize(frame, this.Quality);
this.WriteGraphicalControlExtension(frame, writer, quantizedFrame.TransparentIndex); this.WriteGraphicalControlExtension(frame, writer, quantizedFrame.TransparentIndex);
this.WriteImageDescriptor(frame, writer); this.WriteImageDescriptor(frame, writer);
this.WriteColorTable(quantizedFrame, writer); this.WriteColorTable(quantizedFrame, writer);
@ -113,14 +113,14 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the logical screen descriptor to the stream. /// Writes the logical screen descriptor to the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The image to encode.</param> /// <param name="image">The image to encode.</param>
/// <param name="writer">The writer to write to the stream with.</param> /// <param name="writer">The writer to write to the stream with.</param>
/// <param name="tranparencyIndex">The transparency index to set the default backgound index to.</param> /// <param name="tranparencyIndex">The transparency index to set the default backgound index to.</param>
private void WriteLogicalScreenDescriptor<T, TP>(Image<T, TP> image, EndianBinaryWriter writer, int tranparencyIndex) private void WriteLogicalScreenDescriptor<TColor, TPacked>(Image<TColor, TPacked> image, EndianBinaryWriter writer, int tranparencyIndex)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
GifLogicalScreenDescriptor descriptor = new GifLogicalScreenDescriptor GifLogicalScreenDescriptor descriptor = new GifLogicalScreenDescriptor
{ {
@ -186,14 +186,14 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the graphics control extension to the stream. /// Writes the graphics control extension to the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The <see cref="ImageBase{T,TP}"/> to encode.</param> /// <param name="image">The <see cref="ImageBase{TColor, TPacked}"/> to encode.</param>
/// <param name="writer">The stream to write to.</param> /// <param name="writer">The stream to write to.</param>
/// <param name="transparencyIndex">The index of the color in the color palette to make transparent.</param> /// <param name="transparencyIndex">The index of the color in the color palette to make transparent.</param>
private void WriteGraphicalControlExtension<T, TP>(ImageBase<T, TP> image, EndianBinaryWriter writer, int transparencyIndex) private void WriteGraphicalControlExtension<TColor, TPacked>(ImageBase<TColor, TPacked> image, EndianBinaryWriter writer, int transparencyIndex)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
// TODO: Check transparency logic. // TODO: Check transparency logic.
bool hasTransparent = transparencyIndex > -1; bool hasTransparent = transparencyIndex > -1;
@ -234,13 +234,13 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the image descriptor to the stream. /// Writes the image descriptor to the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The <see cref="ImageBase{T,TP}"/> to be encoded.</param> /// <param name="image">The <see cref="ImageBase{TColor, TPacked}"/> to be encoded.</param>
/// <param name="writer">The stream to write to.</param> /// <param name="writer">The stream to write to.</param>
private void WriteImageDescriptor<T, TP>(ImageBase<T, TP> image, EndianBinaryWriter writer) private void WriteImageDescriptor<TColor, TPacked>(ImageBase<TColor, TPacked> image, EndianBinaryWriter writer)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
writer.Write(GifConstants.ImageDescriptorLabel); // 2c writer.Write(GifConstants.ImageDescriptorLabel); // 2c
// TODO: Can we capture this? // TODO: Can we capture this?
@ -261,16 +261,16 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the color table to the stream. /// Writes the color table to the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The <see cref="ImageBase{T,TP}"/> to encode.</param> /// <param name="image">The <see cref="ImageBase{TColor, TPacked}"/> to encode.</param>
/// <param name="writer">The writer to write to the stream with.</param> /// <param name="writer">The writer to write to the stream with.</param>
private void WriteColorTable<T, TP>(QuantizedImage<T, TP> image, EndianBinaryWriter writer) private void WriteColorTable<TColor, TPacked>(QuantizedImage<TColor, TPacked> image, EndianBinaryWriter writer)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
// Grab the palette and write it to the stream. // Grab the palette and write it to the stream.
T[] palette = image.Palette; TColor[] palette = image.Palette;
int pixelCount = palette.Length; int pixelCount = palette.Length;
// Get max colors for bit depth. // Get max colors for bit depth.
@ -294,13 +294,13 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the image pixel data to the stream. /// Writes the image pixel data to the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The <see cref="QuantizedImage{T,TP}"/> containing indexed pixels.</param> /// <param name="image">The <see cref="QuantizedImage{TColor, TPacked}"/> containing indexed pixels.</param>
/// <param name="writer">The stream to write to.</param> /// <param name="writer">The stream to write to.</param>
private void WriteImageData<T, TP>(QuantizedImage<T, TP> image, EndianBinaryWriter writer) private void WriteImageData<TColor, TPacked>(QuantizedImage<TColor, TPacked> image, EndianBinaryWriter writer)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
byte[] indexedPixels = image.Pixels; byte[] indexedPixels = image.Pixels;

2
src/ImageProcessorCore/Formats/Gif/LzwDecoder.cs

@ -33,7 +33,7 @@ namespace ImageProcessorCore.Formats
/// and sets the stream, where the compressed data should be read from. /// and sets the stream, where the compressed data should be read from.
/// </summary> /// </summary>
/// <param name="stream">The stream to read from.</param> /// <param name="stream">The stream to read from.</param>
/// <exception cref="ArgumentNullException"><paramref name="stream"/> is null.</exception> /// <exception cref="System.ArgumentNullException"><paramref name="stream"/> is null.</exception>
public LzwDecoder(Stream stream) public LzwDecoder(Stream stream)
{ {
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));

2
src/ImageProcessorCore/Formats/Gif/LzwEncoder.cs

@ -310,7 +310,7 @@ namespace ImageProcessorCore.Formats
} }
/// <summary> /// <summary>
/// Return the next pixel from the image /// Return the nexTColor pixel from the image
/// </summary> /// </summary>
/// <returns> /// <returns>
/// The <see cref="int"/> /// The <see cref="int"/>

2
src/ImageProcessorCore/Formats/Gif/Sections/GifGraphicsControlExtension.cs

@ -27,7 +27,7 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Gets or sets the transparency index. /// Gets or sets the transparency index.
/// The Transparency Index is such that when encountered, the corresponding pixel /// The Transparency Index is such that when encountered, the corresponding pixel
/// of the display device is not modified and processing goes on to the next pixel. /// of the display device is not modified and processing goes on to the nexTColor pixel.
/// </summary> /// </summary>
public int TransparencyIndex { get; set; } public int TransparencyIndex { get; set; }

14
src/ImageProcessorCore/Formats/IImageDecoder.cs

@ -39,14 +39,14 @@ namespace ImageProcessorCore.Formats
bool IsSupportedFileFormat(byte[] header); bool IsSupportedFileFormat(byte[] header);
/// <summary> /// <summary>
/// Decodes the image from the specified stream to the <see cref="ImageBase{T,TP}"/>. /// Decodes the image from the specified stream to the <see cref="ImageBase{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The <see cref="ImageBase{T,TP}"/> to decode to.</param> /// <param name="image">The <see cref="ImageBase{TColor, TPacked}"/> to decode to.</param>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param> /// <param name="stream">The <see cref="Stream"/> containing image data.</param>
void Decode<T, TP>(Image<T, TP> image, Stream stream) void Decode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct; where TPacked : struct;
} }
} }

10
src/ImageProcessorCore/Formats/IImageEncoder.cs

@ -40,12 +40,12 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Encodes the image to the specified stream from the <see cref="Image{T,P}"/>. /// Encodes the image to the specified stream from the <see cref="Image{T,P}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The <see cref="Image{T,P}"/> to encode from.</param> /// <param name="image">The <see cref="Image{T,P}"/> 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>
void Encode<T, TP>(Image<T, TP> image, Stream stream) void Encode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct; where TPacked : struct;
} }
} }

6
src/ImageProcessorCore/Formats/Jpg/JpegDecoder.cs

@ -76,9 +76,9 @@ namespace ImageProcessorCore.Formats
} }
/// <inheritdoc/> /// <inheritdoc/>
public void Decode<T, TP>(Image<T, TP> image, Stream stream) public void Decode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Guard.NotNull(image, "image"); Guard.NotNull(image, "image");
Guard.NotNull(stream, "stream"); Guard.NotNull(stream, "stream");

2
src/ImageProcessorCore/Formats/Jpg/JpegDecoderCore.cs.REMOVED.git-id

@ -1 +1 @@
09f4618eaade2900f7174b9ab400deb0a25bd813 d6ce5dd6236ac6ef9ba570fb4e57e81c06bbb854

6
src/ImageProcessorCore/Formats/Jpg/JpegEncoder.cs

@ -78,9 +78,9 @@ namespace ImageProcessorCore.Formats
} }
/// <inheritdoc/> /// <inheritdoc/>
public void Encode<T, TP>(Image<T, TP> image, Stream stream) public void Encode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
JpegEncoderCore encode = new JpegEncoderCore(); JpegEncoderCore encode = new JpegEncoderCore();
if (this.subsampleSet) if (this.subsampleSet)

38
src/ImageProcessorCore/Formats/Jpg/JpegEncoderCore.cs

@ -339,9 +339,9 @@ namespace ImageProcessorCore.Formats
// toYCbCr converts the 8x8 region of m whose top-left corner is p to its // toYCbCr converts the 8x8 region of m whose top-left corner is p to its
// YCbCr values. // YCbCr values.
private void ToYCbCr<T, TP>(IPixelAccessor<T, TP> pixels, int x, int y, Block yBlock, Block cbBlock, Block crBlock) private void ToYCbCr<TColor, TPacked>(PixelAccessor<TColor, TPacked> pixels, int x, int y, Block yBlock, Block cbBlock, Block crBlock)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
int xmax = pixels.Width - 1; int xmax = pixels.Width - 1;
int ymax = pixels.Height - 1; int ymax = pixels.Height - 1;
@ -430,9 +430,9 @@ namespace ImageProcessorCore.Formats
// Encode writes the Image m to w in JPEG 4:2:0 baseline format with the given // Encode writes the Image m to w in JPEG 4:2:0 baseline format with the given
// options. Default parameters are used if a nil *Options is passed. // options. Default parameters are used if a nil *Options is passed.
public void Encode<T, TP>(Image<T, TP> image, Stream stream, int quality, JpegSubsample sample) public void Encode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream, int quality, JpegSubsample sample)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Guard.NotNull(image, nameof(image)); Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
@ -502,7 +502,7 @@ namespace ImageProcessorCore.Formats
this.WriteDHT(componentCount); this.WriteDHT(componentCount);
// Write the image data. // Write the image data.
using (IPixelAccessor<T, TP> pixels = image.Lock()) using (PixelAccessor<TColor, TPacked> pixels = image.Lock())
{ {
this.WriteSOS(pixels); this.WriteSOS(pixels);
} }
@ -570,9 +570,9 @@ namespace ImageProcessorCore.Formats
this.outputStream.Write(this.buffer, 0, 4); this.outputStream.Write(this.buffer, 0, 4);
} }
private void WriteProfiles<T, TP>(Image<T, TP> image) private void WriteProfiles<TColor, TPacked>(Image<TColor, TPacked> image)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
WriteProfile(image.ExifProfile); WriteProfile(image.ExifProfile);
} }
@ -710,9 +710,9 @@ namespace ImageProcessorCore.Formats
/// Writes the StartOfScan marker. /// Writes the StartOfScan marker.
/// </summary> /// </summary>
/// <param name="pixels">The pixel accessor providing acces to the image pixels.</param> /// <param name="pixels">The pixel accessor providing acces to the image pixels.</param>
private void WriteSOS<T, TP>(IPixelAccessor<T, TP> pixels) private void WriteSOS<TColor, TPacked>(PixelAccessor<TColor, TPacked> pixels)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
// TODO: We should allow grayscale writing. // TODO: We should allow grayscale writing.
this.outputStream.Write(this.SOSHeaderYCbCr, 0, this.SOSHeaderYCbCr.Length); this.outputStream.Write(this.SOSHeaderYCbCr, 0, this.SOSHeaderYCbCr.Length);
@ -737,9 +737,9 @@ namespace ImageProcessorCore.Formats
/// Encodes the image with no subsampling. /// Encodes the image with no subsampling.
/// </summary> /// </summary>
/// <param name="pixels">The pixel accessor providing acces to the image pixels.</param> /// <param name="pixels">The pixel accessor providing acces to the image pixels.</param>
private void Encode444<T, TP>(IPixelAccessor<T, TP> pixels) private void Encode444<TColor, TPacked>(PixelAccessor<TColor, TPacked> pixels)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Block b = new Block(); Block b = new Block();
Block cb = new Block(); Block cb = new Block();
@ -763,9 +763,9 @@ namespace ImageProcessorCore.Formats
/// at a factor of 2 both horizontally and vertically. /// at a factor of 2 both horizontally and vertically.
/// </summary> /// </summary>
/// <param name="pixels">The pixel accessor providing acces to the image pixels.</param> /// <param name="pixels">The pixel accessor providing acces to the image pixels.</param>
private void Encode420<T, TP>(IPixelAccessor<T, TP> pixels) private void Encode420<TColor, TPacked>(PixelAccessor<TColor, TPacked> pixels)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Block b = new Block(); Block b = new Block();
Block[] cb = new Block[4]; Block[] cb = new Block[4];

2
src/ImageProcessorCore/Formats/Png/Filters/UpFilter.cs

@ -6,7 +6,7 @@
namespace ImageProcessorCore.Formats namespace ImageProcessorCore.Formats
{ {
/// <summary> /// <summary>
/// The Up filter is just like the Sub filter except that the pixel immediately above the current pixel, /// The Up filter is just like the Sub filter except that the pixel immediately above the currenTColor pixel,
/// rather than just to its left, is used as the predictor. /// rather than just to its left, is used as the predictor.
/// <see href="https://www.w3.org/TR/PNG-Filters.html"/> /// <see href="https://www.w3.org/TR/PNG-Filters.html"/>
/// </summary> /// </summary>

10
src/ImageProcessorCore/Formats/Png/PngDecoder.cs

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

80
src/ImageProcessorCore/Formats/Png/PngDecoderCore.cs

@ -80,8 +80,8 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Decodes the stream to the image. /// Decodes the stream to the image.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The image to decode to.</param> /// <param name="image">The image to decode to.</param>
/// <param name="stream">The stream containing image data. </param> /// <param name="stream">The stream containing image data. </param>
/// <exception cref="ImageFormatException"> /// <exception cref="ImageFormatException">
@ -90,11 +90,11 @@ namespace ImageProcessorCore.Formats
/// <exception cref="ArgumentOutOfRangeException"> /// <exception cref="ArgumentOutOfRangeException">
/// Thrown if the image is larger than the maximum allowable size. /// Thrown if the image is larger than the maximum allowable size.
/// </exception> /// </exception>
public void Decode<T, TP>(Image<T, TP> image, Stream stream) public void Decode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Image<T, TP> currentImage = image; Image<TColor, TPacked> currentImage = image;
this.currentStream = stream; this.currentStream = stream;
this.currentStream.Seek(8, SeekOrigin.Current); this.currentStream.Seek(8, SeekOrigin.Current);
@ -149,10 +149,10 @@ namespace ImageProcessorCore.Formats
+ $"max allowed size '{image.MaxWidth}x{image.MaxHeight}'"); + $"max allowed size '{image.MaxWidth}x{image.MaxHeight}'");
} }
T[] pixels = new T[this.header.Width * this.header.Height]; TColor[] pixels = new TColor[this.header.Width * this.header.Height];
this.ReadScanlines<T, TP>(dataStream, pixels); this.ReadScanlines<TColor, TPacked>(dataStream, pixels);
image.SetPixels(this.header.Width, this.header.Height, pixels); image.SetPixels(this.header.Width, this.header.Height, pixels);
@ -162,13 +162,13 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Reads the data chunk containing physical dimension data. /// Reads the data chunk containing physical dimension data.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The image to read to.</param> /// <param name="image">The image to read to.</param>
/// <param name="data">The data containing physical data.</param> /// <param name="data">The data containing physical data.</param>
private void ReadPhysicalChunk<T, TP>(Image<T, TP> image, byte[] data) private void ReadPhysicalChunk<TColor, TPacked>(Image<TColor, TPacked> image, byte[] data)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Array.Reverse(data, 0, 4); Array.Reverse(data, 0, 4);
Array.Reverse(data, 4, 4); Array.Reverse(data, 4, 4);
@ -228,10 +228,10 @@ namespace ImageProcessorCore.Formats
/// </summary> /// </summary>
/// <param name="dataStream">The <see cref="MemoryStream"/> containing data.</param> /// <param name="dataStream">The <see cref="MemoryStream"/> containing data.</param>
/// <param name="pixels"> /// <param name="pixels">
/// The <see cref="T:float[]"/> containing pixel data.</param> /// The <see cref="T:floaTColor[]"/> containing pixel data.</param>
private void ReadScanlines<T, TP>(MemoryStream dataStream, T[] pixels) private void ReadScanlines<TColor, TPacked>(MemoryStream dataStream, TColor[] pixels)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
this.bytesPerPixel = this.CalculateBytesPerPixel(); this.bytesPerPixel = this.CalculateBytesPerPixel();
this.bytesPerScanline = this.CalculateScanlineLength() + 1; this.bytesPerScanline = this.CalculateScanlineLength() + 1;
@ -250,7 +250,7 @@ namespace ImageProcessorCore.Formats
decompressedStream.Flush(); decompressedStream.Flush();
byte[] decompressedBytes = decompressedStream.ToArray(); byte[] decompressedBytes = decompressedStream.ToArray();
DecodePixelData<T, TP>(decompressedBytes, pixels); DecodePixelData<TColor, TPacked>(decompressedBytes, pixels);
} }
} }
} }
@ -258,13 +258,13 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Decodes the raw pixel data row by row /// Decodes the raw pixel data row by row
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="pixelData">The pixel data.</param> /// <param name="pixelData">The pixel data.</param>
/// <param name="pixels">The image pixels.</param> /// <param name="pixels">The image pixels.</param>
private void DecodePixelData<T, TP>(byte[] pixelData, T[] pixels) private void DecodePixelData<TColor, TPacked>(byte[] pixelData, TColor[] pixels)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
byte[] previousScanline = new byte[this.bytesPerScanline]; byte[] previousScanline = new byte[this.bytesPerScanline];
@ -312,21 +312,21 @@ namespace ImageProcessorCore.Formats
} }
previousScanline = defilteredScanline; previousScanline = defilteredScanline;
ProcessDefilteredScanline<T, TP>(defilteredScanline, y, pixels); ProcessDefilteredScanline<TColor, TPacked>(defilteredScanline, y, pixels);
} }
} }
/// <summary> /// <summary>
/// Processes the defiltered scanline filling the image pixel data /// Processes the defiltered scanline filling the image pixel data
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="defilteredScanline"></param> /// <param name="defilteredScanline"></param>
/// <param name="row">The current image row.</param> /// <param name="row">The current image row.</param>
/// <param name="pixels">The image pixels</param> /// <param name="pixels">The image pixels</param>
private void ProcessDefilteredScanline<T, TP>(byte[] defilteredScanline, int row, T[] pixels) private void ProcessDefilteredScanline<TColor, TPacked>(byte[] defilteredScanline, int row, TColor[] pixels)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
switch (this.PngColorType) switch (this.PngColorType)
{ {
@ -338,7 +338,7 @@ namespace ImageProcessorCore.Formats
byte intensity = defilteredScanline[offset]; byte intensity = defilteredScanline[offset];
T color = default(T); TColor color = default(TColor);
color.PackFromBytes(intensity, intensity, intensity, 255); color.PackFromBytes(intensity, intensity, intensity, 255);
pixels[(row * this.header.Width) + x] = color; pixels[(row * this.header.Width) + x] = color;
} }
@ -354,7 +354,7 @@ namespace ImageProcessorCore.Formats
byte intensity = defilteredScanline[offset]; byte intensity = defilteredScanline[offset];
byte alpha = defilteredScanline[offset + bytesPerSample]; byte alpha = defilteredScanline[offset + bytesPerSample];
T color = default(T); TColor color = default(TColor);
color.PackFromBytes(intensity, intensity, intensity, alpha); color.PackFromBytes(intensity, intensity, intensity, alpha);
pixels[(row * this.header.Width) + x] = color; pixels[(row * this.header.Width) + x] = color;
} }
@ -376,7 +376,7 @@ namespace ImageProcessorCore.Formats
int pixelOffset = index * 3; int pixelOffset = index * 3;
byte a = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255; byte a = this.paletteAlpha.Length > index ? this.paletteAlpha[index] : (byte)255;
T color = default(T); TColor color = default(TColor);
if (a > 0) if (a > 0)
{ {
byte r = this.palette[pixelOffset]; byte r = this.palette[pixelOffset];
@ -400,7 +400,7 @@ namespace ImageProcessorCore.Formats
byte g = this.palette[pixelOffset + 1]; byte g = this.palette[pixelOffset + 1];
byte b = this.palette[pixelOffset + 2]; byte b = this.palette[pixelOffset + 2];
T color = default(T); TColor color = default(TColor);
color.PackFromBytes(r, g, b, 255); color.PackFromBytes(r, g, b, 255);
pixels[offset] = color; pixels[offset] = color;
} }
@ -418,7 +418,7 @@ namespace ImageProcessorCore.Formats
byte g = defilteredScanline[offset + bytesPerSample]; byte g = defilteredScanline[offset + bytesPerSample];
byte b = defilteredScanline[offset + 2 * bytesPerSample]; byte b = defilteredScanline[offset + 2 * bytesPerSample];
T color = default(T); TColor color = default(TColor);
color.PackFromBytes(r, g, b, 255); color.PackFromBytes(r, g, b, 255);
pixels[(row * this.header.Width) + x] = color; pixels[(row * this.header.Width) + x] = color;
} }
@ -436,7 +436,7 @@ namespace ImageProcessorCore.Formats
byte b = defilteredScanline[offset + 2 * bytesPerSample]; byte b = defilteredScanline[offset + 2 * bytesPerSample];
byte a = defilteredScanline[offset + 3 * bytesPerSample]; byte a = defilteredScanline[offset + 3 * bytesPerSample];
T color = default(T); TColor color = default(TColor);
color.PackFromBytes(r, g, b, a); color.PackFromBytes(r, g, b, a);
pixels[(row * this.header.Width) + x] = color; pixels[(row * this.header.Width) + x] = color;
} }
@ -451,13 +451,13 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Reads a text chunk containing image properties from the data. /// Reads a text chunk containing image properties from the data.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The image to decode to.</param> /// <param name="image">The image to decode to.</param>
/// <param name="data">The <see cref="T:byte[]"/> containing data.</param> /// <param name="data">The <see cref="T:byte[]"/> containing data.</param>
private void ReadTextChunk<T, TP>(Image<T, TP> image, byte[] data) private void ReadTextChunk<TColor, TPacked>(Image<TColor, TPacked> image, byte[] data)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
int zeroIndex = 0; int zeroIndex = 0;

6
src/ImageProcessorCore/Formats/Png/PngEncoder.cs

@ -72,9 +72,9 @@ namespace ImageProcessorCore.Formats
} }
/// <inheritdoc/> /// <inheritdoc/>
public void Encode<T, TP>(Image<T, TP> image, Stream stream) public void Encode<TColor, TPacked>(Image<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
PngEncoderCore encoder = new PngEncoderCore PngEncoderCore encoder = new PngEncoderCore
{ {

78
src/ImageProcessorCore/Formats/Png/PngEncoderCore.cs

@ -89,15 +89,15 @@ namespace ImageProcessorCore.Formats
public byte Threshold { get; set; } = 128; public byte Threshold { get; set; } = 128;
/// <summary> /// <summary>
/// Encodes the image to the specified stream from the <see cref="ImageBase{T,TP}"/>. /// Encodes the image to the specified stream from the <see cref="ImageBase{TColor, TPacked}"/>.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The <see cref="ImageBase{T,TP}"/> to encode from.</param> /// <param name="image">The <see cref="ImageBase{TColor, TPacked}"/> 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>
public void Encode<T, TP>(ImageBase<T, TP> image, Stream stream) public void Encode<TColor, TPacked>(ImageBase<TColor, TPacked> image, Stream stream)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Guard.NotNull(image, nameof(image)); Guard.NotNull(image, nameof(image));
Guard.NotNull(stream, nameof(stream)); Guard.NotNull(stream, nameof(stream));
@ -185,34 +185,34 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Collects the indexed pixel data. /// Collects the indexed pixel data.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The image to encode.</param> /// <param name="image">The image to encode.</param>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param> /// <param name="stream">The <see cref="Stream"/> containing image data.</param>
/// <param name="header">The <see cref="PngHeader"/>.</param> /// <param name="header">The <see cref="PngHeader"/>.</param>
private void CollectIndexedBytes<T, TP>(ImageBase<T, TP> image, Stream stream, PngHeader header) private void CollectIndexedBytes<TColor, TPacked>(ImageBase<TColor, TPacked> image, Stream stream, PngHeader header)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
// Quatize the image and get the pixels // Quatize the image and get the pixels
QuantizedImage<T, TP> quantized = this.WritePaletteChunk(stream, header, image); QuantizedImage<TColor, TPacked> quantized = this.WritePaletteChunk(stream, header, image);
pixelData = quantized.Pixels; pixelData = quantized.Pixels;
} }
/// <summary> /// <summary>
/// Collects the grayscale pixel data. /// Collects the grayscale pixel data.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The image to encode.</param> /// <param name="image">The image to encode.</param>
private void CollectGrayscaleBytes<T, TP>(ImageBase<T, TP> image) private void CollectGrayscaleBytes<TColor, TPacked>(ImageBase<TColor, TPacked> image)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
// Copy the pixels across from the image. // Copy the pixels across from the image.
this.pixelData = new byte[this.width * this.height * this.bytesPerPixel]; this.pixelData = new byte[this.width * this.height * this.bytesPerPixel];
int stride = this.width * this.bytesPerPixel; int stride = this.width * this.bytesPerPixel;
using (IPixelAccessor<T, TP> pixels = image.Lock()) using (PixelAccessor<TColor, TPacked> pixels = image.Lock())
{ {
Parallel.For( Parallel.For(
0, 0,
@ -246,17 +246,17 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Collects the true color pixel data. /// Collects the true color pixel data.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="image">The image to encode.</param> /// <param name="image">The image to encode.</param>
private void CollectColorBytes<T, TP>(ImageBase<T, TP> image) private void CollectColorBytes<TColor, TPacked>(ImageBase<TColor, TPacked> image)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
// Copy the pixels across from the image. // Copy the pixels across from the image.
this.pixelData = new byte[this.width * this.height * this.bytesPerPixel]; this.pixelData = new byte[this.width * this.height * this.bytesPerPixel];
int stride = this.width * this.bytesPerPixel; int stride = this.width * this.bytesPerPixel;
using (IPixelAccessor<T, TP> pixels = image.Lock()) using (PixelAccessor<TColor, TPacked> pixels = image.Lock())
{ {
Parallel.For( Parallel.For(
0, 0,
@ -474,14 +474,14 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the palette chunk to the stream. /// Writes the palette chunk to the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param> /// <param name="stream">The <see cref="Stream"/> containing image data.</param>
/// <param name="header">The <see cref="PngHeader"/>.</param> /// <param name="header">The <see cref="PngHeader"/>.</param>
/// <param name="image">The image to encode.</param> /// <param name="image">The image to encode.</param>
private QuantizedImage<T, TP> WritePaletteChunk<T, TP>(Stream stream, PngHeader header, ImageBase<T, TP> image) private QuantizedImage<TColor, TPacked> WritePaletteChunk<TColor, TPacked>(Stream stream, PngHeader header, ImageBase<TColor, TPacked> image)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
if (this.Quality > 256) if (this.Quality > 256)
{ {
@ -490,14 +490,14 @@ namespace ImageProcessorCore.Formats
if (this.Quantizer == null) if (this.Quantizer == null)
{ {
this.Quantizer = new WuQuantizer<T, TP> { Threshold = this.Threshold }; this.Quantizer = new WuQuantizer<TColor, TPacked> { Threshold = this.Threshold };
} }
// Quantize the image returning a palette. This boxing is icky. // Quantize the image returning a palette. This boxing is icky.
QuantizedImage<T, TP> quantized = ((IQuantizer<T, TP>)this.Quantizer).Quantize(image, this.Quality); QuantizedImage<TColor, TPacked> quantized = ((IQuantizer<TColor, TPacked>)this.Quantizer).Quantize(image, this.Quality);
// Grab the palette and write it to the stream. // Grab the palette and write it to the stream.
T[] palette = quantized.Palette; TColor[] palette = quantized.Palette;
int pixelCount = palette.Length; int pixelCount = palette.Length;
// Get max colors for bit depth. // Get max colors for bit depth.
@ -533,15 +533,15 @@ namespace ImageProcessorCore.Formats
/// <summary> /// <summary>
/// Writes the physical dimension information to the stream. /// Writes the physical dimension information to the stream.
/// </summary> /// </summary>
/// <typeparam name="T">The pixel format.</typeparam> /// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TP">The packed format. <example>long, float.</example></typeparam> /// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="stream">The <see cref="Stream"/> containing image data.</param> /// <param name="stream">The <see cref="Stream"/> containing image data.</param>
/// <param name="imageBase">The image base.</param> /// <param name="imageBase">The image base.</param>
private void WritePhysicalChunk<T, TP>(Stream stream, ImageBase<T, TP> imageBase) private void WritePhysicalChunk<TColor, TPacked>(Stream stream, ImageBase<TColor, TPacked> imageBase)
where T : IPackedVector<TP> where TColor : IPackedVector<TPacked>
where TP : struct where TPacked : struct
{ {
Image<T, TP> image = imageBase as Image<T, TP>; Image<TColor, TPacked> image = imageBase as Image<TColor, TPacked>;
if (image != null && image.HorizontalResolution > 0 && image.VerticalResolution > 0) if (image != null && image.HorizontalResolution > 0 && image.VerticalResolution > 0)
{ {
// 39.3700787 = inches in a meter. // 39.3700787 = inches in a meter.

2
src/ImageProcessorCore/IO/EndianBinaryWriter.cs

@ -306,7 +306,7 @@ namespace ImageProcessorCore.IO
/// Writes a string to the stream, using the encoding for this writer. /// Writes a string to the stream, using the encoding for this writer.
/// </summary> /// </summary>
/// <param name="value">The value to write. Must not be null.</param> /// <param name="value">The value to write. Must not be null.</param>
/// <exception cref="ArgumentNullException">value is null</exception> /// <exception cref="System.ArgumentNullException">value is null</exception>
public void Write(string value) public void Write(string value)
{ {
if (value == null) if (value == null)

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save