diff --git a/src/ImageProcessorCore/Bootstrapper.cs b/src/ImageProcessorCore/Bootstrapper.cs
index a9c7dc831..5f2978534 100644
--- a/src/ImageProcessorCore/Bootstrapper.cs
+++ b/src/ImageProcessorCore/Bootstrapper.cs
@@ -8,6 +8,8 @@ namespace ImageProcessorCore
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+ using System.Text;
+
using ImageProcessorCore.Formats;
///
@@ -26,18 +28,25 @@ namespace ImageProcessorCore
///
private readonly List imageFormats;
+ private readonly Dictionary pixelAccessors;
+
///
/// Prevents a default instance of the class from being created.
///
private Bootstrapper()
{
- this.imageFormats = new List(new List
+ this.imageFormats = new List
{
new BmpFormat(),
new JpegFormat(),
new PngFormat(),
new GifFormat()
- });
+ };
+
+ this.pixelAccessors = new Dictionary
+ {
+ { typeof(Bgra32), typeof(Bgra32PixelAccessor) }
+ };
}
///
@@ -58,5 +67,58 @@ namespace ImageProcessorCore
{
this.imageFormats.Add(format);
}
+
+ ///
+ /// Gets an instance of the correct for the packed vector.
+ ///
+ /// The type of pixel data.
+ /// The image
+ /// The
+ public IPixelAccessor GetPixelAccessor(Image image)
+ where TPackedVector : IPackedVector
+ {
+ Type packed = typeof(TPackedVector);
+ if (!this.pixelAccessors.ContainsKey(packed))
+ {
+ // TODO: Double check this. It should work...
+ return (IPixelAccessor)Activator.CreateInstance(this.pixelAccessors[packed], image);
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.AppendLine("PixelAccessor cannot be loaded. Available accessors:");
+
+ foreach (Type value in this.pixelAccessors.Values)
+ {
+ stringBuilder.AppendLine("-" + value.Name);
+ }
+
+ throw new NotSupportedException(stringBuilder.ToString());
+ }
+
+ ///
+ /// Gets an instance of the correct for the packed vector.
+ ///
+ /// The type of pixel data.
+ /// The image
+ /// The
+ public IPixelAccessor GetPixelAccessor(ImageFrame image)
+ where TPackedVector : IPackedVector
+ {
+ Type packed = typeof(TPackedVector);
+ if (!this.pixelAccessors.ContainsKey(packed))
+ {
+ return (IPixelAccessor)Activator.CreateInstance(this.pixelAccessors[packed], image);
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.AppendLine("PixelAccessor cannot be loaded. Available accessors:");
+
+ foreach (Type value in this.pixelAccessors.Values)
+ {
+ stringBuilder.AppendLine("-" + value.Name);
+ }
+
+ throw new NotSupportedException(stringBuilder.ToString());
+ }
}
}
diff --git a/src/ImageProcessorCore/GenericImage.cs b/src/ImageProcessorCore/GenericImage.cs
deleted file mode 100644
index b0408513a..000000000
--- a/src/ImageProcessorCore/GenericImage.cs
+++ /dev/null
@@ -1,261 +0,0 @@
-
-
-namespace ImageProcessorCore
-{
- using System.IO;
- using System.Text;
-
- using System;
- using System.Collections.Generic;
- using System.Linq;
-
- using ImageProcessorCore.Formats;
-
- ///
- /// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
- ///
- ///
- /// The image data is always stored in RGBA format, where the red, green, blue, and
- /// alpha values are floating point numbers.
- ///
- public abstract class GenericImage : ImageBase
- where TPacked : IPackedVector
- {
- ///
- /// The default horizontal resolution value (dots per inch) in x direction.
- /// The default value is 96 dots per inch.
- ///
- public const double DefaultHorizontalResolution = 96;
-
- ///
- /// The default vertical resolution value (dots per inch) in y direction.
- /// The default value is 96 dots per inch.
- ///
- public const double DefaultVerticalResolution = 96;
-
- ///
- /// Initializes a new instance of the class.
- ///
- protected GenericImage()
- {
- this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
- }
-
- ///
- /// Initializes a new instance of the class
- /// with the height and the width of the image.
- ///
- /// The width of the image in pixels.
- /// The height of the image in pixels.
- protected GenericImage(int width, int height)
- : base(width, height)
- {
- this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The stream containing image information.
- ///
- /// Thrown if the is null.
- protected GenericImage(Stream stream)
- {
- Guard.NotNull(stream, nameof(stream));
- this.Load(stream);
- }
-
- ///
- /// Gets a list of supported image formats.
- ///
- public IReadOnlyCollection Formats { get; } = Bootstrapper.Instance.ImageFormats;
-
- ///
- /// Gets or sets the resolution of the image in x- direction. It is defined as
- /// number of dots per inch and should be an positive value.
- ///
- /// The density of the image in x- direction.
- public double HorizontalResolution { get; set; } = DefaultHorizontalResolution;
-
- ///
- /// Gets or sets the resolution of the image in y- direction. It is defined as
- /// number of dots per inch and should be an positive value.
- ///
- /// The density of the image in y- direction.
- public double VerticalResolution { get; set; } = DefaultVerticalResolution;
-
- ///
- /// Gets the width of the image in inches. It is calculated as the width of the image
- /// in pixels multiplied with the density. When the density is equals or less than zero
- /// the default value is used.
- ///
- /// The width of the image in inches.
- public double InchWidth
- {
- get
- {
- double resolution = this.HorizontalResolution;
-
- if (resolution <= 0)
- {
- resolution = DefaultHorizontalResolution;
- }
-
- return this.Width / resolution;
- }
- }
-
- ///
- /// Gets the height of the image in inches. It is calculated as the height of the image
- /// in pixels multiplied with the density. When the density is equals or less than zero
- /// the default value is used.
- ///
- /// The height of the image in inches.
- public double InchHeight
- {
- get
- {
- double resolution = this.VerticalResolution;
-
- if (resolution <= 0)
- {
- resolution = DefaultVerticalResolution;
- }
-
- return this.Height / resolution;
- }
- }
-
- ///
- /// Gets a value indicating whether this image is animated.
- ///
- ///
- /// True if this image is animated; otherwise, false.
- ///
- public bool IsAnimated => this.Frames.Count > 0;
-
- ///
- /// Gets or sets the number of times any animation is repeated.
- /// 0 means to repeat indefinitely.
- ///
- public ushort RepeatCount { get; set; }
-
- ///
- /// Gets the other frames for the animation.
- ///
- /// The list of frame images.
- public IList> Frames { get; } = new List>();
-
- ///
- /// Gets the list of properties for storing meta information about this image.
- ///
- /// A list of image properties.
- public IList Properties { get; } = new List();
-
- ///
- /// Gets the currently loaded image format.
- ///
- public IImageFormat CurrentImageFormat { get; internal set; }
-
- ///
- /// Saves the image to the given stream using the currently loaded image format.
- ///
- /// The stream to save the image to.
- /// Thrown if the stream is null.
- public void Save(Stream stream)
- {
- Guard.NotNull(stream, nameof(stream));
- this.CurrentImageFormat.Encoder.Encode(this, stream);
- }
-
- ///
- /// Saves the image to the given stream using the given image format.
- ///
- /// The stream to save the image to.
- /// The format to save the image as.
- /// Thrown if the stream is null.
- public void Save(Stream stream, IImageFormat format)
- {
- Guard.NotNull(stream, nameof(stream));
- format.Encoder.Encode(this, stream);
- }
-
- ///
- /// Saves the image to the given stream using the given image encoder.
- ///
- /// The stream to save the image to.
- /// The encoder to save the image with.
- /// Thrown if the stream is null.
- public void Save(Stream stream, IImageEncoder encoder)
- {
- Guard.NotNull(stream, nameof(stream));
- encoder.Encode(this, stream);
- }
-
- ///
- /// Returns a Base64 encoded string from the given image.
- ///
- /// data:image/gif;base64,R0lGODlhAQABAIABAEdJRgAAACwAAAAAAQABAAACAkQBAA==
- /// The
- public override string ToString()
- {
- using (MemoryStream stream = new MemoryStream())
- {
- this.Save(stream);
- stream.Flush();
- return $"data:{this.CurrentImageFormat.Encoder.MimeType};base64,{Convert.ToBase64String(stream.ToArray())}";
- }
- }
-
- ///
- /// Loads the image from the given stream.
- ///
- /// The stream containing image information.
- ///
- /// Thrown if the stream is not readable nor seekable.
- ///
- private void Load(Stream stream)
- {
- if (!this.Formats.Any()) { return; }
-
- if (!stream.CanRead)
- {
- throw new NotSupportedException("Cannot read from the stream.");
- }
-
- if (!stream.CanSeek)
- {
- throw new NotSupportedException("The stream does not support seeking.");
- }
-
- int maxHeaderSize = this.Formats.Max(x => x.Decoder.HeaderSize);
- if (maxHeaderSize > 0)
- {
- byte[] header = new byte[maxHeaderSize];
-
- stream.Position = 0;
- stream.Read(header, 0, maxHeaderSize);
- stream.Position = 0;
-
- IImageFormat format = this.Formats.FirstOrDefault(x => x.Decoder.IsSupportedFileFormat(header));
- if (format != null)
- {
- format.Decoder.Decode(this, stream);
- this.CurrentImageFormat = format;
- return;
- }
- }
-
- StringBuilder stringBuilder = new StringBuilder();
- stringBuilder.AppendLine("Image cannot be loaded. Available formats:");
-
- foreach (IImageFormat format in this.Formats)
- {
- stringBuilder.AppendLine("-" + format);
- }
-
- throw new NotSupportedException(stringBuilder.ToString());
- }
- }
-}
diff --git a/src/ImageProcessorCore/GenericImageFrame.cs b/src/ImageProcessorCore/GenericImageFrame.cs
deleted file mode 100644
index b0dbe341c..000000000
--- a/src/ImageProcessorCore/GenericImageFrame.cs
+++ /dev/null
@@ -1,40 +0,0 @@
-//
-// Copyright (c) James Jackson-South and contributors.
-// Licensed under the Apache License, Version 2.0.
-//
-
-namespace ImageProcessorCore
-{
- using System;
-
- ///
- /// Represents a single frame in a animation.
- ///
- ///
- /// The packed vector pixels format.
- ///
- public abstract class GenericImageFrame : ImageBase, IImageFrame
- where TPacked : IPackedVector
- {
- ///
- /// Initializes a new instance of the class.
- ///
- protected GenericImageFrame()
- {
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The other to create this instance from.
- ///
- ///
- /// Thrown if the given is null.
- ///
- protected GenericImageFrame(GenericImageFrame other)
- : base(other)
- {
- }
- }
-}
diff --git a/src/ImageProcessorCore/IImageBase.cs b/src/ImageProcessorCore/IImageBase.cs
index 85ffa0086..b01ee7c9c 100644
--- a/src/ImageProcessorCore/IImageBase.cs
+++ b/src/ImageProcessorCore/IImageBase.cs
@@ -1,18 +1,18 @@
namespace ImageProcessorCore
{
- public interface IImageBase
- where TPacked : IPackedVector
+ public interface IImageBase
+ where TPackedVector : IPackedVector
{
Rectangle Bounds { get; }
int FrameDelay { get; set; }
int Height { get; }
double PixelRatio { get; }
- TPacked[] Pixels { get; }
+ TPackedVector[] Pixels { get; }
int Quality { get; set; }
int Width { get; }
- void ClonePixels(int width, int height, TPacked[] pixels);
+ void ClonePixels(int width, int height, TPackedVector[] pixels);
IPixelAccessor Lock();
- void SetPixels(int width, int height, TPacked[] pixels);
+ void SetPixels(int width, int height, TPackedVector[] pixels);
}
}
\ No newline at end of file
diff --git a/src/ImageProcessorCore/IImageProcessor.cs b/src/ImageProcessorCore/IImageProcessor.cs
index e71762b10..ad6e4ac76 100644
--- a/src/ImageProcessorCore/IImageProcessor.cs
+++ b/src/ImageProcessorCore/IImageProcessor.cs
@@ -27,8 +27,9 @@ namespace ImageProcessorCore.Processors
event ProgressEventHandler OnProgress;
///
- /// Applies the process to the specified portion of the specified .
+ /// Applies the process to the specified portion of the specified .
///
+ /// The type of pixels contained within the image.
/// Target image to apply the process to.
/// The source image. Cannot be null.
///
@@ -44,12 +45,13 @@ namespace ImageProcessorCore.Processors
///
/// doesnt fit the dimension of the image.
///
- void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle);
+ void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle) where TPackedVector : IPackedVector;
///
- /// Applies the process to the specified portion of the specified at the specified
+ /// Applies the process to the specified portion of the specified at the specified
/// location and with the specified size.
///
+ /// The type of pixels contained within the image.
/// Target image to apply the process to.
/// The source image. Cannot be null.
/// The target width.
@@ -65,6 +67,6 @@ namespace ImageProcessorCore.Processors
/// The method keeps the source image unchanged and returns the
/// the result of image process as new image.
///
- void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle, Rectangle sourceRectangle);
+ void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle, Rectangle sourceRectangle) where TPackedVector : IPackedVector;
}
}
diff --git a/src/ImageProcessorCore/Image.cs b/src/ImageProcessorCore/Image.cs
index 88d4d1b6c..c8dc861d6 100644
--- a/src/ImageProcessorCore/Image.cs
+++ b/src/ImageProcessorCore/Image.cs
@@ -1,33 +1,86 @@
-namespace ImageProcessorCore
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessorCore
{
+ using System.IO;
+ using System.Text;
+
using System;
- using System.Diagnostics;
+ using System.Collections.Generic;
using System.Linq;
+ using Formats;
+
///
/// Encapsulates an image, which consists of the pixel data for a graphics image and its attributes.
///
- ///
- /// The image data is always stored in format, where the blue, green, red, and
- /// alpha values are 8 bit unsigned bytes.
- ///
- [DebuggerDisplay("Image: {Width}x{Height}")]
- public class Image : GenericImage
+ ///
+ /// The packed vector containing pixel information.
+ ///
+ public class Image : ImageBase
+ where TPackedVector : IPackedVector
{
///
- /// Initializes a new instance of the class
+ /// The default horizontal resolution value (dots per inch) in x direction.
+ /// The default value is 96 dots per inch.
+ ///
+ public const double DefaultHorizontalResolution = 96;
+
+ ///
+ /// The default vertical resolution value (dots per inch) in y direction.
+ /// The default value is 96 dots per inch.
+ ///
+ public const double DefaultVerticalResolution = 96;
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public Image()
+ {
+ this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
+ }
+
+ ///
+ /// Initializes a new instance of the class
+ /// with the height and the width of the image.
+ ///
+ /// The width of the image in pixels.
+ /// The height of the image in pixels.
+ public Image(int width, int height)
+ : base(width, height)
+ {
+ this.CurrentImageFormat = Bootstrapper.Instance.ImageFormats.First(f => f.GetType() == typeof(PngFormat));
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The stream containing image information.
+ ///
+ /// Thrown if the is null.
+ public Image(Stream stream)
+ {
+ Guard.NotNull(stream, nameof(stream));
+ this.Load(stream);
+ }
+
+ ///
+ /// Initializes a new instance of the class
/// by making a copy from another image.
///
/// The other image, where the clone should be made from.
/// is null.
- public Image(Image other)
+ public Image(Image other)
{
- // TODO: Check this. Not sure why I was getting a cast warning.
- foreach (ImageFrame frame in other.Frames.Cast())
+ foreach (ImageFrame frame in other.Frames)
{
if (frame != null)
{
- this.Frames.Add(new ImageFrame(frame));
+ this.Frames.Add(new ImageFrame(frame));
}
}
@@ -37,10 +90,202 @@
this.CurrentImageFormat = other.CurrentImageFormat;
}
+ ///
+ /// Gets a list of supported image formats.
+ ///
+ public IReadOnlyCollection Formats { get; } = Bootstrapper.Instance.ImageFormats;
+
+ ///
+ /// Gets or sets the resolution of the image in x- direction. It is defined as
+ /// number of dots per inch and should be an positive value.
+ ///
+ /// The density of the image in x- direction.
+ public double HorizontalResolution { get; set; } = DefaultHorizontalResolution;
+
+ ///
+ /// Gets or sets the resolution of the image in y- direction. It is defined as
+ /// number of dots per inch and should be an positive value.
+ ///
+ /// The density of the image in y- direction.
+ public double VerticalResolution { get; set; } = DefaultVerticalResolution;
+
+ ///
+ /// Gets the width of the image in inches. It is calculated as the width of the image
+ /// in pixels multiplied with the density. When the density is equals or less than zero
+ /// the default value is used.
+ ///
+ /// The width of the image in inches.
+ public double InchWidth
+ {
+ get
+ {
+ double resolution = this.HorizontalResolution;
+
+ if (resolution <= 0)
+ {
+ resolution = DefaultHorizontalResolution;
+ }
+
+ return this.Width / resolution;
+ }
+ }
+
+ ///
+ /// Gets the height of the image in inches. It is calculated as the height of the image
+ /// in pixels multiplied with the density. When the density is equals or less than zero
+ /// the default value is used.
+ ///
+ /// The height of the image in inches.
+ public double InchHeight
+ {
+ get
+ {
+ double resolution = this.VerticalResolution;
+
+ if (resolution <= 0)
+ {
+ resolution = DefaultVerticalResolution;
+ }
+
+ return this.Height / resolution;
+ }
+ }
+
+ ///
+ /// Gets a value indicating whether this image is animated.
+ ///
+ ///
+ /// True if this image is animated; otherwise, false.
+ ///
+ public bool IsAnimated => this.Frames.Count > 0;
+
+ ///
+ /// Gets or sets the number of times any animation is repeated.
+ /// 0 means to repeat indefinitely.
+ ///
+ public ushort RepeatCount { get; set; }
+
+ ///
+ /// Gets the other frames for the animation.
+ ///
+ /// The list of frame images.
+ public IList> Frames { get; } = new List>();
+
+ ///
+ /// Gets the list of properties for storing meta information about this image.
+ ///
+ /// A list of image properties.
+ public IList Properties { get; } = new List();
+
+ ///
+ /// Gets the currently loaded image format.
+ ///
+ public IImageFormat CurrentImageFormat { get; internal set; }
+
///
public override IPixelAccessor Lock()
{
- return new PixelAccessor(this);
+ return Bootstrapper.Instance.GetPixelAccessor(this);
+ }
+
+ ///
+ /// Saves the image to the given stream using the currently loaded image format.
+ ///
+ /// The stream to save the image to.
+ /// Thrown if the stream is null.
+ public void Save(Stream stream)
+ {
+ Guard.NotNull(stream, nameof(stream));
+ this.CurrentImageFormat.Encoder.Encode(this, stream);
+ }
+
+ ///
+ /// Saves the image to the given stream using the given image format.
+ ///
+ /// The stream to save the image to.
+ /// The format to save the image as.
+ /// Thrown if the stream is null.
+ public void Save(Stream stream, IImageFormat format)
+ {
+ Guard.NotNull(stream, nameof(stream));
+ format.Encoder.Encode(this, stream);
+ }
+
+ ///
+ /// Saves the image to the given stream using the given image encoder.
+ ///
+ /// The stream to save the image to.
+ /// The encoder to save the image with.
+ /// Thrown if the stream is null.
+ public void Save(Stream stream, IImageEncoder encoder)
+ {
+ Guard.NotNull(stream, nameof(stream));
+ encoder.Encode(this, stream);
+ }
+
+ ///
+ /// Returns a Base64 encoded string from the given image.
+ ///
+ /// data:image/gif;base64,R0lGODlhAQABAIABAEdJRgAAACwAAAAAAQABAAACAkQBAA==
+ /// The
+ public override string ToString()
+ {
+ using (MemoryStream stream = new MemoryStream())
+ {
+ this.Save(stream);
+ stream.Flush();
+ return $"data:{this.CurrentImageFormat.Encoder.MimeType};base64,{Convert.ToBase64String(stream.ToArray())}";
+ }
+ }
+
+ ///
+ /// Loads the image from the given stream.
+ ///
+ /// The stream containing image information.
+ ///
+ /// Thrown if the stream is not readable nor seekable.
+ ///
+ private void Load(Stream stream)
+ {
+ if (!this.Formats.Any()) { return; }
+
+ if (!stream.CanRead)
+ {
+ throw new NotSupportedException("Cannot read from the stream.");
+ }
+
+ if (!stream.CanSeek)
+ {
+ throw new NotSupportedException("The stream does not support seeking.");
+ }
+
+ int maxHeaderSize = this.Formats.Max(x => x.Decoder.HeaderSize);
+ if (maxHeaderSize > 0)
+ {
+ byte[] header = new byte[maxHeaderSize];
+
+ stream.Position = 0;
+ stream.Read(header, 0, maxHeaderSize);
+ stream.Position = 0;
+
+ IImageFormat format = this.Formats.FirstOrDefault(x => x.Decoder.IsSupportedFileFormat(header));
+ if (format != null)
+ {
+ format.Decoder.Decode(this, stream);
+ this.CurrentImageFormat = format;
+ return;
+ }
+ }
+
+ StringBuilder stringBuilder = new StringBuilder();
+ stringBuilder.AppendLine("Image cannot be loaded. Available formats:");
+
+ foreach (IImageFormat format in this.Formats)
+ {
+ stringBuilder.AppendLine("-" + format);
+ }
+
+ throw new NotSupportedException(stringBuilder.ToString());
}
}
}
diff --git a/src/ImageProcessorCore/ImageFrame.cs b/src/ImageProcessorCore/ImageFrame.cs
index 2f1fe518c..479d9dd9b 100644
--- a/src/ImageProcessorCore/ImageFrame.cs
+++ b/src/ImageProcessorCore/ImageFrame.cs
@@ -1,21 +1,26 @@
-namespace ImageProcessorCore
+//
+// Copyright (c) James Jackson-South and contributors.
+// Licensed under the Apache License, Version 2.0.
+//
+
+namespace ImageProcessorCore
{
///
/// Represents a single frame in a animation.
///
- ///
- /// The image data is always stored in format, where the blue, green, red, and
- /// alpha values are 8 bit unsigned bytes.
- ///
- public class ImageFrame : ImageBase, IImageFrame
+ ///
+ /// The packed vector containing pixel information.
+ ///
+ public class ImageFrame : ImageBase
+ where TPackedVector : IPackedVector
{
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
///
/// The frame to create the frame from.
///
- public ImageFrame(ImageFrame frame)
+ public ImageFrame(ImageFrame frame)
: base(frame)
{
}
@@ -23,7 +28,7 @@
///
public override IPixelAccessor Lock()
{
- return new PixelAccessor(this);
+ return Bootstrapper.Instance.GetPixelAccessor(this);
}
}
}
diff --git a/src/ImageProcessorCore/ImageProcessor.cs b/src/ImageProcessorCore/ImageProcessor.cs
index ea76ebbf8..e7057a3f9 100644
--- a/src/ImageProcessorCore/ImageProcessor.cs
+++ b/src/ImageProcessorCore/ImageProcessor.cs
@@ -27,7 +27,8 @@ namespace ImageProcessorCore.Processors
private int totalRows;
///
- public void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle)
+ public void Apply(ImageBase target, ImageBase source, Rectangle sourceRectangle)
+ where TPackedVector : IPackedVector
{
try
{
@@ -48,11 +49,12 @@ namespace ImageProcessorCore.Processors
}
///
- public void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle = default(Rectangle), Rectangle sourceRectangle = default(Rectangle))
+ public void Apply(ImageBase target, ImageBase source, int width, int height, Rectangle targetRectangle = default(Rectangle), Rectangle sourceRectangle = default(Rectangle))
+ where TPackedVector : IPackedVector
{
try
{
- float[] pixels = new float[width * height * 4];
+ TPackedVector[] pixels = new TPackedVector[width * height];
target.SetPixels(width, height, pixels);
// Ensure we always have bounds.
@@ -93,14 +95,16 @@ namespace ImageProcessorCore.Processors
///
/// The structure that specifies the portion of the image object to draw.
///
- protected virtual void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
+ protected virtual void OnApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
+ where TPackedVector : IPackedVector
{
}
///
- /// Applies the process to the specified portion of the specified at the specified location
+ /// Applies the process to the specified portion of the specified at the specified location
/// and with the specified size.
///
+ /// The type of pixels contained within the image.
/// Target image to apply the process to.
/// The source image. Cannot be null.
///
@@ -116,11 +120,12 @@ namespace ImageProcessorCore.Processors
/// The method keeps the source image unchanged and returns the
/// the result of image process as new image.
///
- protected abstract void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY);
+ protected abstract void Apply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle, int startY, int endY) where TPackedVector : IPackedVector;
///
/// This method is called after the process is applied to prepare the processor.
///
+ /// The type of pixels contained within the image.
/// Target image to apply the process to.
/// The source image. Cannot be null.
///
@@ -130,7 +135,8 @@ namespace ImageProcessorCore.Processors
///
/// The structure that specifies the portion of the image object to draw.
///
- protected virtual void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
+ protected virtual void AfterApply(ImageBase target, ImageBase source, Rectangle targetRectangle, Rectangle sourceRectangle)
+ where TPackedVector : IPackedVector
{
}
diff --git a/src/ImageProcessorCore/PixelAccessor.cs b/src/ImageProcessorCore/PixelAccessor/Bgra32PixelAccessor.cs
similarity index 92%
rename from src/ImageProcessorCore/PixelAccessor.cs
rename to src/ImageProcessorCore/PixelAccessor/Bgra32PixelAccessor.cs
index 360649132..cecc148b9 100644
--- a/src/ImageProcessorCore/PixelAccessor.cs
+++ b/src/ImageProcessorCore/PixelAccessor/Bgra32PixelAccessor.cs
@@ -1,4 +1,4 @@
-//
+//
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
//
@@ -15,7 +15,7 @@ namespace ImageProcessorCore
/// The image data is always stored in format, where the blue, green, red, and
/// alpha values are 8 bit unsigned bytes.
///
- public sealed unsafe class PixelAccessor : IPixelAccessor
+ public sealed unsafe class Bgra32PixelAccessor : IPixelAccessor
{
///
/// The position of the first pixel in the bitmap.
@@ -41,12 +41,12 @@ namespace ImageProcessorCore
private bool isDisposed;
///
- /// Initializes a new instance of the class.
+ /// Initializes a new instance of the class.
///
///
/// The image to provide pixel access for.
///
- public PixelAccessor(ImageBase image)
+ public Bgra32PixelAccessor(IImageBase image)
{
Guard.NotNull(image, nameof(image));
Guard.MustBeGreaterThan(image.Width, 0, "image width");
@@ -60,9 +60,9 @@ namespace ImageProcessorCore
}
///
- /// Finalizes an instance of the class.
+ /// Finalizes an instance of the class.
///
- ~PixelAccessor()
+ ~Bgra32PixelAccessor()
{
this.Dispose();
}
diff --git a/src/ImageProcessorCore/IPixelAccessor.cs b/src/ImageProcessorCore/PixelAccessor/IPixelAccessor.cs
similarity index 100%
rename from src/ImageProcessorCore/IPixelAccessor.cs
rename to src/ImageProcessorCore/PixelAccessor/IPixelAccessor.cs