Browse Source

Update Crop method to accept rectangle

af/merge-core
James Jackson-South 9 years ago
parent
commit
c040582df6
  1. 37
      src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs
  2. 30
      src/ImageSharp/Filters/Transforms/Crop.cs

37
src/ImageSharp/Filters/Processors/Transforms/CropProcessor.cs

@ -5,6 +5,7 @@
namespace ImageSharp.Processors
{
using System;
using System.Threading.Tasks;
/// <summary>
@ -19,18 +20,16 @@ namespace ImageSharp.Processors
/// <summary>
/// Initializes a new instance of the <see cref="CropProcessor{TColor,TPacked}"/> class.
/// </summary>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
public CropProcessor(int width, int height)
/// <param name="cropRectangle">The target cropped rectangle.</param>
public CropProcessor(Rectangle cropRectangle)
{
this.Width = width;
this.Height = height;
this.CropRectangle = cropRectangle;
}
/// <summary>
/// Gets the width.
/// </summary>
public int Width { get; }
public Rectangle CropRectangle { get; }
/// <summary>
/// Gets the height.
@ -40,22 +39,20 @@ namespace ImageSharp.Processors
/// <inheritdoc/>
protected override void Apply(ImageBase<TColor, TPacked> source, Rectangle sourceRectangle, int startY, int endY)
{
int minX = 0;
int maxX = this.Width;
int minY = 0;
int maxY = this.Height;
int sourceX = sourceRectangle.X;
int sourceY = sourceRectangle.Y;
if (this.CropRectangle == sourceRectangle)
{
return;
}
Guard.MustBeGreaterThanOrEqualTo(minX, sourceX, nameof(minX));
Guard.MustBeGreaterThanOrEqualTo(minY, startY, nameof(startY));
Guard.MustBeLessThanOrEqualTo(maxX, sourceRectangle.Right, nameof(maxX));
Guard.MustBeLessThanOrEqualTo(maxY, endY, nameof(maxY));
int minY = Math.Max(this.CropRectangle.Y, startY);
int maxY = Math.Min(this.CropRectangle.Bottom, endY);
int minX = Math.Max(this.CropRectangle.X, sourceRectangle.X);
int maxX = Math.Min(this.CropRectangle.Right, sourceRectangle.Right);
TColor[] target = new TColor[this.Width * this.Height];
TColor[] target = new TColor[this.CropRectangle.Width * this.CropRectangle.Height];
using (PixelAccessor<TColor, TPacked> sourcePixels = source.Lock())
using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock<TColor, TPacked>(this.Width, this.Height))
using (PixelAccessor<TColor, TPacked> targetPixels = target.Lock<TColor, TPacked>(this.CropRectangle.Width, this.CropRectangle.Height))
{
Parallel.For(
minY,
@ -65,12 +62,12 @@ namespace ImageSharp.Processors
{
for (int x = minX; x < maxX; x++)
{
targetPixels[x, y] = sourcePixels[x + sourceX, y + sourceY];
targetPixels[x - minX, y - minY] = sourcePixels[x, y];
}
});
}
source.SetPixels(this.Width, this.Height, target);
source.SetPixels(this.CropRectangle.Width, this.CropRectangle.Height, target);
}
}
}

30
src/ImageSharp/Filters/Transforms/Crop.cs

@ -25,41 +25,25 @@ namespace ImageSharp
where TColor : struct, IPackedPixel<TPacked>
where TPacked : struct
{
return Crop(source, width, height, source.Bounds);
return Crop(source, new Rectangle(0, 0, width, height));
}
/// <summary>
/// Crops an image to the given width and height with the given source rectangle.
/// <remarks>
/// If the source rectangle is smaller than the target dimensions then the
/// area within the source is resized performing a zoomed crop.
/// </remarks>
/// Crops an image to the given rectangle.
/// </summary>
/// <typeparam name="TColor">The pixel format.</typeparam>
/// <typeparam name="TPacked">The packed format. <example>uint, long, float.</example></typeparam>
/// <param name="source">The image to crop.</param>
/// <param name="width">The target image width.</param>
/// <param name="height">The target image height.</param>
/// <param name="sourceRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to draw.
/// <param name="cropRectangle">
/// The <see cref="Rectangle"/> structure that specifies the portion of the image object to retain.
/// </param>
/// <returns>The <see cref="Image"/></returns>
public static Image<TColor, TPacked> Crop<TColor, TPacked>(this Image<TColor, TPacked> source, int width, int height, Rectangle sourceRectangle)
public static Image<TColor, TPacked> Crop<TColor, TPacked>(this Image<TColor, TPacked> source, Rectangle cropRectangle)
where TColor : struct, IPackedPixel<TPacked>
where TPacked : struct
{
Guard.MustBeGreaterThan(width, 0, nameof(width));
Guard.MustBeGreaterThan(height, 0, nameof(height));
if (sourceRectangle.Width < width || sourceRectangle.Height < height)
{
// If the source rectangle is smaller than the target perform a
// cropped zoom.
source = source.Resize(sourceRectangle.Width, sourceRectangle.Height);
}
CropProcessor<TColor, TPacked> processor = new CropProcessor<TColor, TPacked>(width, height);
return source.Process(sourceRectangle, processor);
CropProcessor<TColor, TPacked> processor = new CropProcessor<TColor, TPacked>(cropRectangle);
return source.Process(source.Bounds, processor);
}
}
}
Loading…
Cancel
Save