diff --git a/ImageSharp.v3.ncrunchsolution b/ImageSharp.v3.ncrunchsolution
new file mode 100644
index 000000000..10420ac91
--- /dev/null
+++ b/ImageSharp.v3.ncrunchsolution
@@ -0,0 +1,6 @@
+
+
+ True
+ True
+
+
\ 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 4cd3585ec..2d29e23fe 100644
--- a/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs
+++ b/src/ImageSharp.Drawing/Brushes/ImageBrush{TPixel}.cs
@@ -32,6 +32,15 @@ namespace SixLabors.ImageSharp.Drawing.Brushes
this.image = image;
}
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The image.
+ public ImageBrush(Image image)
+ : this(image.Frames.RootFrame)
+ {
+ }
+
///
public BrushApplicator CreateApplicator(ImageFrame source, RectangleF region, GraphicsOptions options)
{
diff --git a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs
index 511e66c64..0acb846c5 100644
--- a/src/ImageSharp/Advanced/AdvancedImageExtensions.cs
+++ b/src/ImageSharp/Advanced/AdvancedImageExtensions.cs
@@ -12,6 +12,16 @@ namespace SixLabors.ImageSharp.Advanced
///
public static class AdvancedImageExtensions
{
+ ///
+ /// 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);
+
///
/// Returns a reference to the 0th element of the Pixel buffer,
/// allowing direct manipulation of pixel data through unsafe operations.
@@ -78,16 +88,6 @@ namespace SixLabors.ImageSharp.Advanced
where TPixel : struct, IPixel
=> source.Frames.RootFrame.GetPixelRowSpan(row);
- ///
- /// Gets the configuration for the image.
- ///
- /// The Pixel format.
- /// The source image
- /// Returns the configuration.
- internal static Configuration GetConfiguration(this Image source)
- where TPixel : struct, IPixel
- => GetConfiguration((IConfigurable)source);
-
///
/// Gets the span to the backing buffer.
///
diff --git a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
index c3c395e85..e4c7d93a0 100644
--- a/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
+++ b/src/ImageSharp/Formats/Gif/GifDecoderCore.cs
@@ -388,15 +388,13 @@ namespace SixLabors.ImageSharp.Formats.Gif
previousFrame = this.previousFrame;
}
- currentFrame = this.previousFrame.Clone();
+ currentFrame = this.image.Frames.AddFrame(this.previousFrame); // this clones the frame and adds it the collection
this.SetFrameMetaData(currentFrame.MetaData);
image = currentFrame;
this.RestoreToBackground(image);
-
- this.image.Frames.Add(currentFrame);
}
int i = 0;
diff --git a/src/ImageSharp/Image/IImageFrameCollection.cs b/src/ImageSharp/Image/IImageFrameCollection.cs
index ee325bc63..81b512e22 100644
--- a/src/ImageSharp/Image/IImageFrameCollection.cs
+++ b/src/ImageSharp/Image/IImageFrameCollection.cs
@@ -27,42 +27,82 @@ namespace SixLabors.ImageSharp
ImageFrame RootFrame { get; }
///
- /// Gets or sets the at the specified index.
+ /// Gets the at the specified index.
///
///
/// The .
///
/// The index.
/// The at the specified index.
- ImageFrame this[int index] { get; set; }
+ ImageFrame this[int index] { get; }
///
- /// Determines the index of a specific in the .
+ /// Clones the the frame at and generates a new images with all the same metadata from the orgional but with only the single frame on it.
///
- /// The to locate in the .
- /// The index of item if found in the list; otherwise, -1.
- int IndexOf(ImageFrame frame);
+ /// The zero-based index at which item should be removed.
+ /// Cannot remove last frame.
+ /// The new with only the one frame on it.
+ Image CloneFrame(int index);
///
- /// Inserts the to the at the specified .
+ /// Removed the frame at and generates a new images with all the same metadata from the orgional but with only the single frame on it.
///
- /// The zero-based index at which item should be inserted..
- /// The to insert into the .
- void Insert(int index, ImageFrame frame);
+ /// The zero-based index at which item should be removed.
+ /// Cannot remove last frame.
+ /// The new with only the one frame on it.
+ Image ExportFrame(int index);
///
- /// Removes the from the at the specified index.
+ /// Remove the frame at and frees all freeable resources associated with it.
///
- /// The zero-based index of the item to remove.
+ /// The zero-based index at which item should be removed.
/// Cannot remove last frame.
- void RemoveAt(int index);
+ void RemoveFrame(int index);
///
- /// Adds the specified frame.
+ /// Creates a new and appends it appends it to the end of the collection.
///
- /// The frame.
+ /// The new .
+ ImageFrame CreateFrame();
+
+ ///
+ /// Clones the frame and appends the clone to the end of the collection.
+ ///
+ /// The raw pixel data to generate from.
+ /// The cloned .
+ ImageFrame AddFrame(ImageFrame source);
+
+ ///
+ /// Creates a new frame from the pixel data at the same dimensions at the current image and inserts the new frame
+ /// into the at the end of the collection.
+ ///
+ /// The raw pixel data to generate from.
+ /// The new .
+ ImageFrame AddFrame(TPixel[] source);
+
+ ///
+ /// Clones and inserts the into the at the specified .
+ ///
+ /// The zero-based index at which item should be inserted.
+ /// The to clone and insert into the .
/// Frame must have the same dimensions as the image - frame
- void Add(ImageFrame frame);
+ /// The cloned .
+ ImageFrame InsertFrame(int index, ImageFrame source);
+
+ ///
+ /// Moves a from the at the specified index to the other index.
+ ///
+ /// The zero-based index of the item to move.
+ /// The zero-based index of the new index that should be inserted at.
+ /// Cannot remove last frame.
+ void MoveFrame(int sourceIndex, int destinationIndex);
+
+ ///
+ /// 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);
///
/// Determines whether the contains the .
@@ -72,13 +112,5 @@ namespace SixLabors.ImageSharp
/// 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/ImageFrame.LoadPixelData.cs b/src/ImageSharp/Image/ImageFrame.LoadPixelData.cs
index aecd9bba9..e2230c436 100644
--- a/src/ImageSharp/Image/ImageFrame.LoadPixelData.cs
+++ b/src/ImageSharp/Image/ImageFrame.LoadPixelData.cs
@@ -15,7 +15,7 @@ namespace SixLabors.ImageSharp
///
/// Adds static methods allowing the creation of new image from raw pixel data.
///
- public static partial class ImageFrame
+ internal static partial class ImageFrame
{
///
/// Create a new instance of the class from the given byte array in format.
diff --git a/src/ImageSharp/Image/ImageFrameCollection.cs b/src/ImageSharp/Image/ImageFrameCollection.cs
index 25c0d0c44..b29fdc511 100644
--- a/src/ImageSharp/Image/ImageFrameCollection.cs
+++ b/src/ImageSharp/Image/ImageFrameCollection.cs
@@ -4,7 +4,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
-
+using SixLabors.ImageSharp.Advanced;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
@@ -13,124 +13,134 @@ namespace SixLabors.ImageSharp
/// Encapsulates an imaged collection of frames.
///
/// The type of the pixel.
- internal sealed class ImageFrameCollection : IImageFrameCollection, IDisposable
+ internal sealed class ImageFrameCollection : IImageFrameCollection
where TPixel : struct, IPixel
{
private readonly IList> frames = new List>();
+ private readonly Image parent;
- internal ImageFrameCollection(int width, int height)
+ internal ImageFrameCollection(Image parent, int width, int height)
{
- this.Add(new ImageFrame(width, height));
+ Guard.NotNull(parent, nameof(parent));
+
+ this.parent = parent;
+ this.AddFrame(new ImageFrame(width, height));
}
- internal ImageFrameCollection(IEnumerable> frames)
+ internal ImageFrameCollection(Image parent, IEnumerable> frames)
{
+ Guard.NotNull(parent, nameof(parent));
Guard.NotNullOrEmpty(frames, nameof(frames));
+
+ this.parent = parent;
foreach (ImageFrame f in frames)
{
- this.Add(f);
+ this.AddFrame(f);
}
}
- ///
- /// Gets the count.
- ///
+ ///
public int Count => this.frames.Count;
- ///
- /// Gets the root frame.
- ///
+ ///
public ImageFrame RootFrame => this.frames.Count > 0 ? this.frames[0] : null;
- ///
- /// Gets or sets the at the specified index.
- ///
- ///
- /// The .
- ///
- /// The index.
- /// The at the specified index.
+ ///
public ImageFrame this[int index]
{
get => this.frames[index];
-
- set
- {
- this.ValidateFrame(value);
- this.frames[index] = value;
- }
}
- ///
- /// Determines the index of a specific in the .
- ///
- /// The to locate in the .
- /// The index of item if found in the list; otherwise, -1.
+ ///
public int IndexOf(ImageFrame frame) => this.frames.IndexOf(frame);
- ///
- /// Inserts the to the at the specified .
- ///
- /// The zero-based index at which item should be inserted..
- /// The to insert into the .
- public void Insert(int index, ImageFrame frame)
+ ///
+ public ImageFrame InsertFrame(int index, ImageFrame frame)
{
this.ValidateFrame(frame);
- this.frames.Insert(index, frame);
+ ImageFrame clonedFrame = frame.Clone();
+ this.frames.Insert(index, clonedFrame);
+ return clonedFrame;
}
- ///
- /// Removes the from the at the specified index.
- ///
- /// The zero-based index of the item to remove.
- /// Cannot remove last frame.
- public void RemoveAt(int index)
+ ///
+ public ImageFrame AddFrame(ImageFrame frame)
+ {
+ this.ValidateFrame(frame);
+ ImageFrame clonedFrame = frame.Clone();
+ this.frames.Add(clonedFrame);
+ return clonedFrame;
+ }
+
+ ///
+ public ImageFrame AddFrame(TPixel[] data)
+ {
+ var frame = ImageFrame.LoadPixelData(new Span(data), this.RootFrame.Width, this.RootFrame.Height);
+ this.frames.Add(frame);
+ return frame;
+ }
+
+ ///
+ public void RemoveFrame(int index)
{
if (index == 0 && this.Count == 1)
{
throw new InvalidOperationException("Cannot remove last frame.");
}
+ ImageFrame frame = this.frames[index];
this.frames.RemoveAt(index);
+ frame.Dispose();
}
- ///
- /// Adds the specified frame.
- ///
- /// The frame.
- /// Frame must have the same dimensions as the image - frame
- public void Add(ImageFrame frame)
+ ///
+ public bool Contains(ImageFrame frame)
{
- this.ValidateFrame(frame);
- this.frames.Add(frame);
+ return this.frames.Contains(frame);
}
- ///
- /// Determines whether the contains the .
- ///
- /// The frame.
- ///
- /// true if the the specified frame; otherwise, false.
- ///
- public bool Contains(ImageFrame frame)
+ ///
+ public void MoveFrame(int sourceIndex, int destIndex)
{
- return this.frames.Contains(frame);
+ if (sourceIndex == destIndex)
+ {
+ return;
+ }
+
+ ImageFrame frameAtIndex = this.frames[sourceIndex];
+ this.frames.RemoveAt(sourceIndex);
+ this.frames.Insert(destIndex, frameAtIndex);
}
- ///
- /// Removes the specified frame.
- ///
- /// The frame.
- /// true if item is found in the ; otherwise,
- /// Cannot remove last frame
- public bool Remove(ImageFrame frame)
+ ///
+ public Image ExportFrame(int index)
{
+ ImageFrame frame = this[index];
+
if (this.Count == 1 && this.frames.Contains(frame))
{
throw new InvalidOperationException("Cannot remove last frame.");
}
- return this.frames.Remove(frame);
+ this.frames.Remove(frame);
+
+ return new Image(this.parent.GetConfiguration(), this.parent.MetaData.Clone(), new[] { frame });
+ }
+
+ ///
+ public Image CloneFrame(int index)
+ {
+ ImageFrame frame = this[index];
+ ImageFrame clonedFrame = frame.Clone();
+ return new Image(this.parent.GetConfiguration(), this.parent.MetaData.Clone(), new[] { clonedFrame });
+ }
+
+ ///
+ public ImageFrame CreateFrame()
+ {
+ var frame = new ImageFrame(this.RootFrame.Width, this.RootFrame.Height);
+ this.frames.Add(frame);
+ return frame;
}
///
@@ -152,8 +162,7 @@ namespace SixLabors.ImageSharp
}
}
- ///
- public void Dispose()
+ internal void Dispose()
{
foreach (ImageFrame f in this.frames)
{
diff --git a/src/ImageSharp/Image/ImageFrame{TPixel}.cs b/src/ImageSharp/Image/ImageFrame{TPixel}.cs
index 73e3a80ae..45ed5f053 100644
--- a/src/ImageSharp/Image/ImageFrame{TPixel}.cs
+++ b/src/ImageSharp/Image/ImageFrame{TPixel}.cs
@@ -103,15 +103,6 @@ namespace SixLabors.ImageSharp
}
}
- ///
- /// Performs an explicit conversion from to .
- ///
- /// The image.
- ///
- /// The result of the conversion.
- ///
- public static implicit operator ImageFrame(Image image) => image.Frames[0];
-
///
/// Gets a reference to the pixel at the specified position.
///
@@ -172,7 +163,7 @@ namespace SixLabors.ImageSharp
///
/// Disposes the object and frees resources for the Garbage Collector.
///
- public void Dispose()
+ internal void Dispose()
{
if (this.isDisposed)
{
@@ -197,7 +188,7 @@ namespace SixLabors.ImageSharp
///
/// The pixel format.
/// The
- public ImageFrame CloneAs()
+ internal ImageFrame CloneAs()
where TPixel2 : struct, IPixel
{
if (typeof(TPixel2) == typeof(TPixel))
@@ -234,9 +225,15 @@ namespace SixLabors.ImageSharp
/// Clones the current instance.
///
/// The
- public ImageFrame Clone()
+ internal ImageFrame Clone()
{
return new ImageFrame(this);
}
+
+ ///
+ void IDisposable.Dispose()
+ {
+ this.Dispose();
+ }
}
}
\ No newline at end of file
diff --git a/src/ImageSharp/Image/Image{TPixel}.cs b/src/ImageSharp/Image/Image{TPixel}.cs
index e92255c20..85e1aa858 100644
--- a/src/ImageSharp/Image/Image{TPixel}.cs
+++ b/src/ImageSharp/Image/Image{TPixel}.cs
@@ -62,7 +62,7 @@ namespace SixLabors.ImageSharp
{
this.configuration = configuration ?? Configuration.Default;
this.MetaData = metadata ?? new ImageMetaData();
- this.frames = new ImageFrameCollection(width, height);
+ this.frames = new ImageFrameCollection(this, width, height);
}
///
@@ -77,7 +77,7 @@ namespace SixLabors.ImageSharp
this.configuration = configuration ?? Configuration.Default;
this.MetaData = metadata ?? new ImageMetaData();
- this.frames = new ImageFrameCollection(frames);
+ this.frames = new ImageFrameCollection(this, frames);
}
///
@@ -148,30 +148,6 @@ namespace SixLabors.ImageSharp
return new Image(this.configuration, this.MetaData.Clone(), frames);
}
- ///
- /// Clones the current image
- ///
- /// The index of the frame to clone into the new image
- /// Returns a new image with all the same metadata as the original but only the single frame.
- public Image Clone(int frameIndex)
- {
- ImageFrame frame = this.frames[frameIndex];
- ImageFrame clonedFrame = frame.Clone();
- return new Image(this.configuration, this.MetaData.Clone(), new[] { clonedFrame });
- }
-
- ///
- /// Extracts a frame from the current image
- ///
- /// The index of the frame to cloen into the new image
- /// Returns a new image with all the same metadata as the original but only the single frame.
- public Image Extract(int frameIndex)
- {
- ImageFrame frame = this.frames[frameIndex];
- this.frames.Remove(frame); // try and remove frame from the current image
- return new Image(this.configuration, this.MetaData.Clone(), new[] { frame });
- }
-
///
public override string ToString()
{
@@ -192,22 +168,6 @@ namespace SixLabors.ImageSharp
return target;
}
- ///
- /// Returns a copy of the image in the given pixel format.
- ///
- /// The pixel format.
- /// The index of the frame to clone into the new image
- /// Returns a new with all the same metadata as the original but only the single frame.
- public Image CloneAs(int frameIndex)
- where TPixel2 : struct, IPixel
- {
- ImageFrame frame = this.frames[frameIndex];
- ImageFrame clonedFrame = frame.CloneAs();
- var target = new Image(this.configuration, this.MetaData, new[] { clonedFrame });
-
- return target;
- }
-
///
/// Releases managed resources.
///
diff --git a/src/ImageSharp/ImageSharp.csproj b/src/ImageSharp/ImageSharp.csproj
index 480d2d4d8..45d0a70b8 100644
--- a/src/ImageSharp/ImageSharp.csproj
+++ b/src/ImageSharp/ImageSharp.csproj
@@ -5,7 +5,7 @@
$(packageversion)
0.0.1
Six Labors and contributors
- netstandard1.3;netstandard1.1
+ netstandard1.1;netstandard1.3
true
true
SixLabors.ImageSharp
diff --git a/src/ImageSharp/ImageSharp.netstandard1.1.v3.ncrunchproject b/src/ImageSharp/ImageSharp.netstandard1.1.v3.ncrunchproject
new file mode 100644
index 000000000..319cd523c
--- /dev/null
+++ b/src/ImageSharp/ImageSharp.netstandard1.1.v3.ncrunchproject
@@ -0,0 +1,5 @@
+
+
+ True
+
+
\ No newline at end of file
diff --git a/src/ImageSharp/Processing/Transforms/Resize.cs b/src/ImageSharp/Processing/Transforms/Resize.cs
index 826741d94..7897e8f30 100644
--- a/src/ImageSharp/Processing/Transforms/Resize.cs
+++ b/src/ImageSharp/Processing/Transforms/Resize.cs
@@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp
options.Size = new Size(options.Size.Width, (int)MathF.Round(img.Height * options.Size.Width / (float)img.Width));
}
- Rectangle targetRectangle = ResizeHelper.CalculateTargetLocationAndBounds(img, options);
+ Rectangle targetRectangle = ResizeHelper.CalculateTargetLocationAndBounds(img.Frames.RootFrame, options);
img.Mutate(x => Resize(x, options.Size.Width, options.Size.Height, options.Sampler, targetRectangle, options.Compand));
});
diff --git a/src/ImageSharp/Quantizers/Quantize.cs b/src/ImageSharp/Quantizers/Quantize.cs
index 049090f43..d99d4af34 100644
--- a/src/ImageSharp/Quantizers/Quantize.cs
+++ b/src/ImageSharp/Quantizers/Quantize.cs
@@ -58,7 +58,7 @@ namespace SixLabors.ImageSharp
return source.Apply(img =>
{
// TODO : move helper logic into the processor
- QuantizedImage quantized = quantizer.Quantize(img, maxColors);
+ QuantizedImage quantized = quantizer.Quantize(img.Frames.RootFrame, maxColors);
int palleteCount = quantized.Palette.Length - 1;
using (var pixels = new PixelAccessor(quantized.Width, quantized.Height))
diff --git a/tests/ImageSharp.Tests/Image/ImageFramesCollectionTests.cs b/tests/ImageSharp.Tests/Image/ImageFramesCollectionTests.cs
index e19d7ddef..afae9cae8 100644
--- a/tests/ImageSharp.Tests/Image/ImageFramesCollectionTests.cs
+++ b/tests/ImageSharp.Tests/Image/ImageFramesCollectionTests.cs
@@ -3,92 +3,94 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using SixLabors.ImageSharp.Advanced;
+using SixLabors.ImageSharp.PixelFormats;
using Xunit;
namespace SixLabors.ImageSharp.Tests
{
- public class ImageFramesCollectionTests
+ public class ImageFramesCollectionTests : IDisposable
{
+ private Image image;
+ private ImageFrameCollection collection;
+
+ public ImageFramesCollectionTests()
+ {
+ this.image = new Image(10, 10);
+ this.collection = new ImageFrameCollection(this.image, 10, 10);
+ }
+
[Fact]
public void ImageFramesaLwaysHaveOneFrame()
{
- var collection = new ImageFrameCollection(10, 10);
- Assert.Equal(1, collection.Count);
+ Assert.Equal(1, this.collection.Count);
}
[Fact]
public void AddNewFrame_FramesMustHaveSameSize()
{
- var collection = new ImageFrameCollection(10, 10);
-
ArgumentException ex = Assert.Throws(() =>
{
- collection.Add(new ImageFrame(1, 1));
+ this.collection.AddFrame(new ImageFrame(1, 1));
});
Assert.StartsWith("Frame must have the same dimensions as the image.", ex.Message);
}
[Fact]
- public void AddNewFrame_FramesNotBeNull()
+ public void AddNewFrame_Frame_FramesNotBeNull()
{
- var collection = new ImageFrameCollection(10, 10);
ArgumentNullException ex = Assert.Throws(() =>
{
- collection.Add(null);
+ this.collection.AddFrame((ImageFrame)null);
});
Assert.StartsWith("Value cannot be null.", ex.Message);
}
[Fact]
- public void InsertNewFrame_FramesMustHaveSameSize()
+ public void AddNewFrame_PixelBuffer_FramesNotBeNull()
{
- var collection = new ImageFrameCollection(10, 10);
- ArgumentException ex = Assert.Throws(() =>
+ ArgumentNullException ex = Assert.Throws(() =>
{
- collection.Insert(1, new ImageFrame(1, 1));
+ this.collection.AddFrame((Rgba32[])null);
});
- Assert.StartsWith("Frame must have the same dimensions as the image.", ex.Message);
+ Assert.StartsWith("Value cannot be null.", ex.Message);
}
[Fact]
- public void InsertNewFrame_FramesNotBeNull()
+ public void AddNewFrame_PixelBuffer_BufferIncorrectSize()
{
- var collection = new ImageFrameCollection(10, 10);
- ArgumentNullException ex = Assert.Throws(() =>
+ ArgumentOutOfRangeException ex = Assert.Throws(() =>
{
- collection.Insert(1, null);
+ this.collection.AddFrame(new Rgba32[0]);
});
- Assert.StartsWith("Value cannot be null.", ex.Message);
+ Assert.StartsWith("Value must be greater than or equal to 100.", ex.Message);
}
[Fact]
- public void SetFrameAtIndex_FramesMustHaveSameSize()
+ public void InsertNewFrame_FramesMustHaveSameSize()
{
- var collection = new ImageFrameCollection(10, 10);
ArgumentException ex = Assert.Throws(() =>
{
- collection[0] = new ImageFrame(1, 1);
+ this.collection.InsertFrame(1, new ImageFrame(1, 1));
});
Assert.StartsWith("Frame must have the same dimensions as the image.", ex.Message);
}
[Fact]
- public void SetFrameAtIndex_FramesNotBeNull()
+ public void InsertNewFrame_FramesNotBeNull()
{
- var collection = new ImageFrameCollection(10, 10);
ArgumentNullException ex = Assert.Throws(() =>
{
- collection[0] = null;
+ this.collection.InsertFrame(1, null);
});
Assert.StartsWith("Value cannot be null.", ex.Message);
@@ -100,7 +102,7 @@ namespace SixLabors.ImageSharp.Tests
ArgumentException ex = Assert.Throws(() =>
{
- var collection = new ImageFrameCollection(new[] {
+ var collection = new ImageFrameCollection(this.image, new[] {
new ImageFrame(10,10),
new ImageFrame(1,1),
});
@@ -112,13 +114,13 @@ namespace SixLabors.ImageSharp.Tests
[Fact]
public void RemoveAtFrame_ThrowIfRemovingLastFrame()
{
- var collection = new ImageFrameCollection(new[] {
+ var collection = new ImageFrameCollection(this.image, new[] {
new ImageFrame(10,10)
});
InvalidOperationException ex = Assert.Throws(() =>
{
- collection.RemoveAt(0);
+ collection.RemoveFrame(0);
});
Assert.Equal("Cannot remove last frame.", ex.Message);
}
@@ -127,46 +129,19 @@ namespace SixLabors.ImageSharp.Tests
public void RemoveAtFrame_CanRemoveFrameZeroIfMultipleFramesExist()
{
- var collection = new ImageFrameCollection(new[] {
+ var collection = new ImageFrameCollection(this.image, new[] {
new ImageFrame(10,10),
new ImageFrame(10,10),
});
- collection.RemoveAt(0);
- Assert.Equal(1, collection.Count);
- }
-
- [Fact]
- public void RemoveFrame_ThrowIfRemovingLastFrame()
- {
- var collection = new ImageFrameCollection(new[] {
- new ImageFrame(10,10)
- });
-
- InvalidOperationException ex = Assert.Throws(() =>
- {
- collection.Remove(collection[0]);
- });
- Assert.Equal("Cannot remove last frame.", ex.Message);
- }
-
- [Fact]
- public void RemoveFrame_CanRemoveFrameZeroIfMultipleFramesExist()
- {
-
- var collection = new ImageFrameCollection(new[] {
- new ImageFrame(10,10),
- new ImageFrame(10,10),
- });
-
- collection.Remove(collection[0]);
+ collection.RemoveFrame(0);
Assert.Equal(1, collection.Count);
}
[Fact]
public void RootFrameIsFrameAtIndexZero()
{
- var collection = new ImageFrameCollection(new[] {
+ var collection = new ImageFrameCollection(this.image, new[] {
new ImageFrame(10,10),
new ImageFrame(10,10),
});
@@ -177,7 +152,7 @@ namespace SixLabors.ImageSharp.Tests
[Fact]
public void ConstructorPopulatesFrames()
{
- var collection = new ImageFrameCollection(new[] {
+ var collection = new ImageFrameCollection(this.image, new[] {
new ImageFrame(10,10),
new ImageFrame(10,10),
});
@@ -188,7 +163,7 @@ namespace SixLabors.ImageSharp.Tests
[Fact]
public void DisposeClearsCollection()
{
- var collection = new ImageFrameCollection(new[] {
+ var collection = new ImageFrameCollection(this.image, new[] {
new ImageFrame(10,10),
new ImageFrame(10,10),
});
@@ -201,7 +176,7 @@ namespace SixLabors.ImageSharp.Tests
[Fact]
public void Dispose_DisposesAllInnerFrames()
{
- var collection = new ImageFrameCollection(new[] {
+ var collection = new ImageFrameCollection(this.image, new[] {
new ImageFrame(10,10),
new ImageFrame(10,10),
});
@@ -215,5 +190,132 @@ namespace SixLabors.ImageSharp.Tests
Assert.Null(f.PixelBuffer);
});
}
+
+ [Theory]
+ [WithTestPatternImages(10, 10, PixelTypes.Rgba32)]
+ public void CloneFrame(TestImageProvider provider)
+ where TPixel : struct, IPixel
+ {
+ using (Image img = provider.GetImage())
+ {
+ img.Frames.AddFrame(new ImageFrame(10, 10));// add a frame anyway
+ using (Image cloned = img.Frames.CloneFrame(0))
+ {
+ Assert.Equal(2, img.Frames.Count);
+ cloned.ComparePixelBufferTo(img.GetPixelSpan());
+ }
+ }
+ }
+
+ [Theory]
+ [WithTestPatternImages(10, 10, PixelTypes.Rgba32)]
+ public void ExtractFrame(TestImageProvider provider)
+ where TPixel : struct, IPixel
+ {
+ using (Image img = provider.GetImage())
+ {
+ var sourcePixelData = img.GetPixelSpan().ToArray();
+
+ img.Frames.AddFrame(new ImageFrame(10, 10));
+ using (Image cloned = img.Frames.ExportFrame(0))
+ {
+ Assert.Equal(1, img.Frames.Count);
+ cloned.ComparePixelBufferTo(sourcePixelData);
+ }
+ }
+ }
+
+ [Fact]
+ public void CreateFrame()
+ {
+ this.image.Frames.CreateFrame();
+ Assert.Equal(2, this.image.Frames.Count);
+ }
+
+ [Fact]
+ public void AddFrameFromPixelData()
+ {
+ var pixelData = this.image.Frames.RootFrame.GetPixelSpan().ToArray();
+ this.image.Frames.AddFrame(pixelData);
+ Assert.Equal(2, this.image.Frames.Count);
+ }
+
+ [Fact]
+ public void AddFrame_clones_sourceFrame()
+ {
+ var pixelData = this.image.Frames.RootFrame.GetPixelSpan().ToArray();
+ var otherFRame = new ImageFrame(10, 10);
+ var addedFrame = this.image.Frames.AddFrame(otherFRame);
+ addedFrame.ComparePixelBufferTo(otherFRame.GetPixelSpan());
+ Assert.NotEqual(otherFRame, addedFrame);
+ }
+
+ [Fact]
+ public void InsertFrame_clones_sourceFrame()
+ {
+ var pixelData = this.image.Frames.RootFrame.GetPixelSpan().ToArray();
+ var otherFRame = new ImageFrame(10, 10);
+ var addedFrame = this.image.Frames.InsertFrame(0, otherFRame);
+ addedFrame.ComparePixelBufferTo(otherFRame.GetPixelSpan());
+ Assert.NotEqual(otherFRame, addedFrame);
+ }
+
+ [Fact]
+ public void MoveFrame_LeavesFrmaeInCorrectLocation()
+ {
+ for (var i = 0; i < 9; i++)
+ {
+ this.image.Frames.CreateFrame();
+ }
+
+ var frame = this.image.Frames[4];
+ this.image.Frames.MoveFrame(4, 7);
+ var newIndex = this.image.Frames.IndexOf(frame);
+ Assert.Equal(7, newIndex);
+ }
+
+
+ [Fact]
+ public void IndexOf_ReturnsCorrectIndex()
+ {
+ for (var i = 0; i < 9; i++)
+ {
+ this.image.Frames.CreateFrame();
+ }
+
+ var frame = this.image.Frames[4];
+ var index = this.image.Frames.IndexOf(frame);
+ Assert.Equal(4, index);
+ }
+
+ [Fact]
+ public void Contains_TrueIfMember()
+ {
+ for (var i = 0; i < 9; i++)
+ {
+ this.image.Frames.CreateFrame();
+ }
+
+ var frame = this.image.Frames[4];
+ Assert.True(this.image.Frames.Contains(frame));
+ }
+
+ [Fact]
+ public void Contains_TFalseIfNoneMember()
+ {
+ for (var i = 0; i < 9; i++)
+ {
+ this.image.Frames.CreateFrame();
+ }
+
+ var frame = new ImageFrame(10, 10);
+ Assert.False(this.image.Frames.Contains(frame));
+ }
+
+ public void Dispose()
+ {
+ this.image.Dispose();
+ this.collection.Dispose();
+ }
}
}
diff --git a/tests/ImageSharp.Tests/Image/ImageTests.cs b/tests/ImageSharp.Tests/Image/ImageTests.cs
index 00338e0bd..da813f428 100644
--- a/tests/ImageSharp.Tests/Image/ImageTests.cs
+++ b/tests/ImageSharp.Tests/Image/ImageTests.cs
@@ -110,64 +110,5 @@ namespace SixLabors.ImageSharp.Tests
Assert.Equal("image/png", mime.DefaultMimeType);
}
}
-
- [Theory]
- [WithTestPatternImages(10, 10, PixelTypes.Rgba32)]
- public void CloneFrame(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image img = provider.GetImage())
- {
- img.Frames.Add(new ImageFrame(10, 10));// add a frame anyway
- using (Image cloned = img.Clone(0))
- {
- Assert.Equal(2, img.Frames.Count);
- cloned.ComparePixelBufferTo(img.GetPixelSpan());
- }
- }
- }
-
- [Theory]
- [WithTestPatternImages(10, 10, PixelTypes.Rgba32)]
- public void CloneFrameAs(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image img = provider.GetImage())
- {
- img.Frames.Add(new ImageFrame(10, 10));// add a frame anyway
- using (Image cloned = img.CloneAs(0))
- {
- for (var x = 0; x < img.Width; x++)
- {
- for (var y = 0; y < img.Height; y++)
- {
- Bgra32 pixelClone = cloned[x, y];
- Bgra32 pixelSource = default(Bgra32);
- img[x, y].ToBgra32(ref pixelSource);
- Assert.Equal(pixelSource, pixelClone);
- }
- }
- Assert.Equal(2, img.Frames.Count);
- }
- }
- }
-
- [Theory]
- [WithTestPatternImages(10, 10, PixelTypes.Rgba32)]
- public void ExtractFrame(TestImageProvider provider)
- where TPixel : struct, IPixel
- {
- using (Image img = provider.GetImage())
- {
- var sourcePixelData = img.GetPixelSpan().ToArray();
-
- img.Frames.Add(new ImageFrame(10, 10));
- using (Image cloned = img.Extract(0))
- {
- Assert.Equal(1, img.Frames.Count);
- cloned.ComparePixelBufferTo(sourcePixelData);
- }
- }
- }
}
}
diff --git a/tests/ImageSharp.Tests/ImageSharp.Tests.v3.ncrunchproject b/tests/ImageSharp.Tests/ImageSharp.Tests.v3.ncrunchproject
new file mode 100644
index 000000000..f015b4b86
--- /dev/null
+++ b/tests/ImageSharp.Tests/ImageSharp.Tests.v3.ncrunchproject
@@ -0,0 +1,9 @@
+
+
+ False
+ UseStaticAnalysis
+
+ False
+ False
+
+
\ No newline at end of file
diff --git a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs
index 829bf3d10..d23ab0202 100644
--- a/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/ImageComparison/ImageComparer.cs
@@ -36,7 +36,7 @@ namespace SixLabors.ImageSharp.Tests.TestUtilities.ImageComparison
Image actual)
where TPixelA : struct, IPixel where TPixelB : struct, IPixel
{
- return comparer.CompareImagesOrFrames((ImageFrame)expected, (ImageFrame)actual);
+ return comparer.CompareImagesOrFrames(expected.Frames.RootFrame, actual.Frames.RootFrame);
}
public static IEnumerable> CompareImages(
diff --git a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs
index 7fd7a59a9..7da0f0696 100644
--- a/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/ImagingTestCaseUtility.cs
@@ -206,7 +206,7 @@ namespace SixLabors.ImageSharp.Tests
public static void ModifyPixel(Image img, int x, int y, byte perChannelChange)
where TPixel : struct, IPixel
{
- ModifyPixel((ImageFrame)img, x, y, perChannelChange);
+ ModifyPixel(img.Frames.RootFrame, x, y, perChannelChange);
}
public static void ModifyPixel(ImageFrame img, int x, int y, byte perChannelChange)
diff --git a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
index b367ecbd9..505cdc172 100644
--- a/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
+++ b/tests/ImageSharp.Tests/TestUtilities/TestImageExtensions.cs
@@ -166,12 +166,28 @@ namespace SixLabors.ImageSharp.Tests
for (int i = 0; i < expectedPixels.Length; i++)
{
- Assert.True(expectedPixels[i].Equals(actual[i]), $"Pixels are different on position {i}!" );
+ Assert.True(expectedPixels[i].Equals(actual[i]), $"Pixels are different on position {i}!");
}
-
+
return image;
}
+ public static ImageFrame ComparePixelBufferTo(
+ this ImageFrame image,
+ Span expectedPixels)
+ where TPixel : struct, IPixel
+ {
+ Span actual = image.GetPixelSpan();
+
+ Assert.True(expectedPixels.Length == actual.Length, "Buffer sizes are not equal!");
+
+ for (int i = 0; i < expectedPixels.Length; i++)
+ {
+ Assert.True(expectedPixels[i].Equals(actual[i]), $"Pixels are different on position {i}!");
+ }
+
+ return image;
+ }
public static Image CompareToOriginal(
this Image image,