Browse Source

Processed review comments, removed IImageFrameCollection interface, and added backgroundColor parameter to ImageFrameCollection.CreateFrame() method with default.

pull/552/head
woutware 8 years ago
parent
commit
0d81089159
  1. 115
      src/ImageSharp/IImageFrameCollection.cs
  2. 123
      src/ImageSharp/ImageFrameCollection.cs
  3. 2
      src/ImageSharp/Image{TPixel}.cs

115
src/ImageSharp/IImageFrameCollection.cs

@ -1,115 +0,0 @@
// Copyright (c) Six Labors and contributors.
// Licensed under the Apache License, Version 2.0.
using System;
using System.Collections.Generic;
using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp
{
/// <summary>
/// Encapsulates a collection of <see cref="ImageFrame{T}"/> instances that make up an <see cref="Image{T}"/>.
/// </summary>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
public interface IImageFrameCollection<TPixel> : IEnumerable<ImageFrame<TPixel>>
where TPixel : struct, IPixel<TPixel>
{
/// <summary>
/// Gets the number of frames.
/// </summary>
int Count { get; }
/// <summary>
/// Gets the root frame.
/// </summary>
ImageFrame<TPixel> RootFrame { get; }
/// <summary>
/// Gets the <see cref="ImageFrame{TPixel}"/> at the specified index.
/// </summary>
/// <value>
/// The <see cref="ImageFrame{TPixel}"/>.
/// </value>
/// <param name="index">The index.</param>
/// <returns>The <see cref="ImageFrame{TPixel}"/> at the specified index.</returns>
ImageFrame<TPixel> this[int index] { get; }
/// <summary>
/// Creates an <see cref="Image{T}"/> with only the frame at the specified index
/// with the same metadata as the original image.
/// </summary>
/// <param name="index">The zero-based index of the frame to clone.</param>
/// <returns>The new <see cref="Image{TPixel}"/> with the specified frame.</returns>
Image<TPixel> CloneFrame(int index);
/// <summary>
/// Removes the frame at the specified index and creates a new image with only the removed frame
/// with the same metadata as the original image.
/// </summary>
/// <param name="index">The zero-based index of the frame to export.</param>
/// <exception cref="InvalidOperationException">Cannot remove last frame.</exception>
/// <returns>The new <see cref="Image{TPixel}"/> with the specified frame.</returns>
Image<TPixel> ExportFrame(int index);
/// <summary>
/// Removes the frame at the specified index and frees all freeable resources associated with it.
/// </summary>
/// <param name="index">The zero-based index of the frame to remove.</param>
/// <exception cref="InvalidOperationException">Cannot remove last frame.</exception>
void RemoveFrame(int index);
/// <summary>
/// Creates a new <seealso cref="ImageFrame{TPixel}"/> and appends it to the end of the collection.
/// </summary>
/// <returns>The new <see cref="ImageFrame{TPixel}"/>.</returns>
ImageFrame<TPixel> CreateFrame();
/// <summary>
/// Clones the <paramref name="source"/> frame and appends the clone to the end of the collection.
/// </summary>
/// <param name="source">The raw pixel data to generate the <seealso cref="ImageFrame{TPixel}"/> from.</param>
/// <returns>The cloned <see cref="ImageFrame{TPixel}"/>.</returns>
ImageFrame<TPixel> AddFrame(ImageFrame<TPixel> source);
/// <summary>
/// Creates a new frame from the pixel data with the same dimensions as the other frames and inserts the
/// new frame at the end of the collection.
/// </summary>
/// <param name="source">The raw pixel data to generate the <seealso cref="ImageFrame{TPixel}"/> from.</param>
/// <returns>The new <see cref="ImageFrame{TPixel}"/>.</returns>
ImageFrame<TPixel> AddFrame(TPixel[] source);
/// <summary>
/// Clones and inserts the <paramref name="source"/> into the <seealso cref="IImageFrameCollection{TPixel}"/> at the specified <paramref name="index"/>.
/// </summary>
/// <param name="index">The zero-based index to insert the frame at.</param>
/// <param name="source">The <seealso cref="ImageFrame{TPixel}"/> to clone and insert into the <seealso cref="IImageFrameCollection{TPixel}"/>.</param>
/// <exception cref="ArgumentException">Frame must have the same dimensions as the image.</exception>
/// <returns>The cloned <see cref="ImageFrame{TPixel}"/>.</returns>
ImageFrame<TPixel> InsertFrame(int index, ImageFrame<TPixel> source);
/// <summary>
/// Moves an <seealso cref="ImageFrame{TPixel}"/> from <paramref name="sourceIndex"/> to <paramref name="destinationIndex"/>.
/// </summary>
/// <param name="sourceIndex">The zero-based index of the frame to move.</param>
/// <param name="destinationIndex">The index to move the frame to.</param>
void MoveFrame(int sourceIndex, int destinationIndex);
/// <summary>
/// Determines the index of a specific <paramref name="frame"/> in the <seealso cref="IImageFrameCollection{TPixel}"/>.
/// </summary>
/// <param name="frame">The <seealso cref="ImageFrame{TPixel}"/> to locate in the <seealso cref="IImageFrameCollection{TPixel}"/>.</param>
/// <returns>The index of item if found in the list; otherwise, -1.</returns>
int IndexOf(ImageFrame<TPixel> frame);
/// <summary>
/// Determines whether the <seealso cref="IImageFrameCollection{TPixel}"/> contains the <paramref name="frame"/>.
/// </summary>
/// <param name="frame">The frame.</param>
/// <returns>
/// <c>true</c> if the <seealso cref="IImageFrameCollection{TPixel}"/> contains the specified frame; otherwise, <c>false</c>.
/// </returns>
bool Contains(ImageFrame<TPixel> frame);
}
}

