diff --git a/src/ImageSharp.Drawing/Brushes/IBrush.cs b/src/ImageSharp.Drawing/Brushes/IBrush.cs
index 8b163d7f67..bb907281b0 100644
--- a/src/ImageSharp.Drawing/Brushes/IBrush.cs
+++ b/src/ImageSharp.Drawing/Brushes/IBrush.cs
@@ -32,6 +32,6 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
/// The when being applied to things like shapes would usually be the
/// bounding box of the shape not necessarily the bounds of the whole image
///
- BrushApplicator CreateApplicator(ImageBase source, RectangleF region, GraphicsOptions options);
+ BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options);
}
}
\ No newline at end of file
diff --git a/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs
index 850775ce05..4cd3585ec7 100644
--- a/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs
+++ b/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs
@@ -21,19 +21,19 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
///
/// The image to paint.
///
- private readonly ImageBase image;
+ private readonly ImageFrame image;
///
/// Initializes a new instance of the class.
///
/// The image.
- public ImageBrush(ImageBase image)
+ public ImageBrush(ImageFrame image)
{
this.image = image;
}
///
- public BrushApplicator CreateApplicator(ImageBase source, RectangleF region, GraphicsOptions options)
+ public BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options)
{
return new ImageBrushApplicator(source, this.image, region, options);
}
@@ -46,7 +46,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
///
/// The source image.
///
- private readonly ImageBase source;
+ private readonly ImageFrame source;
///
/// The y-length.
@@ -75,7 +75,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
/// The image.
/// The region.
/// The options
- public ImageBrushApplicator(ImageBase target, ImageBase image, RectangleF region, GraphicsOptions options)
+ public ImageBrushApplicator(ImageFrame target, ImageFrame image, RectangleF region, GraphicsOptions options)
: base(target, options)
{
this.source = image;
diff --git a/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs
index b1dab0ea9c..844df0e0e9 100644
--- a/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs
+++ b/src/ImageSharp.Drawing/Brushes/PatternBrush{TPixel}.cs
@@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
}
///
- public BrushApplicator CreateApplicator(ImageBase source, RectangleF region, GraphicsOptions options)
+ public BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options)
{
return new PatternBrushApplicator(source, this.pattern, this.patternVector, options);
}
@@ -115,7 +115,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
/// The pattern.
/// The patternVector.
/// The options
- public PatternBrushApplicator(ImageBase source, Fast2DArray pattern, Fast2DArray patternVector, GraphicsOptions options)
+ public PatternBrushApplicator(ImageFrame source, Fast2DArray pattern, Fast2DArray patternVector, GraphicsOptions options)
: base(source, options)
{
this.pattern = pattern;
diff --git a/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs b/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs
index 258d69721c..ca6f7630d9 100644
--- a/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs
+++ b/src/ImageSharp.Drawing/Brushes/Processors/BrushApplicator.cs
@@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes.Processors
///
/// The target.
/// The options.
- internal BrushApplicator(ImageBase target, GraphicsOptions options)
+ internal BrushApplicator(ImageFrame target, GraphicsOptions options)
{
this.Target = target;
@@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes.Processors
///
/// Gets the destinaion
///
- protected ImageBase Target { get; }
+ protected ImageFrame Target { get; }
///
/// Gets the blend percentage
diff --git a/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs
index bbd0e4d864..ba2fca4e4b 100644
--- a/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs
+++ b/src/ImageSharp.Drawing/Brushes/RecolorBrush{TPixel}.cs
@@ -57,7 +57,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
public TPixel TargeTPixel { get; }
///
- public BrushApplicator CreateApplicator(ImageBase source, RectangleF region, GraphicsOptions options)
+ public BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options)
{
return new RecolorBrushApplicator(source, this.SourceColor, this.TargeTPixel, this.Threshold, options);
}
@@ -92,7 +92,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
/// Color of the target.
/// The threshold .
/// The options
- public RecolorBrushApplicator(ImageBase source, TPixel sourceColor, TPixel targetColor, float threshold, GraphicsOptions options)
+ public RecolorBrushApplicator(ImageFrame source, TPixel sourceColor, TPixel targetColor, float threshold, GraphicsOptions options)
: base(source, options)
{
this.sourceColor = sourceColor.ToVector4();
diff --git a/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs b/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs
index 27bce86bfb..658164339d 100644
--- a/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs
+++ b/src/ImageSharp.Drawing/Brushes/SolidBrush{TPixel}.cs
@@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
public TPixel Color => this.color;
///
- public BrushApplicator CreateApplicator(ImageBase source, RectangleF region, GraphicsOptions options)
+ public BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options)
{
return new SolidBrushApplicator(source, this.color, options);
}
@@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
/// The source image.
/// The color.
/// The options
- public SolidBrushApplicator(ImageBase source, TPixel color, GraphicsOptions options)
+ public SolidBrushApplicator(ImageFrame source, TPixel color, GraphicsOptions options)
: base(source, options)
{
this.Colors = new Buffer(source.Width);
diff --git a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
index 4f8ab3462c..89ae566e9a 100644
--- a/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
+++ b/src/ImageSharp.Drawing/ImageSharp.Drawing.csproj
@@ -37,8 +37,8 @@
-
-
+
+
All
diff --git a/src/ImageSharp.Drawing/Paths/ShapeRegion.cs b/src/ImageSharp.Drawing/Paths/ShapeRegion.cs
index a303179e83..a96b03dd04 100644
--- a/src/ImageSharp.Drawing/Paths/ShapeRegion.cs
+++ b/src/ImageSharp.Drawing/Paths/ShapeRegion.cs
@@ -42,18 +42,18 @@ namespace SixLabors.ImageSharp.Drawing
public override Rectangle Bounds { get; }
///
- public override int Scan(float y, Span buffer)
+ public override int Scan(float y, float[] buffer, int offset)
{
var start = new PointF(this.Bounds.Left - 1, y);
var end = new PointF(this.Bounds.Right + 1, y);
using (var innerBuffer = new Buffer(buffer.Length))
{
- var span = innerBuffer.Span;
- int count = this.Shape.FindIntersections(start, end, span);
+ PointF[] array = innerBuffer.Array;
+ int count = this.Shape.FindIntersections(start, end, array, 0);
for (int i = 0; i < count; i++)
{
- buffer[i] = span[i].X;
+ buffer[i + offset] = array[i].X;
}
return count;
diff --git a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs b/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
index e1ce6b0133..213ab1b4a7 100644
--- a/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
+++ b/src/ImageSharp.Drawing/Processors/DrawImageProcessor.cs
@@ -4,6 +4,8 @@
using System;
using System.Numerics;
using System.Threading.Tasks;
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Helpers;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@@ -58,7 +60,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
public Point Location { get; }
///
- protected override void OnApply(ImageBase source, Rectangle sourceRectangle)
+ protected override void OnApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
{
Image disposableImage = null;
Image targetImage = this.Image;
@@ -94,7 +96,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
Parallel.For(
minY,
maxY,
- source.Configuration.ParallelOptions,
+ configuration.ParallelOptions,
y =>
{
Span background = sourcePixels.GetRowSpan(y).Slice(minX, width);
diff --git a/src/ImageSharp.Drawing/Processors/FillProcessor.cs b/src/ImageSharp.Drawing/Processors/FillProcessor.cs
index fbd9654262..679ca6a228 100644
--- a/src/ImageSharp.Drawing/Processors/FillProcessor.cs
+++ b/src/ImageSharp.Drawing/Processors/FillProcessor.cs
@@ -4,6 +4,7 @@
using System;
using System.Numerics;
using System.Threading.Tasks;
+using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Drawing.Brushes;
using SixLabors.ImageSharp.Drawing.Brushes.Processors;
@@ -39,7 +40,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
}
///
- protected override void OnApply(ImageBase source, Rectangle sourceRectangle)
+ protected override void OnApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
{
int startX = sourceRectangle.X;
int endX = sourceRectangle.Right;
@@ -65,9 +66,6 @@ namespace SixLabors.ImageSharp.Drawing.Processors
int width = maxX - minX;
- // We could possibly do some optimization by having knowledge about the individual brushes operate
- // for example If brush is SolidBrush then we could just get the color upfront
- // and skip using the IBrushApplicator?.
using (var amount = new Buffer(width))
using (BrushApplicator applicator = this.brush.CreateApplicator(source, sourceRectangle, this.options))
{
@@ -79,7 +77,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
Parallel.For(
minY,
maxY,
- source.Configuration.ParallelOptions,
+ configuration.ParallelOptions,
y =>
{
int offsetY = y - startY;
diff --git a/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs b/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
index 3e0dedb3b0..d867008d7e 100644
--- a/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
+++ b/src/ImageSharp.Drawing/Processors/FillRegionProcessor.cs
@@ -3,6 +3,7 @@
using System;
using System.Buffers;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
using SixLabors.ImageSharp.Drawing;
using SixLabors.ImageSharp.Drawing.Brushes;
@@ -57,7 +58,7 @@ namespace SixLabors.ImageSharp.Drawing.Processors
public GraphicsOptions Options { get; }
///
- protected override void OnApply(ImageBase source, Rectangle sourceRectangle)
+ protected override void OnApply(ImageFrame source, Rectangle sourceRectangle, Configuration configuration)
{
Region region = this.Region;
Rectangle rect = region.Bounds;
@@ -93,7 +94,6 @@ namespace SixLabors.ImageSharp.Drawing.Processors
using (BrushApplicator applicator = this.Brush.CreateApplicator(source, rect, this.Options))
{
float[] buffer = arrayPool.Rent(maxIntersections);
- Span bufferSpan = buffer.AsSpan().Slice(0, maxIntersections);
int scanlineWidth = maxX - minX;
using (var scanline = new Buffer(scanlineWidth))
{
@@ -117,14 +117,14 @@ namespace SixLabors.ImageSharp.Drawing.Processors
float subpixelFractionPoint = subpixelFraction / subpixelCount;
for (float subPixel = (float)y; subPixel < y + 1; subPixel += subpixelFraction)
{
- int pointsFound = region.Scan(subPixel, bufferSpan);
+ int pointsFound = region.Scan(subPixel, buffer, 0);
if (pointsFound == 0)
{
// nothing on this line skip
continue;
}
- QuickSort(bufferSpan.Slice(0, pointsFound));
+ QuickSort(new Span(buffer, 0, pointsFound));
for (int point = 0; point < pointsFound; point += 2)
{
diff --git a/src/ImageSharp.Drawing/Region.cs b/src/ImageSharp.Drawing/Region.cs
index 5d4d471f18..c5e7c1cfd4 100644
--- a/src/ImageSharp.Drawing/Region.cs
+++ b/src/ImageSharp.Drawing/Region.cs
@@ -20,7 +20,7 @@ namespace SixLabors.ImageSharp.Drawing
/// Gets the bounding box that entirely surrounds this region.
///
///
- /// This should always contains all possible points returned from .
+ /// This should always contains all possible points returned from .
///
public abstract Rectangle Bounds { get; }
@@ -29,7 +29,8 @@ namespace SixLabors.ImageSharp.Drawing
///
/// The position along the y axis to find intersections.
/// The buffer.
+ /// The point in the buffer to start setting offset.
/// The number of intersections found.
- public abstract int Scan(float y, Span buffer);
+ public abstract int Scan(float y, float[] buffer, int offset);
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Advanced/IConfigurable.cs b/src/ImageSharp/Advanced/IConfigurable.cs
new file mode 100644
index 0000000000..fd97ae921a
--- /dev/null
+++ b/src/ImageSharp/Advanced/IConfigurable.cs
@@ -0,0 +1,16 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+namespace SixLabors.ImageSharp.Advanced
+{
+ ///
+ /// Encapsulates the properties for configuration
+ ///
+ internal interface IConfigurable
+ {
+ ///
+ /// Gets the configuration.
+ ///
+ Configuration Configuration { get; }
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/Advanced/IPixelSource{TPixel}.cs b/src/ImageSharp/Advanced/IPixelSource.cs
similarity index 62%
rename from src/ImageSharp/Advanced/IPixelSource{TPixel}.cs
rename to src/ImageSharp/Advanced/IPixelSource.cs
index 777cb76e2e..c9edf118c6 100644
--- a/src/ImageSharp/Advanced/IPixelSource{TPixel}.cs
+++ b/src/ImageSharp/Advanced/IPixelSource.cs
@@ -2,20 +2,23 @@
// Licensed under the Apache License, Version 2.0.
using System;
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Memory;
+using SixLabors.ImageSharp.MetaData;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp.Advanced
{
///
- /// Allows access to the pixels as an area of contiguous memory in the given pixel format.
+ /// Encapsulates the basic properties and methods required to manipulate images.
///
/// The type of the pixel.
internal interface IPixelSource
where TPixel : struct, IPixel
{
///
- /// Gets the representation of the pixels as an area of contiguous memory in the given pixel format.
+ /// Gets the pixel buffer.
///
- Span Span { get; }
+ Buffer2D PixelBuffer { get; }
}
-}
+}
\ No newline at end of file
diff --git a/src/ImageSharp/Advanced/ImageExtensions.cs b/src/ImageSharp/Advanced/ImageExtensions.cs
index 7377e6ca0b..f4043b5ade 100644
--- a/src/ImageSharp/Advanced/ImageExtensions.cs
+++ b/src/ImageSharp/Advanced/ImageExtensions.cs
@@ -2,19 +2,15 @@
// Licensed under the Apache License, Version 2.0.
using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
-using SixLabors.ImageSharp.Formats;
+using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.Primitives;
namespace SixLabors.ImageSharp.Advanced
{
///
/// Extension methods over Image{TPixel}
///
- public static partial class ImageExtensions
+ internal static class ImageExtensions
{
///
/// Gets the representation of the pixels as an area of contiguous memory in the given pixel format.
@@ -22,29 +18,94 @@ namespace SixLabors.ImageSharp.Advanced
/// The type of the pixel.
/// The source.
/// The
- public static Span GetPixelSpan(this ImageBase source)
+ public static Span GetPixelSpan(this ImageFrame source)
where TPixel : struct, IPixel
=> GetSpan(source);
///
- /// Gets a representing the row 'y' beginning from the the first pixel on that row.
+ /// Gets the representation of the pixels as an area of contiguous memory at row 'y' beginning from the the first pixel on that row.
///
/// The type of the pixel.
/// The source.
/// The row.
/// The
- public static Span GetPixelRowSpan(this ImageBase source, int row)
+ public static Span GetPixelRowSpan(this ImageFrame source, int row)
where TPixel : struct, IPixel
- => GetSpan(source).Slice(row * source.Width, source.Width);
+ => GetSpan(source, row);
///
- /// Gets the span.
+ /// Gets the representation of the pixels as an area of contiguous memory in the given pixel format.
+ ///
+ /// The type of the pixel.
+ /// The source.
+ /// The
+ public static Span GetPixelSpan(this Image source)
+ where TPixel : struct, IPixel
+ => source.Frames.RootFrame.GetPixelSpan();
+
+ ///
+ /// Gets the representation of the pixels as an area of contiguous memory at row 'y' beginning from the the first pixel on that row.
+ ///
+ /// The type of the pixel.
+ /// The source.
+ /// The row.
+ /// The
+ public static Span GetPixelRowSpan(this Image source, int row)
+ where TPixel : struct, IPixel
+ => source.Frames.RootFrame.GetPixelRowSpan(row);
+
+ ///
+ /// Gets the configuration for the image.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// Returns the configuration.
+ public static Configuration GetConfiguration(this Image source)
+ where TPixel : struct, IPixel
+ => GetConfiguration((IConfigurable)source);
+
+ ///
+ /// Gets the span to the backing buffer.
///
/// The type of the pixel.
/// The source.
/// The span retuned from Pixel source
private static Span GetSpan(IPixelSource source)
where TPixel : struct, IPixel
- => source.Span;
+ => source.PixelBuffer.Span;
+
+ ///
+ /// Gets the span to the backing buffer at the given row.
+ ///
+ /// The type of the pixel.
+ /// The source.
+ /// The row.
+ ///
+ /// The span retuned from Pixel source
+ ///
+ private static Span GetSpan(IPixelSource source, int row)
+ where TPixel : struct, IPixel
+ => GetSpan(source.PixelBuffer, row);
+
+ ///
+ /// Gets the span to the backing buffer at the given row.
+ ///
+ /// The type of the pixel.
+ /// The source.
+ /// The row.
+ ///
+ /// The span retuned from Pixel source
+ ///
+ private static Span GetSpan(Buffer2D source, int row)
+ where TPixel : struct, IPixel
+ => source.Span.Slice(row * source.Width, source.Width);
+
+ ///
+ /// Gets the configuration.
+ ///
+ /// The source image
+ /// Returns the bounds of the image
+ private static Configuration GetConfiguration(IConfigurable source)
+ => source?.Configuration ?? Configuration.Default;
}
}
diff --git a/src/ImageSharp/ApplyProcessors.cs b/src/ImageSharp/ApplyProcessors.cs
index 1788332755..58a952c406 100644
--- a/src/ImageSharp/ApplyProcessors.cs
+++ b/src/ImageSharp/ApplyProcessors.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System;
+using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
@@ -24,7 +25,7 @@ namespace SixLabors.ImageSharp
Guard.NotNull(operation, nameof(operation));
Guard.NotNull(source, nameof(source));
- IInternalImageProcessingContext operationsRunner = source.Configuration.ImageOperationsProvider.CreateImageProcessingContext(source, true);
+ IInternalImageProcessingContext operationsRunner = source.GetConfiguration().ImageOperationsProvider.CreateImageProcessingContext(source, true);
operation(operationsRunner);
operationsRunner.Apply();
}
@@ -41,7 +42,7 @@ namespace SixLabors.ImageSharp
Guard.NotNull(operations, nameof(operations));
Guard.NotNull(source, nameof(source));
- IInternalImageProcessingContext operationsRunner = source.Configuration.ImageOperationsProvider.CreateImageProcessingContext(source, true);
+ IInternalImageProcessingContext operationsRunner = source.GetConfiguration().ImageOperationsProvider.CreateImageProcessingContext(source, true);
operationsRunner.ApplyProcessors(operations);
operationsRunner.Apply();
}
@@ -59,7 +60,7 @@ namespace SixLabors.ImageSharp
Guard.NotNull(operation, nameof(operation));
Guard.NotNull(source, nameof(source));
- IInternalImageProcessingContext operationsRunner = source.Configuration.ImageOperationsProvider.CreateImageProcessingContext(source, false);
+ IInternalImageProcessingContext operationsRunner = source.GetConfiguration().ImageOperationsProvider.CreateImageProcessingContext(source, false);
operation(operationsRunner);
return operationsRunner.Apply();
}
@@ -77,7 +78,7 @@ namespace SixLabors.ImageSharp
Guard.NotNull(operations, nameof(operations));
Guard.NotNull(source, nameof(source));
- IInternalImageProcessingContext operationsRunner = source.Configuration.ImageOperationsProvider.CreateImageProcessingContext(source, false);
+ IInternalImageProcessingContext operationsRunner = source.GetConfiguration().ImageOperationsProvider.CreateImageProcessingContext(source, false);
operationsRunner.ApplyProcessors(operations);
return operationsRunner.Apply();
}
diff --git a/src/ImageSharp/Common/Helpers/ImageMaths.cs b/src/ImageSharp/Common/Helpers/ImageMaths.cs
index 8453881cc5..8717fa9876 100644
--- a/src/ImageSharp/Common/Helpers/ImageMaths.cs
+++ b/src/ImageSharp/Common/Helpers/ImageMaths.cs
@@ -150,7 +150,7 @@ namespace SixLabors.ImageSharp
///
/// The .
///
- public static Rectangle GetFilteredBoundingRectangle(ImageBase bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
+ public static Rectangle GetFilteredBoundingRectangle(ImageFrame bitmap, float componentValue, RgbaComponent channel = RgbaComponent.B)
where TPixel : struct, IPixel
{
int width = bitmap.Width;
@@ -158,7 +158,7 @@ namespace SixLabors.ImageSharp
var topLeft = default(Point);
var bottomRight = default(Point);
- Func, int, int, float, bool> delegateFunc;
+ Func, int, int, float, bool> delegateFunc;
// Determine which channel to check against
switch (channel)
@@ -180,7 +180,7 @@ namespace SixLabors.ImageSharp
break;
}
- int GetMinY(ImageBase pixels)
+ int GetMinY(ImageFrame pixels)
{
for (int y = 0; y < height; y++)
{
@@ -196,7 +196,7 @@ namespace SixLabors.ImageSharp
return 0;
}
- int GetMaxY(ImageBase pixels)
+ int GetMaxY(ImageFrame pixels)
{
for (int y = height - 1; y > -1; y--)
{
@@ -212,7 +212,7 @@ namespace SixLabors.ImageSharp
return height;
}
- int GetMinX(ImageBase pixels)
+ int GetMinX(ImageFrame pixels)
{
for (int x = 0; x < width; x++)
{
@@ -228,7 +228,7 @@ namespace SixLabors.ImageSharp
return 0;
}
- int GetMaxX(ImageBase pixels)
+ int GetMaxX(ImageFrame pixels)
{
for (int x = width - 1; x > -1; x--)
{
diff --git a/src/ImageSharp/DefaultInternalImageProcessorContext.cs b/src/ImageSharp/DefaultInternalImageProcessorContext.cs
index 8eb1c09fee..575525a773 100644
--- a/src/ImageSharp/DefaultInternalImageProcessorContext.cs
+++ b/src/ImageSharp/DefaultInternalImageProcessorContext.cs
@@ -1,6 +1,7 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
+using SixLabors.ImageSharp.Helpers;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.Primitives;
@@ -53,8 +54,7 @@ namespace SixLabors.ImageSharp
// This will only work if the first processor applied is the cloning one thus
// realistically for this optermissation to work the resize must the first processor
// applied any only up processors will take the douple data path.
- var cloningImageProcessor = processor as ICloningImageProcessor;
- if (cloningImageProcessor != null)
+ if (processor is ICloningImageProcessor cloningImageProcessor)
{
this.destination = cloningImageProcessor.CloneAndApply(this.source, rectangle);
return this;
diff --git a/src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuserBase.cs b/src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuserBase.cs
index 3fb86f1924..510a097eaf 100644
--- a/src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuserBase.cs
+++ b/src/ImageSharp/Dithering/ErrorDiffusion/ErrorDiffuserBase.cs
@@ -70,7 +70,7 @@ namespace SixLabors.ImageSharp.Dithering.Base
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Dither(ImageBase pixels, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY)
+ public void Dither(ImageFrame pixels, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY)
where TPixel : struct, IPixel
{
this.Dither(pixels, source, transformed, x, y, minX, minY, maxX, maxY, true);
@@ -78,7 +78,7 @@ namespace SixLabors.ImageSharp.Dithering.Base
///
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- public void Dither(ImageBase image, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY, bool replacePixel)
+ public void Dither(ImageFrame image, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY, bool replacePixel)
where TPixel : struct, IPixel
{
if (replacePixel)
diff --git a/src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs b/src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs
index 850c978fef..c538d643c6 100644
--- a/src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs
+++ b/src/ImageSharp/Dithering/ErrorDiffusion/IErrorDiffuser.cs
@@ -23,7 +23,7 @@ namespace SixLabors.ImageSharp.Dithering
/// The maximum column value.
/// The maximum row value.
/// The pixel format.
- void Dither(ImageBase image, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY)
+ void Dither(ImageFrame image, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY)
where TPixel : struct, IPixel;
///
@@ -43,7 +43,7 @@ namespace SixLabors.ImageSharp.Dithering
/// Generally this would be true for standard two-color dithering but when used in conjunction with color quantization this should be false.
///
/// The pixel format.
- void Dither(ImageBase image, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY, bool replacePixel)
+ void Dither(ImageFrame image, TPixel source, TPixel transformed, int x, int y, int minX, int minY, int maxX, int maxY, bool replacePixel)
where TPixel : struct, IPixel;
}
}
diff --git a/src/ImageSharp/Dithering/Ordered/IOrderedDither.cs b/src/ImageSharp/Dithering/Ordered/IOrderedDither.cs
index e3c7c5cbaf..e0e11ad9ee 100644
--- a/src/ImageSharp/Dithering/Ordered/IOrderedDither.cs
+++ b/src/ImageSharp/Dithering/Ordered/IOrderedDither.cs
@@ -22,7 +22,7 @@ namespace SixLabors.ImageSharp.Dithering
/// The column index.
/// The row index.
/// The pixel format.
- void Dither(ImageBase image, TPixel source, TPixel upper, TPixel lower, byte[] bytes, int index, int x, int y)
+ void Dither(ImageFrame image, TPixel source, TPixel upper, TPixel lower, byte[] bytes, int index, int x, int y)
where TPixel : struct, IPixel;
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Dithering/Ordered/OrderedDitherBase.cs b/src/ImageSharp/Dithering/Ordered/OrderedDitherBase.cs
index 6fa406bec8..09c30eb272 100644
--- a/src/ImageSharp/Dithering/Ordered/OrderedDitherBase.cs
+++ b/src/ImageSharp/Dithering/Ordered/OrderedDitherBase.cs
@@ -26,7 +26,7 @@ namespace SixLabors.ImageSharp.Dithering.Base
}
///
- public void Dither(ImageBase image, TPixel source, TPixel upper, TPixel lower, byte[] bytes, int index, int x, int y)
+ public void Dither(ImageFrame image, TPixel source, TPixel upper, TPixel lower, byte[] bytes, int index, int x, int y)
where TPixel : struct, IPixel
{
// TODO: This doesn't really cut it for me.
diff --git a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
index 12dd0f91a3..d34d170847 100644
--- a/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
+++ b/src/ImageSharp/Formats/Bmp/BmpEncoderCore.cs
@@ -33,12 +33,12 @@ namespace SixLabors.ImageSharp.Formats.Bmp
}
///
- /// Encodes the image to the specified stream from the .
+ /// Encodes the image to the specified stream from the .
///
/// The pixel format.
- /// The to encode from.
+ /// The to encode from.
/// The to encode the image data to.
- public void Encode(ImageBase image, Stream stream)
+ public void Encode(Image image, Stream stream)
where TPixel : struct, IPixel
{
Guard.NotNull(image, nameof(image));
@@ -73,7 +73,7 @@ namespace SixLabors.ImageSharp.Formats.Bmp
WriteHeader(writer, fileHeader);
this.WriteInfo(writer, infoHeader);
- this.WriteImage(writer, image);
+ this.WriteImage(writer, image.Frames.RootFrame);
writer.Flush();
}
@@ -125,9 +125,9 @@ namespace SixLabors.ImageSharp.Formats.Bmp
/// The pixel format.
/// The containing the stream to write to.
///
- /// The containing pixel data.
+ /// The containing pixel data.
///
- private void WriteImage(EndianBinaryWriter writer, ImageBase image)
+ private void WriteImage(EndianBinaryWriter writer, ImageFrame image)
where TPixel : struct, IPixel
{
using (PixelAccessor pixels = image.Lock())
diff --git a/src/ImageSharp/Formats/Bmp/ImageExtensions.cs b/src/ImageSharp/Formats/Bmp/ImageExtensions.cs
index 558ce69c55..935ce8f4ad 100644
--- a/src/ImageSharp/Formats/Bmp/ImageExtensions.cs
+++ b/src/ImageSharp/Formats/Bmp/ImageExtensions.cs
@@ -3,6 +3,7 @@
using System;
using System.IO;
+using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Bmp;
using SixLabors.ImageSharp.PixelFormats;
@@ -35,6 +36,6 @@ namespace SixLabors.ImageSharp
/// Thrown if the stream is null.
public static void SaveAsBmp(this Image source, Stream stream, BmpEncoder encoder)
where TPixel : struct, IPixel
- => source.Save(stream, encoder ?? source.Configuration.FindEncoder(ImageFormats.Bmp));
+ => source.Save(stream, encoder ?? source.GetConfiguration().FindEncoder(ImageFormats.Bmp));
}
}
diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
index cb124d305a..c3c395e852 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
@@ -369,7 +369,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
ImageFrame currentFrame = null;
- ImageBase image;
+ ImageFrame image;
if (this.previousFrame == null)
{
@@ -378,7 +378,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.SetFrameMetaData(this.metaData);
- image = this.image;
+ image = this.image.Frames.RootFrame;
}
else
{
@@ -471,7 +471,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
return;
}
- this.previousFrame = currentFrame == null ? this.image.ToFrame() : currentFrame;
+ this.previousFrame = currentFrame == null ? this.image.Frames.RootFrame : currentFrame;
if (this.graphicsControlExtension != null &&
this.graphicsControlExtension.DisposalMethod == DisposalMethod.RestoreToBackground)
@@ -484,7 +484,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// Restores the current frame area to the background.
///
/// The frame.
- private void RestoreToBackground(ImageBase frame)
+ private void RestoreToBackground(ImageFrame frame)
{
if (this.restoreArea == null)
{
diff --git a/src/ImageSharp/Formats/Gif/GifEncoder.cs b/src/ImageSharp/Formats/Gif/GifEncoder.cs
index 2c3bb29299..ccf46a17d6 100644
--- a/src/ImageSharp/Formats/Gif/GifEncoder.cs
+++ b/src/ImageSharp/Formats/Gif/GifEncoder.cs
@@ -44,7 +44,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
public void Encode(Image image, Stream stream)
where TPixel : struct, IPixel
{
- GifEncoderCore encoder = new GifEncoderCore(this);
+ var encoder = new GifEncoderCore(this);
encoder.Encode(image, stream);
}
}
diff --git a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
index 5022678384..d143cd5319 100644
--- a/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifEncoderCore.cs
@@ -90,20 +90,20 @@ namespace SixLabors.ImageSharp.Formats.Gif
var writer = new EndianBinaryWriter(Endianness.LittleEndian, stream);
// Ensure that pallete size can be set but has a fallback.
- int paletteSize = this.paletteSize;
- paletteSize = paletteSize > 0 ? paletteSize.Clamp(1, 256) : 256;
+ int size = this.paletteSize;
+ size = size > 0 ? size.Clamp(1, 256) : 256;
// Get the number of bits.
- this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(paletteSize);
+ this.bitDepth = ImageMaths.GetBitsNeededForColorDepth(size);
- this.hasFrames = image.Frames.Any();
+ this.hasFrames = image.Frames.Count > 1;
// Dithering when animating gifs is a bad idea as we introduce pixel tearing across frames.
var ditheredQuantizer = (IQuantizer)this.quantizer;
ditheredQuantizer.Dither = !this.hasFrames;
// Quantize the image returning a palette.
- QuantizedImage quantized = ditheredQuantizer.Quantize(image, paletteSize);
+ QuantizedImage quantized = ditheredQuantizer.Quantize(image.Frames.RootFrame, size);
int index = this.GetTransparentIndex(quantized);
@@ -114,28 +114,27 @@ namespace SixLabors.ImageSharp.Formats.Gif
this.WriteLogicalScreenDescriptor(image, writer, index);
// Write the first frame.
- this.WriteGraphicalControlExtension(image.MetaData, writer, index);
this.WriteComments(image, writer);
- this.WriteImageDescriptor(image, writer);
- this.WriteColorTable(quantized, writer);
- this.WriteImageData(quantized, writer);
// Write additional frames.
if (this.hasFrames)
{
this.WriteApplicationExtension(writer, image.MetaData.RepeatCount, image.Frames.Count);
+ }
- // ReSharper disable once ForCanBeConvertedToForeach
- for (int i = 0; i < image.Frames.Count; i++)
+ foreach (ImageFrame frame in image.Frames)
+ {
+ if (quantized == null)
{
- ImageFrame frame = image.Frames[i];
- QuantizedImage quantizedFrame = ditheredQuantizer.Quantize(frame, paletteSize);
-
- this.WriteGraphicalControlExtension(frame.MetaData, writer, this.GetTransparentIndex(quantizedFrame));
- this.WriteImageDescriptor(frame, writer);
- this.WriteColorTable(quantizedFrame, writer);
- this.WriteImageData(quantizedFrame, writer);
+ quantized = ditheredQuantizer.Quantize(frame, size);
}
+
+ this.WriteGraphicalControlExtension(frame.MetaData, writer, this.GetTransparentIndex(quantized));
+ this.WriteImageDescriptor(frame, writer);
+ this.WriteColorTable(quantized, writer);
+ this.WriteImageData(quantized, writer);
+
+ quantized = null; // so next frame can regenerate it
}
// TODO: Write extension etc
@@ -253,7 +252,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// Writes the image comments to the stream.
///
/// The pixel format.
- /// The to be encoded.
+ /// The to be encoded.
/// The stream to write to.
private void WriteComments(Image image, EndianBinaryWriter writer)
where TPixel : struct, IPixel
@@ -321,9 +320,9 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// Writes the image descriptor to the stream.
///
/// The pixel format.
- /// The to be encoded.
+ /// The to be encoded.
/// The stream to write to.
- private void WriteImageDescriptor(ImageBase image, EndianBinaryWriter writer)
+ private void WriteImageDescriptor(ImageFrame image, EndianBinaryWriter writer)
where TPixel : struct, IPixel
{
writer.Write(GifConstants.ImageDescriptorLabel); // 2c
@@ -347,7 +346,7 @@ namespace SixLabors.ImageSharp.Formats.Gif
/// Writes the color table to the stream.
///
/// The pixel format.
- /// The to encode.
+ /// The to encode.
/// The writer to write to the stream with.
private void WriteColorTable(QuantizedImage image, EndianBinaryWriter writer)
where TPixel : struct, IPixel
diff --git a/src/ImageSharp/Formats/Gif/ImageExtensions.cs b/src/ImageSharp/Formats/Gif/ImageExtensions.cs
index b5f358f583..939eb456e1 100644
--- a/src/ImageSharp/Formats/Gif/ImageExtensions.cs
+++ b/src/ImageSharp/Formats/Gif/ImageExtensions.cs
@@ -3,6 +3,7 @@
using System;
using System.IO;
+using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Gif;
using SixLabors.ImageSharp.PixelFormats;
@@ -35,6 +36,6 @@ namespace SixLabors.ImageSharp
/// Thrown if the stream is null.
public static void SaveAsGif(this Image source, Stream stream, GifEncoder encoder)
where TPixel : struct, IPixel
- => source.Save(stream, encoder ?? source.Configuration.FindEncoder(ImageFormats.Gif));
+ => source.Save(stream, encoder ?? source.GetConfiguration().FindEncoder(ImageFormats.Gif));
}
}
diff --git a/src/ImageSharp/Formats/IImageDecoder.cs b/src/ImageSharp/Formats/IImageDecoder.cs
index 86d5f5375b..e392cf7c61 100644
--- a/src/ImageSharp/Formats/IImageDecoder.cs
+++ b/src/ImageSharp/Formats/IImageDecoder.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Formats
public interface IImageDecoder
{
///
- /// Decodes the image from the specified stream to the .
+ /// Decodes the image from the specified stream to the .
///
/// The pixel format.
/// The configuration for the image.
diff --git a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs
index 57b29e8ab4..84867d2766 100644
--- a/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs
+++ b/src/ImageSharp/Formats/Jpeg/Common/Decoder/JpegImagePostProcessor.cs
@@ -2,6 +2,7 @@ using System;
using System.Linq;
using System.Numerics;
using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Helpers;
using SixLabors.ImageSharp.Memory;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.Primitives;
@@ -16,7 +17,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
/// (4) Packing pixels from the buffer.
/// These operations are executed in steps.
/// image rows are converted in one step,
- /// which means that size of the allocated memory is limited (does not depend on ).
+ /// which means that size of the allocated memory is limited (does not depend on ).
///
internal class JpegImagePostProcessor : IDisposable
{
@@ -97,7 +98,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
///
/// The pixel type
/// The destination image
- public void PostProcess(Image destination)
+ public void PostProcess(ImageFrame destination)
where TPixel : struct, IPixel
{
this.PixelRowCounter = 0;
@@ -118,7 +119,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
///
/// The pixel type
/// The destination image.
- public void DoPostProcessorStep(Image destination)
+ public void DoPostProcessorStep(ImageFrame destination)
where TPixel : struct, IPixel
{
foreach (JpegComponentPostProcessor cpp in this.ComponentProcessors)
@@ -136,7 +137,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.Common.Decoder
///
/// The pixel type
/// The destination image
- private void ConvertColorsInto(Image destination)
+ private void ConvertColorsInto(ImageFrame destination)
where TPixel : struct, IPixel
{
int maxY = Math.Min(destination.Height, this.PixelRowCounter + PixelRowsPerStep);
diff --git a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
index 33ebe72d01..8369e92366 100644
--- a/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/GolangPort/OrigJpegDecoderCore.cs
@@ -815,7 +815,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.GolangPort
using (var postProcessor = new JpegImagePostProcessor(this))
{
var image = new Image(this.configuration, this.ImageWidth, this.ImageHeight, this.MetaData);
- postProcessor.PostProcess(image);
+ postProcessor.PostProcess(image.Frames.RootFrame);
return image;
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs b/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs
index c7d7b26da6..9cd7b3a8bd 100644
--- a/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs
+++ b/src/ImageSharp/Formats/Jpeg/ImageExtensions.cs
@@ -3,6 +3,7 @@
using System;
using System.IO;
+using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Jpeg;
using SixLabors.ImageSharp.PixelFormats;
@@ -35,6 +36,6 @@ namespace SixLabors.ImageSharp
/// Thrown if the stream is null.
public static void SaveAsJpeg(this Image source, Stream stream, JpegEncoder encoder)
where TPixel : struct, IPixel
- => source.Save(stream, encoder ?? source.Configuration.FindEncoder(ImageFormats.Jpeg));
+ => source.Save(stream, encoder ?? source.GetConfiguration().FindEncoder(ImageFormats.Jpeg));
}
}
diff --git a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
index c5225b5467..6c84597c99 100644
--- a/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
+++ b/src/ImageSharp/Formats/Jpeg/PdfJsPort/PdfJsJpegDecoderCore.cs
@@ -159,7 +159,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
this.QuantizeAndInverseAllComponents();
var image = new Image(this.configuration, this.ImageWidth, this.ImageHeight, metadata);
- this.FillPixelData(image);
+ this.FillPixelData(image.Frames.RootFrame);
this.AssignResolution(image);
return image;
}
@@ -326,7 +326,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
///
/// The pixel format.
/// The image
- private void FillPixelData(Image image)
+ private void FillPixelData(ImageFrame image)
where TPixel : struct, IPixel
{
if (this.NumberOfComponents > 4)
@@ -856,7 +856,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillGrayScaleImage(Image image)
+ private void FillGrayScaleImage(ImageFrame image)
where TPixel : struct, IPixel
{
for (int y = 0; y < image.Height; y++)
@@ -875,7 +875,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillYCbCrImage(Image image)
+ private void FillYCbCrImage(ImageFrame image)
where TPixel : struct, IPixel
{
for (int y = 0; y < image.Height; y++)
@@ -894,7 +894,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillYcckImage(Image image)
+ private void FillYcckImage(ImageFrame image)
where TPixel : struct, IPixel
{
for (int y = 0; y < image.Height; y++)
@@ -915,7 +915,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillCmykImage(Image image)
+ private void FillCmykImage(ImageFrame image)
where TPixel : struct, IPixel
{
for (int y = 0; y < image.Height; y++)
@@ -941,7 +941,7 @@ namespace SixLabors.ImageSharp.Formats.Jpeg.PdfJsPort
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
- private void FillRgbImage(Image image)
+ private void FillRgbImage(ImageFrame image)
where TPixel : struct, IPixel
{
for (int y = 0; y < image.Height; y++)
diff --git a/src/ImageSharp/Formats/Png/ImageExtensions.cs b/src/ImageSharp/Formats/Png/ImageExtensions.cs
index 5d7539915c..10970fc16a 100644
--- a/src/ImageSharp/Formats/Png/ImageExtensions.cs
+++ b/src/ImageSharp/Formats/Png/ImageExtensions.cs
@@ -2,6 +2,7 @@
// Licensed under the Apache License, Version 2.0.
using System.IO;
+using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.Formats;
using SixLabors.ImageSharp.Formats.Png;
using SixLabors.ImageSharp.PixelFormats;
@@ -34,6 +35,6 @@ namespace SixLabors.ImageSharp
/// Thrown if the stream is null.
public static void SaveAsPng(this Image source, Stream stream, PngEncoder encoder)
where TPixel : struct, IPixel
- => source.Save(stream, encoder ?? source.Configuration.FindEncoder(ImageFormats.Png));
+ => source.Save(stream, encoder ?? source.GetConfiguration().FindEncoder(ImageFormats.Png));
}
}
diff --git a/src/ImageSharp/Formats/Png/PngDecoder.cs b/src/ImageSharp/Formats/Png/PngDecoder.cs
index 786f3fe901..739fd6051e 100644
--- a/src/ImageSharp/Formats/Png/PngDecoder.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoder.cs
@@ -42,7 +42,7 @@ namespace SixLabors.ImageSharp.Formats.Png
public Encoding TextEncoding { get; set; } = PngConstants.DefaultEncoding;
///
- /// Decodes the image from the specified stream to the .
+ /// Decodes the image from the specified stream to the .
///
/// The pixel format.
/// The configuration for the image.
diff --git a/src/ImageSharp/Formats/Png/PngDecoderCore.cs b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
index 48618c5eee..4fd57c2784 100644
--- a/src/ImageSharp/Formats/Png/PngDecoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngDecoderCore.cs
@@ -236,7 +236,7 @@ namespace SixLabors.ImageSharp.Formats.Png
}
deframeStream.AllocateNewBytes(currentChunk.Length);
- this.ReadScanlines(deframeStream.CompressedStream, image);
+ this.ReadScanlines(deframeStream.CompressedStream, image.Frames.RootFrame);
stream.Read(this.crcBuffer, 0, 4);
break;
case PngChunkTypes.Palette:
@@ -442,7 +442,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The containing data.
/// The pixel data.
- private void ReadScanlines(Stream dataStream, Image image)
+ private void ReadScanlines(Stream dataStream, ImageFrame image)
where TPixel : struct, IPixel
{
if (this.header.InterlaceMethod == PngInterlaceMode.Adam7)
@@ -461,7 +461,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The compressed pixel data stream.
/// The image to decode to.
- private void DecodePixelData(Stream compressedStream, Image image)
+ private void DecodePixelData(Stream compressedStream, ImageFrame image)
where TPixel : struct, IPixel
{
while (this.currentRow < this.header.Height)
@@ -519,7 +519,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The compressed pixel data stream.
/// The current image.
- private void DecodeInterlacedPixelData(Stream compressedStream, Image image)
+ private void DecodeInterlacedPixelData(Stream compressedStream, ImageFrame image)
where TPixel : struct, IPixel
{
while (true)
@@ -609,7 +609,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The de-filtered scanline
/// The image
- private void ProcessDefilteredScanline(byte[] defilteredScanline, Image pixels)
+ private void ProcessDefilteredScanline(byte[] defilteredScanline, ImageFrame pixels)
where TPixel : struct, IPixel
{
var color = default(TPixel);
diff --git a/src/ImageSharp/Formats/Png/PngEncoderCore.cs b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
index dfc905bfa3..660c371873 100644
--- a/src/ImageSharp/Formats/Png/PngEncoderCore.cs
+++ b/src/ImageSharp/Formats/Png/PngEncoderCore.cs
@@ -166,7 +166,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// Encodes the image to the specified stream from the .
///
/// The pixel format.
- /// The to encode from.
+ /// The to encode from.
/// The to encode the image data to.
public void Encode(Image image, Stream stream)
where TPixel : struct, IPixel
@@ -233,12 +233,12 @@ namespace SixLabors.ImageSharp.Formats.Png
// Collect the indexed pixel data
if (this.pngColorType == PngColorType.Palette)
{
- this.CollectIndexedBytes(image, stream, header);
+ this.CollectIndexedBytes(image.Frames.RootFrame, stream, header);
}
this.WritePhysicalChunk(stream, image);
this.WriteGammaChunk(stream);
- this.WriteDataChunks(image, stream);
+ this.WriteDataChunks(image.Frames.RootFrame, stream);
this.WriteEndChunk(stream);
stream.Flush();
}
@@ -304,7 +304,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The image to encode.
/// The containing image data.
/// The .
- private void CollectIndexedBytes(ImageBase image, Stream stream, PngHeader header)
+ private void CollectIndexedBytes(ImageFrame image, Stream stream, PngHeader header)
where TPixel : struct, IPixel
{
// Quantize the image and get the pixels.
@@ -529,7 +529,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The .
/// The image to encode.
/// The
- private QuantizedImage WritePaletteChunk(Stream stream, PngHeader header, ImageBase image)
+ private QuantizedImage WritePaletteChunk(Stream stream, PngHeader header, ImageFrame image)
where TPixel : struct, IPixel
{
if (this.paletteSize > 256)
@@ -649,7 +649,7 @@ namespace SixLabors.ImageSharp.Formats.Png
/// The pixel format.
/// The image.
/// The stream.
- private void WriteDataChunks(Image pixels, Stream stream)
+ private void WriteDataChunks(ImageFrame pixels, Stream stream)
where TPixel : struct, IPixel
{
this.bytesPerScanline = this.width * this.bytesPerPixel;
diff --git a/src/ImageSharp/Helpers/ImageExtensions.cs b/src/ImageSharp/Helpers/ImageExtensions.cs
new file mode 100644
index 0000000000..dbf2e34a42
--- /dev/null
+++ b/src/ImageSharp/Helpers/ImageExtensions.cs
@@ -0,0 +1,61 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Runtime.CompilerServices;
+using System.Text;
+using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.Formats;
+using SixLabors.ImageSharp.PixelFormats;
+using SixLabors.Primitives;
+
+namespace SixLabors.ImageSharp.Helpers
+{
+ ///
+ /// Extension methods over Image{TPixel}
+ ///
+ public static partial class ImageExtensions
+ {
+ ///
+ /// Gets the bounds of the image.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// Returns the bounds of the image
+ public static Rectangle Bounds(this Image source)
+ where TPixel : struct, IPixel
+ => new Rectangle(0, 0, source.Width, source.Height);
+
+ ///
+ /// Gets the bounds of the image.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// Returns the bounds of the image
+ public static Rectangle Bounds(this ImageFrame source)
+ where TPixel : struct, IPixel
+ => new Rectangle(0, 0, source.Width, source.Height);
+
+ ///
+ /// Gets the size of the image.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// Returns the bounds of the image
+ public static Size Size(this Image source)
+ where TPixel : struct, IPixel
+ => new Size(source.Width, source.Height);
+
+ ///
+ /// Gets the size of the image.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// Returns the bounds of the image
+ public static Size Size(this ImageFrame source)
+ where TPixel : struct, IPixel
+ => new Size(source.Width, source.Height);
+ }
+}
diff --git a/src/ImageSharp/Image/ICloningImageProcessor.cs b/src/ImageSharp/ICloningImageProcessor.cs
similarity index 96%
rename from src/ImageSharp/Image/ICloningImageProcessor.cs
rename to src/ImageSharp/ICloningImageProcessor.cs
index 1e7d6e4f0a..aeb3c815ec 100644
--- a/src/ImageSharp/Image/ICloningImageProcessor.cs
+++ b/src/ImageSharp/ICloningImageProcessor.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp.Processing
where TPixel : struct, IPixel
{
///
- /// Applies the process to the specified portion of the specified .
+ /// Applies the process to the specified portion of the specified .
///
/// The source image. Cannot be null.
///
diff --git a/src/ImageSharp/Image/IImageProcessor.cs b/src/ImageSharp/IImageProcessor.cs
similarity index 96%
rename from src/ImageSharp/Image/IImageProcessor.cs
rename to src/ImageSharp/IImageProcessor.cs
index b81f08e150..bd6df8d835 100644
--- a/src/ImageSharp/Image/IImageProcessor.cs
+++ b/src/ImageSharp/IImageProcessor.cs
@@ -14,7 +14,7 @@ namespace SixLabors.ImageSharp
where TPixel : struct, IPixel
{
///
- /// Applies the process to the specified portion of the specified .
+ /// Applies the process to the specified portion of the specified .
///
/// The source image. Cannot be null.
///
diff --git a/src/ImageSharp/Image/IImage.cs b/src/ImageSharp/Image/IImage.cs
deleted file mode 100644
index 3223e20f75..0000000000
--- a/src/ImageSharp/Image/IImage.cs
+++ /dev/null
@@ -1,19 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using SixLabors.ImageSharp.Formats;
-using SixLabors.ImageSharp.MetaData;
-
-namespace SixLabors.ImageSharp
-{
- ///
- /// Encapsulates the basic properties and methods required to manipulate images.
- ///
- internal interface IImage : IImageBase
- {
- ///
- /// Gets the meta data of the image.
- ///
- ImageMetaData MetaData { get; }
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Image/IImageBase.cs b/src/ImageSharp/Image/IImageBase.cs
deleted file mode 100644
index 9aea1517d6..0000000000
--- a/src/ImageSharp/Image/IImageBase.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using SixLabors.Primitives;
-
-namespace SixLabors.ImageSharp
-{
- ///
- /// Encapsulates the basic properties and methods required to manipulate images.
- ///
- public interface IImageBase
- {
- ///
- /// Gets the width in pixels.
- ///
- int Width { get; }
-
- ///
- /// Gets the height in pixels.
- ///
- int Height { get; }
-
- ///
- /// Gets the configuration providing initialization code which allows extending the library.
- ///
- Configuration Configuration { get; }
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Image/IImageFrame.cs b/src/ImageSharp/Image/IImageFrame.cs
deleted file mode 100644
index 31a8165887..0000000000
--- a/src/ImageSharp/Image/IImageFrame.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using SixLabors.ImageSharp.MetaData;
-
-namespace SixLabors.ImageSharp
-{
- ///
- /// Encapsulates the basic properties and methods required to manipulate images.
- ///
- internal interface IImageFrame : IImageBase
- {
- ///
- /// Gets the meta data of the image.
- ///
- ImageFrameMetaData MetaData { get; }
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Image/IImageFrameCollection.cs b/src/ImageSharp/Image/IImageFrameCollection.cs
new file mode 100644
index 0000000000..ee325bc632
--- /dev/null
+++ b/src/ImageSharp/Image/IImageFrameCollection.cs
@@ -0,0 +1,84 @@
+// Copyright (c) Six Labors and contributors.
+// Licensed under the Apache License, Version 2.0.
+
+using System;
+using System.Collections;
+using System.Collections.Generic;
+
+using SixLabors.ImageSharp.PixelFormats;
+
+namespace SixLabors.ImageSharp
+{
+ ///
+ /// Encapsulates an imaged collection of frames.
+ ///
+ /// The type of the pixel.
+ public interface IImageFrameCollection : IEnumerable>
+ where TPixel : struct, IPixel
+ {
+ ///
+ /// Gets the count.
+ ///
+ int Count { get; }
+
+ ///
+ /// Gets the root frame.
+ ///
+ ImageFrame RootFrame { get; }
+
+ ///
+ /// Gets or sets the at the specified index.
+ ///
+ ///
+ /// The .
+ ///
+ /// The index.
+ /// The at the specified index.
+ ImageFrame this[int index] { get; set; }
+
+ ///
+ /// Determines the index of a specific in the .
+ ///
+ /// The to locate in the .
+ /// The index of item if found in the list; otherwise, -1.
+ int IndexOf(ImageFrame frame);
+
+ ///
+ /// Inserts the to the at the specified .
+ ///
+ /// The zero-based index at which item should be inserted..
+ /// The to insert into the .
+ void Insert(int index, ImageFrame frame);
+
+ ///
+ /// Removes the from the at the specified index.
+ ///
+ /// The zero-based index of the item to remove.
+ /// Cannot remove last frame.
+ void RemoveAt(int index);
+
+ ///
+ /// Adds the specified frame.
+ ///
+ /// The frame.
+ /// Frame must have the same dimensions as the image - frame
+ void Add(ImageFrame frame);
+
+ ///
+ /// Determines whether the contains the .
+ ///
+ /// The frame.
+ ///
+ /// true if the the specified frame; otherwise, false.
+ ///
+ bool Contains(ImageFrame frame);
+
+ ///
+ /// Removes the specified frame.
+ ///
+ /// The frame.
+ /// true if item is found in the ; otherwise,
+ /// Cannot remove last frame
+ bool Remove(ImageFrame frame);
+ }
+}
\ No newline at end of file
diff --git a/src/ImageSharp/Image/Image.LoadPixelData.cs b/src/ImageSharp/Image/Image.LoadPixelData.cs
index 6302eb66be..5f1a1617f2 100644
--- a/src/ImageSharp/Image/Image.LoadPixelData.cs
+++ b/src/ImageSharp/Image/Image.LoadPixelData.cs
@@ -25,10 +25,34 @@ namespace SixLabors.ImageSharp
/// The height of the final image.
/// The pixel format.
/// A new .
- public static Image LoadPixelData(Span data, int width, int height)
+ public static Image LoadPixelData(TPixel[] data, int width, int height)
where TPixel : struct, IPixel
=> LoadPixelData(Configuration.Default, data, width, height);
+ ///
+ /// Create a new instance of the class from the raw data.
+ ///
+ /// The byte array containing image data.
+ /// The width of the final image.
+ /// The height of the final image.
+ /// The pixel format.
+ /// A new .
+ private static Image LoadPixelData(Span data, int width, int height)
+ where TPixel : struct, IPixel
+ => LoadPixelData(Configuration.Default, data, width, height);
+
+ ///
+ /// Create a new instance of the class from the given byte array in format.
+ ///
+ /// The byte array containing image data.
+ /// The width of the final image.
+ /// The height of the final image.
+ /// The pixel format.
+ /// A new .
+ public static Image LoadPixelData(byte[] data, int width, int height)
+ where TPixel : struct, IPixel
+ => LoadPixelData(Configuration.Default, data, width, height);
+
///
/// Create a new instance of the class from the given byte array in format.
///
@@ -37,7 +61,7 @@ namespace SixLabors.ImageSharp
/// The height of the final image.
/// The pixel format.
/// A new .
- public static Image LoadPixelData(Span data, int width, int height)
+ private static Image LoadPixelData(Span data, int width, int height)
where TPixel : struct, IPixel
=> LoadPixelData(Configuration.Default, data, width, height);
@@ -50,7 +74,20 @@ namespace SixLabors.ImageSharp
/// The height of the final image.
/// The pixel format.
/// A new .
- public static Image LoadPixelData(Configuration config, Span data, int width, int height)
+ public static Image LoadPixelData(Configuration config, byte[] data, int width, int height)
+ where TPixel : struct, IPixel
+ => LoadPixelData(config, new Span(data).NonPortableCast(), width, height);
+
+ ///
+ /// Create a new instance of the class from the given byte array in format.
+ ///
+ /// The config for the decoder.
+ /// The byte array containing image data.
+ /// The width of the final image.
+ /// The height of the final image.
+ /// The pixel format.
+ /// A new .
+ private static Image LoadPixelData(Configuration config, Span data, int width, int height)
where TPixel : struct, IPixel
=> LoadPixelData(config, data.NonPortableCast(), width, height);
@@ -63,7 +100,7 @@ namespace SixLabors.ImageSharp
/// The height of the final image.
/// The pixel format.
/// A new .
- public static Image LoadPixelData(Configuration config, Span data, int width, int height)
+ public static Image LoadPixelData(Configuration config, TPixel[] data, int width, int height)
where TPixel : struct, IPixel
{
int count = width * height;
@@ -74,5 +111,26 @@ namespace SixLabors.ImageSharp
return image;
}
+
+ ///
+ /// Create a new instance of the class from the raw data.
+ ///
+ /// The config for the decoder.
+ /// The Span containing the image Pixel data.
+ /// The width of the final image.
+ /// The height of the final image.
+ /// The pixel format.
+ /// A new .
+ private static Image LoadPixelData(Configuration config, Span data, int width, int height)
+ where TPixel : struct, IPixel
+ {
+ int count = width * height;
+ Guard.MustBeGreaterThanOrEqualTo(data.Length, count, nameof(data));
+
+ var image = new Image(config, width, height);
+ SpanHelper.Copy(data, image.Frames.RootFrame.GetPixelSpan(), count);
+
+ return image;
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Image/ImageBase{TPixel}.cs b/src/ImageSharp/Image/ImageBase{TPixel}.cs
deleted file mode 100644
index e9987e0c76..0000000000
--- a/src/ImageSharp/Image/ImageBase{TPixel}.cs
+++ /dev/null
@@ -1,333 +0,0 @@
-// Copyright (c) Six Labors and contributors.
-// Licensed under the Apache License, Version 2.0.
-
-using System;
-using System.Diagnostics;
-using System.Runtime.CompilerServices;
-using SixLabors.ImageSharp.Advanced;
-using SixLabors.ImageSharp.Memory;
-using SixLabors.ImageSharp.PixelFormats;
-using SixLabors.ImageSharp.Processing;
-using SixLabors.Primitives;
-
-namespace SixLabors.ImageSharp
-{
- ///
- /// The base class of all images. Encapsulates the basic properties and methods required to manipulate
- /// images in different pixel formats.
- ///
- /// The pixel format.
- public abstract class ImageBase : IImageBase, IDisposable, IPixelSource
- where TPixel : struct, IPixel
- {
-#pragma warning disable SA1401 // Fields must be private
- ///
- /// The image pixels. Not private as Buffer2D requires an array in its constructor.
- ///
- internal TPixel[] PixelBuffer;
-#pragma warning restore SA1401 // Fields must be private
-
- ///
- /// A value indicating whether this instance of the given entity has been disposed.
- ///
- /// if this instance has been disposed; otherwise, .
- ///
- /// If the entity is disposed, it must not be disposed a second time. The isDisposed field is set the first time the entity
- /// is disposed. If the isDisposed field is true, then the Dispose() method will not dispose again. This help not to prolong the entity's
- /// life in the Garbage Collector.
- ///
- private bool isDisposed;
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The configuration providing initialization code which allows extending the library.
- ///
- protected ImageBase(Configuration configuration)
- {
- this.Configuration = configuration ?? Configuration.Default;
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The configuration providing initialization code which allows extending the library.
- ///
- /// The width of the image in pixels.
- /// The height of the image in pixels.
- ///
- /// Thrown if either or are less than or equal to 0.
- ///
- protected ImageBase(Configuration configuration, int width, int height)
- : this(configuration)
- {
- Guard.MustBeGreaterThan(width, 0, nameof(width));
- Guard.MustBeGreaterThan(height, 0, nameof(height));
-
- this.Width = width;
- this.Height = height;
- this.RentPixels();
- this.ClearPixels();
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The other to create this instance from.
- ///
- ///
- /// Thrown if the given is null.
- ///
- protected ImageBase(ImageBase other)
- : this(other.Configuration)
- {
- Guard.NotNull(other, nameof(other), "Other image cannot be null.");
-
- this.Width = other.Width;
- this.Height = other.Height;
- this.CopyProperties(other);
-
- // Rent then copy the pixels. Unsafe.CopyBlock gives us a nice speed boost here.
- this.RentPixels();
-
- other.GetPixelSpan().CopyTo(this.GetPixelSpan());
- }
-
- ///
- Span IPixelSource.Span => new Span(this.PixelBuffer, 0, this.Width * this.Height);
-
- ///
- public int Width { get; private set; }
-
- ///
- public int Height { get; private set; }
-
- ///
- /// Gets the configuration providing initialization code which allows extending the library.
- ///
- public Configuration Configuration { get; private set; }
-
- ///
- /// Gets or sets the pixel at the specified position.
- ///
- /// The x-coordinate of the pixel. Must be greater than or equal to zero and less than the width of the image.
- /// The y-coordinate of the pixel. Must be greater than or equal to zero and less than the height of the image.
- /// The at the specified position.
- public TPixel this[int x, int y]
- {
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
- {
- this.CheckCoordinates(x, y);
- return this.PixelBuffer[(y * this.Width) + x];
- }
-
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- set
- {
- this.CheckCoordinates(x, y);
- this.PixelBuffer[(y * this.Width) + x] = value;
- }
- }
-
- ///
- /// Gets a reference to the pixel at the specified position.
- ///
- /// The x-coordinate of the pixel. Must be greater than or equal to zero and less than the width of the image.
- /// The y-coordinate of the pixel. Must be greater than or equal to zero and less than the height of the image.
- /// The at the specified position.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- internal ref TPixel GetPixelReference(int x, int y)
- {
- this.CheckCoordinates(x, y);
- return ref this.PixelBuffer[(y * this.Width) + x];
- }
-
- ///
- /// Clones the image
- ///
- /// A new items which is a clone of the original.
- public ImageBase Clone()
- {
- return this.CloneImageBase();
- }
-
- ///
- public void Dispose()
- {
- this.Dispose(true);
-
- // This object will be cleaned up by the Dispose method.
- // Therefore, you should call GC.SuppressFinalize to
- // take this object off the finalization queue
- // and prevent finalization code for this object
- // from executing a second time.
- GC.SuppressFinalize(this);
- }
-
- ///
- /// Locks the image providing access to the pixels.
- ///
- /// It is imperative that the accessor is correctly disposed off after use.
- ///
- ///
- /// The
- internal PixelAccessor Lock()
- {
- return new PixelAccessor(this);
- }
-
- ///
- /// Copies the pixels to another of the same size.
- ///
- /// The target pixel buffer accessor.
- internal void CopyTo(PixelAccessor target)
- {
- SpanHelper.Copy(this.GetPixelSpan(), target.PixelBuffer.Span);
- }
-
- ///
- /// Switches the buffers used by the image and the PixelAccessor meaning that the Image will "own" the buffer from the PixelAccessor and the PixelAccessor will now own the Images buffer.
- ///
- /// The pixel source.
- internal void SwapPixelsBuffers(PixelAccessor pixelSource)
- {
- Guard.NotNull(pixelSource, nameof(pixelSource));
-
- int newWidth = pixelSource.Width;
- int newHeight = pixelSource.Height;
-
- // Push my memory into the accessor (which in turn unpins the old buffer ready for the images use)
- TPixel[] newPixels = pixelSource.ReturnCurrentColorsAndReplaceThemInternally(this.Width, this.Height, this.PixelBuffer);
- this.Width = newWidth;
- this.Height = newHeight;
- this.PixelBuffer = newPixels;
- }
-
- ///
- /// Switches the buffers used by the image and the pixelSource meaning that the Image will "own" the buffer from the pixelSource and the pixelSource will now own the Images buffer.
- ///
- /// The pixel source.
- internal void SwapPixelsData(ImageBase pixelSource)
- {
- Guard.NotNull(pixelSource, nameof(pixelSource));
-
- int newWidth = pixelSource.Width;
- int newHeight = pixelSource.Height;
- TPixel[] newPixels = pixelSource.PixelBuffer;
-
- pixelSource.PixelBuffer = this.PixelBuffer;
- pixelSource.Width = this.Width;
- pixelSource.Height = this.Height;
-
- this.Width = newWidth;
- this.Height = newHeight;
- this.PixelBuffer = newPixels;
- }
-
- ///
- /// Clones the image
- ///
- /// A new items which is a clone of the original.
- protected abstract ImageBase CloneImageBase();
-
- ///
- /// Copies the properties from the other .
- ///
- ///
- /// The other to copy the properties from.
- ///
- protected void CopyProperties(IImageBase other)
- {
- DebugGuard.NotNull(other, nameof(other));
-
- this.Configuration = other.Configuration;
- }
-
- ///
- /// Disposes the object and frees resources for the Garbage Collector.
- ///
- /// If true, the object gets disposed.
- protected virtual void Dispose(bool disposing)
- {
- if (this.isDisposed)
- {
- return;
- }
-
- if (disposing)
- {
- this.ReturnPixels();
- }
-
- // Note disposing is done.
- this.isDisposed = true;
- }
-
- ///
- /// Rents the pixel array from the pool.
- ///
- private void RentPixels()
- {
- this.PixelBuffer = PixelDataPool.Rent(this.Width * this.Height);
- }
-
- ///
- /// Returns the rented pixel array back to the pool.
- ///
- private void ReturnPixels()
- {
- PixelDataPool.Return(this.PixelBuffer);
- this.PixelBuffer = null;
- }
-
- ///
- /// Clears the pixel array.
- ///
- private void ClearPixels()
- {
- Array.Clear(this.PixelBuffer, 0, this.Width * this.Height);
- }
-
- ///
- /// Checks the coordinates to ensure they are within bounds.
- ///
- /// The y-coordinate of the pixel. Must be greater than zero and less than the height of the image.
- ///
- /// Thrown if the coordinates are not within the bounds of the image.
- ///
- [Conditional("DEBUG")]
- private void CheckCoordinates(int y)
- {
- if (y < 0 || y >= this.Height)
- {
- throw new ArgumentOutOfRangeException(nameof(y), y, $"{y} is outwith the image bounds.");
- }
- }
-
- ///
- /// Checks the coordinates to ensure they are within bounds.
- ///
- /// The x-coordinate of the pixel. Must be greater than zero and less than the width of the image.
- /// The y-coordinate of the pixel. Must be greater than zero and less than the height of the image.
- ///
- /// Thrown if the coordinates are not within the bounds of the image.
- ///
- [Conditional("DEBUG")]
- private void CheckCoordinates(int x, int y)
- {
- if (x < 0 || x >= this.Width)
- {
- throw new ArgumentOutOfRangeException(nameof(x), x, $"{x} is outwith the image bounds.");
- }
-
- if (y < 0 || y >= this.Height)
- {
- throw new ArgumentOutOfRangeException(nameof(y), y, $"{y} is outwith the image bounds.");
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/ImageSharp/Image/ImageExtensions.cs b/src/ImageSharp/Image/ImageExtensions.cs
index 6844bdc813..c5b3d6f31a 100644
--- a/src/ImageSharp/Image/ImageExtensions.cs
+++ b/src/ImageSharp/Image/ImageExtensions.cs
@@ -18,26 +18,6 @@ namespace SixLabors.ImageSharp
///
public static partial class ImageExtensions
{
- ///
- /// Gets the bounds of the image.
- ///
- /// The Pixel format.
- /// The source image
- /// Returns the bounds of the image
- public static Rectangle Bounds(this ImageBase source)
- where TPixel : struct, IPixel
- => new Rectangle(0, 0, source.Width, source.Height);
-
- ///
- /// Gets the size of the image.
- ///
- /// The Pixel format.
- /// The source image
- /// Returns the bounds of the image
- public static Size Size(this ImageBase source)
- where TPixel : struct, IPixel
- => new Size(source.Width, source.Height);
-
#if !NETSTANDARD1_1
///
/// Saves the image to the given stream using the currently loaded image format.
@@ -52,12 +32,12 @@ namespace SixLabors.ImageSharp
Guard.NotNullOrEmpty(filePath, nameof(filePath));
string ext = Path.GetExtension(filePath).Trim('.');
- IImageFormat format = source.Configuration.FindFormatByFileExtension(ext);
+ IImageFormat format = source.GetConfiguration().FindFormatByFileExtension(ext);
if (format == null)
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"Can't find a format that is associated with the file extention '{ext}'. Registered formats with there extensions include:");
- foreach (IImageFormat fmt in source.Configuration.ImageFormats)
+ foreach (IImageFormat fmt in source.GetConfiguration().ImageFormats)
{
stringBuilder.AppendLine($" - {fmt.Name} : {string.Join(", ", fmt.FileExtensions)}");
}
@@ -65,13 +45,13 @@ namespace SixLabors.ImageSharp
throw new NotSupportedException(stringBuilder.ToString());
}
- IImageEncoder encoder = source.Configuration.FindEncoder(format);
+ IImageEncoder encoder = source.GetConfiguration().FindEncoder(format);
if (encoder == null)
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine($"Can't find encoder for file extention '{ext}' using image format '{format.Name}'. Registered encoders include:");
- foreach (KeyValuePair enc in source.Configuration.ImageEncoders)
+ foreach (KeyValuePair enc in source.GetConfiguration().ImageEncoders)
{
stringBuilder.AppendLine($" - {enc.Key} : {enc.Value.GetType().Name}");
}
@@ -94,7 +74,7 @@ namespace SixLabors.ImageSharp
where TPixel : struct, IPixel
{
Guard.NotNull(encoder, nameof(encoder));
- using (Stream fs = source.Configuration.FileSystem.Create(filePath))
+ using (Stream fs = source.GetConfiguration().FileSystem.Create(filePath))
{
source.Save(fs, encoder);
}
@@ -113,14 +93,14 @@ namespace SixLabors.ImageSharp
where TPixel : struct, IPixel
{
Guard.NotNull(format, nameof(format));
- IImageEncoder encoder = source.Configuration.FindEncoder(format);
+ IImageEncoder encoder = source.GetConfiguration().FindEncoder(format);
if (encoder == null)
{
var stringBuilder = new StringBuilder();
stringBuilder.AppendLine("Can't find encoder for provided mime type. Available encoded:");
- foreach (KeyValuePair val in source.Configuration.ImageEncoders)
+ foreach (KeyValuePair val in source.GetConfiguration().ImageEncoders)
{
stringBuilder.AppendLine($" - {val.Key.Name} : {val.Value.GetType().Name}");
}
@@ -131,6 +111,17 @@ namespace SixLabors.ImageSharp
source.Save(stream, encoder);
}
+ ///
+ /// Saves the raw image to the given bytes.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// A copy of the pixel data as bytes from this frame.
+ /// Thrown if the stream is null.
+ public static byte[] SavePixelData(this ImageFrame source)
+ where TPixel : struct, IPixel
+ => source.GetPixelSpan().AsBytes().ToArray();
+
///
/// Saves the raw image to the given bytes.
///
@@ -138,7 +129,18 @@ namespace SixLabors.ImageSharp
/// The source image
/// The buffer to save the raw pixel data to.
/// Thrown if the stream is null.
- public static void SavePixelData(this Image source, Span buffer)
+ public static void SavePixelData(this ImageFrame source, byte[] buffer)
+ where TPixel : struct, IPixel
+ => SavePixelData(source, new Span(buffer));
+
+ ///
+ /// Saves the raw image to the given bytes.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// The buffer to save the raw pixel data to.
+ /// Thrown if the stream is null.
+ private static void SavePixelData(this ImageFrame source, Span buffer)
where TPixel : struct, IPixel
{
Span byteBuffer = source.GetPixelSpan().AsBytes();
@@ -147,6 +149,39 @@ namespace SixLabors.ImageSharp
byteBuffer.CopyTo(buffer);
}
+ ///
+ /// Saves the raw image to the given bytes.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// A copy of the pixel data from the first frame as bytes.
+ /// Thrown if the stream is null.
+ public static byte[] SavePixelData(this Image source)
+ where TPixel : struct, IPixel
+ => source.Frames.RootFrame.SavePixelData();
+
+ ///
+ /// Saves the raw image to the given bytes.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// The buffer to save the raw pixel data to.
+ /// Thrown if the stream is null.
+ public static void SavePixelData(this Image source, byte[] buffer)
+ where TPixel : struct, IPixel
+ => source.Frames.RootFrame.SavePixelData(buffer);
+
+ ///
+ /// Saves the raw image to the given bytes.
+ ///
+ /// The Pixel format.
+ /// The source image
+ /// The buffer to save the raw pixel data to.
+ /// Thrown if the stream is null.
+ private static void SavePixelData(this Image source, Span buffer)
+ where TPixel : struct, IPixel