Using ImageMagick to Resize images in DotNetCore 2.0

Posted in software by Christopher R. Wirz on Sat Dec 29 2018



In the post Resizing Graphics for iOS 12 Loading Image using DotNetCore 2.0, it was shown how to resize images using System.Drawing.Drawing2D. System.Drawing does not work in all environments. When this happens, it is possible to use the Nuget package Magick.NET-Q16-AnyCPU.

First, make your using statements.


using ImageMagick;
using System;

Then, within the class, define the methods for scaling


/// <summary>
///     Scales an image filling a size
/// </summary>
/// <param name="image">The image.</param>
/// <param name="size">The size.</param>
/// <param name="fitAspect">if set to <c>true</c> [fit aspect].</param>
/// <returns>A new image of the desired size</returns>
public static void ScaledToFill(
	this MagickImage image,
	int newWidth,
	int newHeight,
	bool fitAspect = true)
{
	newWidth = Math.Abs(newWidth);
	newHeight = Math.Abs(newHeight);
	if (newWidth<1 || newHeight < 1) { return; }

	if (!fitAspect)
	{
		image.Resize(newWidth, newHeight);
		return;
	}

	double scaleRatio = 1;
	double scaleX = ((double)newWidth / (double)image.Width);
	double scaleY = ((double)newHeight / (double)image.Height);
	if (scaleX == scaleY)
	{
		image.Resize(newWidth, newHeight);
		return;
	}

	scaleRatio = Math.Max(scaleY, scaleX);
	if (scaleRatio == scaleX)
	{
		// The image became wider, so the height must be cut
		var fullHeight = scaleX * image.Height;
		var topCrop = (fullHeight - newHeight) / 2;
		image.Resize(newWidth, (int)fullHeight);
		image.Crop(new MagickGeometry(0, (int)topCrop, newWidth, newHeight));
		return;
	}
	if (scaleRatio == scaleY)
	{
		// The image became wider, so the height must be cut
		var fullWidth = scaleY * image.Width;
		var leftCrop = (fullWidth - newWidth) / 2;
		image.Resize((int)fullWidth, newHeight);
		image.Crop(new MagickGeometry((int)leftCrop, 0, newWidth, newHeight));
		return;
	}

}

/// <summary>
///     Scales an image filling a size
/// </summary>
/// <param name="image">The image bytes.</param>
/// <param name="width">The width.</param>
/// <param name="height">The height.</param>
/// <param name="fitAspect">if set to <c>true</c> [fit aspect].</param>
/// <returns>The bytes of a new image</returns>
public static byte[] ScaledToFill(
	this byte[] image,
	int width = 196,
	int height = 196,
	bool fitAspect = true)
{
	MagickImage mi = new MagickImage(image);
	mi.ScaledToFill(width, height, fitAspect);
	return mi.ToByteArray();
}

/// <summary>
///     Scales an image filling a size
/// </summary>
/// <param name="image">The image.</param>
/// <param name="size">The size.</param>
/// <param name="fitAspect">if set to <c>true</c> [fit aspect].</param>
/// <returns>A new image of the desired size</returns>
public static void ScaledToFit(
	this MagickImage image,
	int newWidth,
	int newHeight)
{
	newWidth = Math.Abs(newWidth);
	newHeight = Math.Abs(newHeight);
	if (newWidth < 1 || newHeight < 1) { return; }


	double scaleRatio = 1;
	double scaleX = ((double)newWidth / (double)image.Width);
	double scaleY = ((double)newHeight / (double)image.Height);
	if (scaleX == scaleY)
	{
		image.Resize(newWidth, newHeight);
		return;
	}

	scaleRatio = Math.Min(scaleY, scaleX);
	if (scaleRatio == scaleX)
	{
		// The image became wider, so the height must be cut
		var fullHeight = scaleX * image.Height;
		image.Resize(newWidth, (int)fullHeight);
		return;
	}
	if (scaleRatio == scaleY)
	{
		// The image became wider, so the height must be cut
		var fullWidth = scaleY * image.Width;
		image.Resize((int)fullWidth, newHeight);
		return;
	}

}

/// <summary>
///     Scales an image filling a size
/// </summary>
/// <param name="image">The image.</param>
/// <param name="width">The new width.</param>
/// <param name="height">The new height.</param>
/// <returns>A new image of the desired size</returns>
public static byte[] ScaledToFit(
	this byte[] image,
	int width = 256,
	int height = 256)
{
	MagickImage mi = new MagickImage(image);
	mi.ScaledToFit(width, height);
	return mi.ToByteArray();
}