123
src/ImageSharp/ImageFrameCollection.cs

@ -9,8 +9,11 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp namespace SixLabors.ImageSharp
{ {
/// <inheritdoc/> /// <summary>
internal sealed class ImageFrameCollection<TPixel> : IImageFrameCollection<TPixel> /// Encapsulates a collection of <see cref="ImageFrame{T}"/> instances that make up an <see cref="Image{T}"/>.
/// </summary>
/// <typeparam name="TPixel">The type of the pixel.</typeparam>
public sealed class ImageFrameCollection<TPixel> : IEnumerable<ImageFrame<TPixel>>
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
private readonly IList<ImageFrame<TPixel>> frames = new List<ImageFrame<TPixel>>(); private readonly IList<ImageFrame<TPixel>> frames = new List<ImageFrame<TPixel>>();
@ -41,51 +44,85 @@ namespace SixLabors.ImageSharp
} }
} }
/// <inheritdoc/> /// <summary>
/// Gets the number of frames.
/// </summary>
public int Count => this.frames.Count; public int Count => this.frames.Count;
/// <inheritdoc/> /// <summary>
/// Gets the root frame.
/// </summary>
public ImageFrame<TPixel> RootFrame => this.frames.Count > 0 ? this.frames[0] : null; public ImageFrame<TPixel> RootFrame => this.frames.Count > 0 ? this.frames[0] : null;
/// <inheritdoc/> /// <summary>
/// Gets the <see cref="ImageFrame{TPixel}"/> at the specified index.
/// </summary>
/// <value>
/// The <see cref="ImageFrame{TPixel}"/>.
/// </value>
/// <param name="index">The index.</param>
/// <returns>The <see cref="ImageFrame{TPixel}"/> at the specified index.</returns>
public ImageFrame<TPixel> this[int index] => this.frames[index]; public ImageFrame<TPixel> this[int index] => this.frames[index];
/// <inheritdoc/> /// <summary>
/// Determines the index of a specific <paramref name="frame"/> in the <seealso cref="ImageFrameCollection{TPixel}"/>.
/// </summary>
/// <param name="frame">The <seealso cref="ImageFrame{TPixel}"/> to locate in the <seealso cref="ImageFrameCollection{TPixel}"/>.</param>
/// <returns>The index of item if found in the list; otherwise, -1.</returns>
public int IndexOf(ImageFrame<TPixel> frame) => this.frames.IndexOf(frame); public int IndexOf(ImageFrame<TPixel> frame) => this.frames.IndexOf(frame);
/// <inheritdoc/> /// <summary>
public ImageFrame<TPixel> InsertFrame(int index, ImageFrame<TPixel> frame) /// Clones and inserts the <paramref name="source"/> into the <seealso cref="ImageFrameCollection{TPixel}"/> at the specified <paramref name="index"/>.
/// </summary>
/// <param name="index">The zero-based index to insert the frame at.</param>
/// <param name="source">The <seealso cref="ImageFrame{TPixel}"/> to clone and insert into the <seealso cref="ImageFrameCollection{TPixel}"/>.</param>
/// <exception cref="ArgumentException">Frame must have the same dimensions as the image.</exception>
/// <returns>The cloned <see cref="ImageFrame{TPixel}"/>.</returns>
public ImageFrame<TPixel> InsertFrame(int index, ImageFrame<TPixel> source)
{ {
this.ValidateFrame(frame); this.ValidateFrame(source);
ImageFrame<TPixel> clonedFrame = frame.Clone(); ImageFrame<TPixel> clonedFrame = source.Clone();
this.frames.Insert(index, clonedFrame); this.frames.Insert(index, clonedFrame);
return clonedFrame; return clonedFrame;
} }
/// <inheritdoc/> /// <summary>
public ImageFrame<TPixel> AddFrame(ImageFrame<TPixel> frame) /// Clones the <paramref name="source"/> frame and appends the clone to the end of the collection.
/// </summary>
/// <param name="source">The raw pixel data to generate the <seealso cref="ImageFrame{TPixel}"/> from.</param>
/// <returns>The cloned <see cref="ImageFrame{TPixel}"/>.</returns>
public ImageFrame<TPixel> AddFrame(ImageFrame<TPixel> source)
{ {
this.ValidateFrame(frame); this.ValidateFrame(source);
ImageFrame<TPixel> clonedFrame = frame.Clone(); ImageFrame<TPixel> clonedFrame = source.Clone();
this.frames.Add(clonedFrame); this.frames.Add(clonedFrame);
return clonedFrame; return clonedFrame;
} }
/// <inheritdoc/> /// <summary>
public ImageFrame<TPixel> AddFrame(TPixel[] data) /// Creates a new frame from the pixel data with the same dimensions as the other frames and inserts the
/// new frame at the end of the collection.
/// </summary>
/// <param name="source">The raw pixel data to generate the <seealso cref="ImageFrame{TPixel}"/> from.</param>
/// <returns>The new <see cref="ImageFrame{TPixel}"/>.</returns>
public ImageFrame<TPixel> AddFrame(TPixel[] source)
{ {
Guard.NotNull(data, nameof(data)); Guard.NotNull(source, nameof(source));
var frame = ImageFrame.LoadPixelData( var frame = ImageFrame.LoadPixelData(
this.parent.GetMemoryManager(), this.parent.GetMemoryManager(),
new Span<TPixel>(data), new Span<TPixel>(source),
this.RootFrame.Width, this.RootFrame.Width,
this.RootFrame.Height); this.RootFrame.Height);
this.frames.Add(frame); this.frames.Add(frame);
return frame; return frame;
} }
/// <inheritdoc/> /// <summary>
/// Removes the frame at the specified index and frees all freeable resources associated with it.
/// </summary>
/// <param name="index">The zero-based index of the frame to remove.</param>
/// <exception cref="InvalidOperationException">Cannot remove last frame.</exception>
public void RemoveFrame(int index) public void RemoveFrame(int index)
{ {
if (index == 0 && this.Count == 1) if (index == 0 && this.Count == 1)
@ -98,26 +135,42 @@ namespace SixLabors.ImageSharp
frame.Dispose(); frame.Dispose();
} }
/// <inheritdoc/> /// <summary>
/// Determines whether the <seealso cref="ImageFrameCollection{TPixel}"/> contains the <paramref name="frame"/>.
/// </summary>
/// <param name="frame">The frame.</param>
/// <returns>
/// <c>true</c> if the <seealso cref="ImageFrameCollection{TPixel}"/> contains the specified frame; otherwise, <c>false</c>.
/// </returns>
public bool Contains(ImageFrame<TPixel> frame) public bool Contains(ImageFrame<TPixel> frame)
{ {
return this.frames.Contains(frame); return this.frames.Contains(frame);
} }
/// <inheritdoc/> /// <summary>
public void MoveFrame(int sourceIndex, int destIndex) /// Moves an <seealso cref="ImageFrame{TPixel}"/> from <paramref name="sourceIndex"/> to <paramref name="destinationIndex"/>.
/// </summary>
/// <param name="sourceIndex">The zero-based index of the frame to move.</param>
/// <param name="destinationIndex">The index to move the frame to.</param>
public void MoveFrame(int sourceIndex, int destinationIndex)
{ {
if (sourceIndex == destIndex) if (sourceIndex == destinationIndex)
{ {
return; return;
} }
ImageFrame<TPixel> frameAtIndex = this.frames[sourceIndex]; ImageFrame<TPixel> frameAtIndex = this.frames[sourceIndex];
this.frames.RemoveAt(sourceIndex); this.frames.RemoveAt(sourceIndex);
this.frames.Insert(destIndex, frameAtIndex); this.frames.Insert(destinationIndex, frameAtIndex);
} }
/// <inheritdoc/> /// <summary>
/// Removes the frame at the specified index and creates a new image with only the removed frame
/// with the same metadata as the original image.
/// </summary>
/// <param name="index">The zero-based index of the frame to export.</param>
/// <exception cref="InvalidOperationException">Cannot remove last frame.</exception>
/// <returns>The new <see cref="Image{TPixel}"/> with the specified frame.</returns>
public Image<TPixel> ExportFrame(int index) public Image<TPixel> ExportFrame(int index)
{ {
ImageFrame<TPixel> frame = this[index]; ImageFrame<TPixel> frame = this[index];
@ -132,7 +185,12 @@ namespace SixLabors.ImageSharp
return new Image<TPixel>(this.parent.GetConfiguration(), this.parent.MetaData.Clone(), new[] { frame }); return new Image<TPixel>(this.parent.GetConfiguration(), this.parent.MetaData.Clone(), new[] { frame });
} }
/// <inheritdoc/> /// <summary>
/// Creates an <see cref="Image{T}"/> with only the frame at the specified index
/// with the same metadata as the original image.
/// </summary>
/// <param name="index">The zero-based index of the frame to clone.</param>
/// <returns>The new <see cref="Image{TPixel}"/> with the specified frame.</returns>
public Image<TPixel> CloneFrame(int index) public Image<TPixel> CloneFrame(int index)
{ {
ImageFrame<TPixel> frame = this[index]; ImageFrame<TPixel> frame = this[index];
@ -140,10 +198,15 @@ namespace SixLabors.ImageSharp
return new Image<TPixel>(this.parent.GetConfiguration(), this.parent.MetaData.Clone(), new[] { clonedFrame }); return new Image<TPixel>(this.parent.GetConfiguration(), this.parent.MetaData.Clone(), new[] { clonedFrame });
} }
/// <inheritdoc/> /// <summary>
public ImageFrame<TPixel> CreateFrame() /// Creates a new <seealso cref="ImageFrame{TPixel}" /> and appends it to the end of the collection.
{ /// </summary>
var frame = new ImageFrame<TPixel>(this.parent.GetConfiguration(), this.RootFrame.Width, this.RootFrame.Height, default); /// <param name="backgroundColor">The background color to initialize the pixels with.</param>
/// <returns>
/// The new <see cref="ImageFrame{TPixel}" />.
/// </returns>
public ImageFrame<TPixel> CreateFrame(TPixel backgroundColor = default) {
var frame = new ImageFrame<TPixel>(this.parent.GetConfiguration(), this.RootFrame.Width, this.RootFrame.Height, backgroundColor);
this.frames.Add(frame); this.frames.Add(frame);
return frame; return frame;
} }

2
src/ImageSharp/Image{TPixel}.cs

@ -135,7 +135,7 @@ namespace SixLabors.ImageSharp
/// <summary> /// <summary>
/// Gets the frames. /// Gets the frames.
/// </summary> /// </summary>
public IImageFrameCollection<TPixel> Frames => this.frames; public ImageFrameCollection<TPixel> Frames => this.frames;
/// <summary> /// <summary>
/// Gets the root frame. /// Gets the root frame.

Loading…
Cancel
Save