Browse Source

Transform() extension method overload taking Size

af/merge-core
Anton Firszov 8 years ago
parent
commit
b09f533aa2
  1. 12
      src/ImageSharp/Image/ImageFrame{TPixel}.cs
  2. 21
      src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs
  3. 30
      src/ImageSharp/Processing/Transforms/Transform.cs

12
src/ImageSharp/Image/ImageFrame{TPixel}.cs

@ -13,6 +13,8 @@ using SixLabors.ImageSharp.PixelFormats;
namespace SixLabors.ImageSharp namespace SixLabors.ImageSharp
{ {
using SixLabors.Primitives;
/// <summary> /// <summary>
/// Represents a single frame in a animation. /// Represents a single frame in a animation.
/// </summary> /// </summary>
@ -53,6 +55,16 @@ namespace SixLabors.ImageSharp
this.MetaData = metaData; this.MetaData = metaData;
} }
/// <summary>
/// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
/// </summary>
/// <param name="size">The <see cref="Size"/> of the frame.</param>
/// <param name="metaData">The meta data.</param>
internal ImageFrame(Size size, ImageFrameMetaData metaData)
: this(size.Width, size.Height, metaData)
{
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class. /// Initializes a new instance of the <see cref="ImageFrame{TPixel}" /> class.
/// </summary> /// </summary>

21
src/ImageSharp/Processing/Processors/Transforms/AffineTransformProcessor.cs

@ -21,7 +21,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
internal class AffineTransformProcessor<TPixel> : InterpolatedTransformProcessorBase<TPixel> internal class AffineTransformProcessor<TPixel> : InterpolatedTransformProcessorBase<TPixel>
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
{ {
private Size? targetDimensions; private Size targetDimensions;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="AffineTransformProcessor{TPixel}"/> class. /// Initializes a new instance of the <see cref="AffineTransformProcessor{TPixel}"/> class.
@ -38,7 +38,7 @@ namespace SixLabors.ImageSharp.Processing.Processors
/// <param name="matrix">The transform matrix</param> /// <param name="matrix">The transform matrix</param>
/// <param name="sampler">The sampler to perform the transform operation.</param> /// <param name="sampler">The sampler to perform the transform operation.</param>
public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler) public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler)
: this(matrix, sampler, Rectangle.Empty) : this(matrix, sampler, Size.Empty)
{ {
} }
@ -47,14 +47,14 @@ namespace SixLabors.ImageSharp.Processing.Processors
/// </summary> /// </summary>
/// <param name="matrix">The transform matrix</param> /// <param name="matrix">The transform matrix</param>
/// <param name="sampler">The sampler to perform the transform operation.</param> /// <param name="sampler">The sampler to perform the transform operation.</param>
/// <param name="rectangle">The rectangle to constrain the transformed image to.</param> /// <param name="targetDimensions">The target dimensions to constrain the transformed image to.</param>
public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Rectangle rectangle) public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size targetDimensions)
: base(sampler) : base(sampler)
{ {
// Tansforms are inverted else the output is the opposite of the expected. // Tansforms are inverted else the output is the opposite of the expected.
Matrix3x2.Invert(matrix, out matrix); Matrix3x2.Invert(matrix, out matrix);
this.TransformMatrix = matrix; this.TransformMatrix = matrix;
this.targetDimensions = rectangle == Rectangle.Empty ?(Size?)null : rectangle.Size; this.targetDimensions = targetDimensions;
} }
/// <summary> /// <summary>
@ -65,17 +65,15 @@ namespace SixLabors.ImageSharp.Processing.Processors
/// <inheritdoc/> /// <inheritdoc/>
protected override Image<TPixel> CreateDestination(Image<TPixel> source, Rectangle sourceRectangle) protected override Image<TPixel> CreateDestination(Image<TPixel> source, Rectangle sourceRectangle)
{ {
if (!this.targetDimensions.HasValue) if (this.targetDimensions == Size.Empty)
{ {
// TODO: CreateDestination() should not modify the processors state! (kinda CQRS) // TODO: CreateDestination() should not modify the processors state! (kinda CQRS)
this.targetDimensions = this.GetTransformedDimensions(sourceRectangle.Size, this.TransformMatrix); this.targetDimensions = this.GetTransformedDimensions(sourceRectangle.Size, this.TransformMatrix);
} }
Size targetDims = this.targetDimensions.Value;
// We will always be creating the clone even for mutate because we may need to resize the canvas // We will always be creating the clone even for mutate because we may need to resize the canvas
IEnumerable<ImageFrame<TPixel>> frames = IEnumerable<ImageFrame<TPixel>> frames =
source.Frames.Select(x => new ImageFrame<TPixel>(targetDims.Width, targetDims.Height, x.MetaData.Clone())); source.Frames.Select(x => new ImageFrame<TPixel>(this.targetDimensions, x.MetaData.Clone()));
// Use the overload to prevent an extra frame being added // Use the overload to prevent an extra frame being added
return new Image<TPixel>(source.GetConfiguration(), source.MetaData.Clone(), frames); return new Image<TPixel>(source.GetConfiguration(), source.MetaData.Clone(), frames);
@ -88,14 +86,13 @@ namespace SixLabors.ImageSharp.Processing.Processors
Rectangle sourceRectangle, Rectangle sourceRectangle,
Configuration configuration) Configuration configuration)
{ {
int height = this.targetDimensions.Value.Height; int height = this.targetDimensions.Height;
int width = this.targetDimensions.Value.Width; int width = this.targetDimensions.Width;
Rectangle sourceBounds = source.Bounds(); Rectangle sourceBounds = source.Bounds();
var targetBounds = new Rectangle(0, 0, width, height); var targetBounds = new Rectangle(0, 0, width, height);
// Since could potentially be resizing the canvas we might need to re-calculate the matrix // Since could potentially be resizing the canvas we might need to re-calculate the matrix
Matrix3x2 matrix = this.GetProcessingMatrix(sourceBounds, targetBounds); Matrix3x2 matrix = this.GetProcessingMatrix(sourceBounds, targetBounds);
if (this.Sampler is NearestNeighborResampler) if (this.Sampler is NearestNeighborResampler)

30
src/ImageSharp/Processing/Transforms/Transform.cs

@ -46,9 +46,35 @@ namespace SixLabors.ImageSharp
/// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param> /// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param>
/// <param name="rectangle">The rectangle to constrain the transformed image to.</param> /// <param name="rectangle">The rectangle to constrain the transformed image to.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns> /// <returns>The <see cref="Image{TPixel}"/></returns>
public static IImageProcessingContext<TPixel> Transform<TPixel>(this IImageProcessingContext<TPixel> source, Matrix3x2 matrix, IResampler sampler, Rectangle rectangle) public static IImageProcessingContext<TPixel> Transform<TPixel>(
this IImageProcessingContext<TPixel> source,
Matrix3x2 matrix,
IResampler sampler,
Rectangle rectangle)
where TPixel : struct, IPixel<TPixel> where TPixel : struct, IPixel<TPixel>
=> source.ApplyProcessor(new AffineTransformProcessor<TPixel>(matrix, sampler, rectangle)); {
// TODO: Fixme!
return source.ApplyProcessor(new AffineTransformProcessor<TPixel>(matrix, sampler, rectangle.Size));
}
/// <summary>
/// Transforms an image by the given matrix using the specified sampling algorithm.
/// </summary>
/// <typeparam name="TPixel">The pixel format.</typeparam>
/// <param name="source">The image to transform.</param>
/// <param name="matrix">The transformation matrix.</param>
/// <param name="sampler">The <see cref="IResampler"/> to perform the resampling.</param>
/// <param name="destinationSize">The dimensions to constrain the transformed image to.</param>
/// <returns>The <see cref="Image{TPixel}"/></returns>
public static IImageProcessingContext<TPixel> Transform<TPixel>(
this IImageProcessingContext<TPixel> source,
Matrix3x2 matrix,
IResampler sampler,
Size destinationSize)
where TPixel : struct, IPixel<TPixel>
{
return source.ApplyProcessor(new AffineTransformProcessor<TPixel>(matrix, sampler, destinationSize));
}
/// <summary> /// <summary>
/// Transforms an image by the given matrix. /// Transforms an image by the given matrix.

Loading…
Cancel
Save