//
// Copyright (c) James Jackson-South and contributors.
// Licensed under the Apache License, Version 2.0.
//
namespace ImageProcessorCore.Samplers
{
///
/// Extensions methods for to apply samplers to the image.
///
public static class ImageSamplerExtensions
{
///
/// Crops an image to the given width and height.
///
/// The image to resize.
/// The target image width.
/// The target image height.
/// A delegate which is called as progress is made processing the image.
/// The
public static Image Crop(this Image source, int width, int height, ProgressEventHandler progressHandler = null)
{
return Crop(source, width, height, source.Bounds, progressHandler);
}
///
/// Crops an image to the given width and height with the given source rectangle.
///
/// If the source rectangle is smaller than the target dimensions then the
/// area within the source is resized performing a zoomed crop.
///
///
/// The image to crop.
/// The target image width.
/// The target image height.
///
/// The structure that specifies the portion of the image object to draw.
///
/// A delegate which is called as progress is made processing the image.
/// The
public static Image Crop(this Image source, int width, int height, Rectangle sourceRectangle, ProgressEventHandler progressHandler = null)
{
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);
}
Crop processor = new Crop();
processor.OnProgress += progressHandler;
try
{
return source.Process(width, height, sourceRectangle, new Rectangle(0, 0, width, height), processor);
}
finally
{
processor.OnProgress -= progressHandler;
}
}
///
/// Crops an image to the area of greatest entropy.
///
/// The image to crop.
/// The threshold for entropic density.
/// A delegate which is called as progress is made processing the image.
/// The
public static Image EntropyCrop(this Image source, float threshold = .5f, ProgressEventHandler progressHandler = null)
{
EntropyCrop processor = new EntropyCrop(threshold);
processor.OnProgress += progressHandler;
try
{
return source.Process(source.Width, source.Height, source.Bounds, Rectangle.Empty, processor);
}
finally
{
processor.OnProgress -= progressHandler;
}
}
///
/// Evenly pads an image to fit the new dimensions.
///
/// The source image to pad.
/// The new width.
/// The new height.
/// A delegate which is called as progress is made processing the image.
/// The .
public static Image Pad(this Image source, int width, int height, ProgressEventHandler progressHandler = null)
{
ResizeOptions options = new ResizeOptions
{
Size = new Size(width, height),
Mode = ResizeMode.BoxPad,
Sampler = new NearestNeighborResampler()
};
return Resize(source, options, progressHandler);
}
///
/// Resizes an image in accordance with the given .
///
/// The image to resize.
/// The resize options.
/// A delegate which is called as progress is made processing the image.
/// The
/// Passing zero for one of height or width within the resize options will automatically preserve the aspect ratio of the original image
public static Image Resize(this Image source, ResizeOptions options, ProgressEventHandler progressHandler = null)
{
// Ensure size is populated across both dimensions.
if (options.Size.Width == 0 && options.Size.Height > 0)
{
options.Size = new Size(source.Width * options.Size.Height / source.Height, options.Size.Height);
}
if (options.Size.Height == 0 && options.Size.Width > 0)
{
options.Size = new Size(options.Size.Width, source.Height * options.Size.Width / source.Width);
}
Rectangle targetRectangle = ResizeHelper.CalculateTargetLocationAndBounds(source, options);
return Resize(source, options.Size.Width, options.Size.Height, options.Sampler, source.Bounds, targetRectangle, options.Compand, progressHandler);
}
///
/// Resizes an image to the given width and height.
///
/// The image to resize.
/// The target image width.
/// The target image height.
/// A delegate which is called as progress is made processing the image.
/// The
/// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image
public static Image Resize(this Image source, int width, int height, ProgressEventHandler progressHandler = null)
{
return Resize(source, width, height, new BicubicResampler(), false, progressHandler);
}
///
/// Resizes an image to the given width and height.
///
/// The image to resize.
/// The target image width.
/// The target image height.
/// Whether to compress and expand the image color-space to gamma correct the image during processing.
/// A delegate which is called as progress is made processing the image.
/// The
/// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image
public static Image Resize(this Image source, int width, int height, bool compand, ProgressEventHandler progressHandler = null)
{
return Resize(source, width, height, new BicubicResampler(), compand, progressHandler);
}
///
/// Resizes an image to the given width and height with the given sampler.
///
/// The image to resize.
/// The target image width.
/// The target image height.
/// The to perform the resampling.
/// Whether to compress and expand the image color-space to gamma correct the image during processing.
/// A delegate which is called as progress is made processing the image.
/// The
/// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image
public static Image Resize(this Image source, int width, int height, IResampler sampler, bool compand, ProgressEventHandler progressHandler = null)
{
return Resize(source, width, height, sampler, source.Bounds, new Rectangle(0, 0, width, height), compand, progressHandler);
}
///
/// Resizes an image to the given width and height with the given sampler and
/// source rectangle.
///
/// The image to resize.
/// The target image width.
/// The target image height.
/// The to perform the resampling.
///
/// The structure that specifies the portion of the image object to draw.
///
///
/// The structure that specifies the portion of the target image object to draw to.
///
/// Whether to compress and expand the image color-space to gamma correct the image during processing.
/// A delegate which is called as progress is made processing the image.
/// The
/// Passing zero for one of height or width will automatically preserve the aspect ratio of the original image
public static Image Resize(this Image source, int width, int height, IResampler sampler, Rectangle sourceRectangle, Rectangle targetRectangle, bool compand = false, ProgressEventHandler progressHandler = null)
{
if (width == 0 && height > 0)
{
width = source.Width * height / source.Height;
targetRectangle.Width = width;
}
if (height == 0 && width > 0)
{
height = source.Height * width / source.Width;
targetRectangle.Height = height;
}
Guard.MustBeGreaterThan(width, 0, nameof(width));
Guard.MustBeGreaterThan(height, 0, nameof(height));
Resize processor = new Resize(sampler) { Compand = compand };
processor.OnProgress += progressHandler;
try
{
return source.Process(width, height, sourceRectangle, targetRectangle, processor);
}
finally
{
processor.OnProgress -= progressHandler;
}
}
///
/// Rotates an image by the given angle in degrees, expanding the image to fit the rotated result.
///
/// The image to rotate.
/// The angle in degrees to perform the rotation.
/// A delegate which is called as progress is made processing the image.
/// The
public static Image Rotate(this Image source, float degrees, ProgressEventHandler progressHandler = null)
{
return Rotate(source, degrees, Point.Empty, true, progressHandler);
}
///
/// Rotates an image by the given angle in degrees around the given center point.
///
/// The image to rotate.
/// The angle in degrees to perform the rotation.
/// The center point at which to rotate the image.
/// Whether to expand the image to fit the rotated result.
/// A delegate which is called as progress is made processing the image.
/// The
public static Image Rotate(this Image source, float degrees, Point center, bool expand, ProgressEventHandler progressHandler = null)
{
Rotate processor = new Rotate { Angle = degrees, Center = center, Expand = expand };
processor.OnProgress += progressHandler;
try
{
return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, processor);
}
finally
{
processor.OnProgress -= progressHandler;
}
}
///
/// Rotates and flips an image by the given instructions.
///
/// The image to rotate, flip, or both.
/// The to perform the rotation.
/// The to perform the flip.
/// A delegate which is called as progress is made processing the image.
/// The
public static Image RotateFlip(this Image source, RotateType rotateType, FlipType flipType, ProgressEventHandler progressHandler = null)
{
RotateFlip processor = new RotateFlip(rotateType, flipType);
processor.OnProgress += progressHandler;
try
{
return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, processor);
}
finally
{
processor.OnProgress -= progressHandler;
}
}
///
/// Skews an image by the given angles in degrees, expanding the image to fit the skewed result.
///
/// The image to skew.
/// The angle in degrees to perform the rotation along the x-axis.
/// The angle in degrees to perform the rotation along the y-axis.
/// A delegate which is called as progress is made processing the image.
/// The
public static Image Skew(this Image source, float degreesX, float degreesY, ProgressEventHandler progressHandler = null)
{
return Skew(source, degreesX, degreesY, Point.Empty, true, progressHandler);
}
///
/// Skews an image by the given angles in degrees around the given center point.
///
/// The image to skew.
/// The angle in degrees to perform the rotation along the x-axis.
/// The angle in degrees to perform the rotation along the y-axis.
/// The center point at which to skew the image.
/// Whether to expand the image to fit the skewed result.
/// A delegate which is called as progress is made processing the image.
/// The
public static Image Skew(this Image source, float degreesX, float degreesY, Point center, bool expand, ProgressEventHandler progressHandler = null)
{
Skew processor = new Skew { AngleX = degreesX, AngleY = degreesY, Center = center, Expand = expand };
processor.OnProgress += progressHandler;
try
{
return source.Process(source.Width, source.Height, source.Bounds, source.Bounds, processor);
}
finally
{
processor.OnProgress -= progressHandler;
}
}
}
}