# Size calculations for image resizing (C#)

I just reused some code I wrote a couple of years ago, and thought I’d share it here.

It’s not about the best ways to resize images. If that is what you search for, have a look at this 🙂

It’s rather some code for calculating the size of the target image from the originals size while applying one of four rules:

• Fit: Often you want to fit the image into a box – but without stretching it. So if you have a image that is 50×100 and you want to fit it into 50×50, the result is 25×100. If the original is 100×50, the result would be 50×25. Getting it?
• Stretch: Not to useful, but sometimes needed 🙂
• FixedHeight: Maintain the ratio, adjust to height.
• FixedWidth: Maintain the ration, adjust to width.

## Usage

Pretty straight-forward, I think.

```var _100_50 = new Size(100, 50);
ResizeType.Fit.CalcNewSize(_100_50, new Size(50, 50), true)
.Satisfy(s => s.Width == 50 && s.Height == 25);

var _50_100 = new Size(50, 100);

ResizeType.Fit.CalcNewSize(_50_100, new Size(50, 50), true)
.Satisfy(s => s.Width == 25 && s.Height == 50);

ResizeType.Stretched.CalcNewSize(_50_100, new Size(500, 500), false)
.Satisfy(s => s.Width == 50 && s.Height == 100);

ResizeType.FixedHeight.CalcNewSize(_50_100, new Size(0, 50), false)
.Satisfy(s => s.Width == 25 && s.Height == 50);

```

* The Satisfy-Method is from SharpTestEx.

## Code

Have fun! 🙂

```using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;

namespace lcorneliussen
{
public interface IResizeType
{
Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller);
}

/// <summary>
/// Offers some helpful methods for image resizing.
/// </summary>
public class ResizeType
{
/// <summary>
/// Returns the new size by fixed height.
/// </summary>
public static IResizeType FixedHeight = new FixedHeightResizeType();

/// <summary>
/// Returns the new size by fixed width.
/// </summary>
public static IResizeType FixedWidth = new FixedWidthResizeType();

/// <summary>
/// Returns a size wich fits in a target size.
/// </summary>
public static IResizeType Fit = new FitResizeType();

/// <summary>
/// Stretches a image to the given size.
/// </summary>
public static IResizeType Stretched = new StretchedResizeType();

private static int CalcNewHeight(int currentWidth, int currentHeight, int newWidth)
{
float ratio = (float)newWidth / (float)currentWidth;
float newHeight = currentHeight * ratio;

return (int)newHeight;
}

private static int CalcNewWidth(int currentWidth, int currentHeight, int newHeight)
{
float ratio = (float)newHeight / (float)currentHeight;
float newWidth = currentWidth * ratio;

return (int)newWidth;
}

private class FixedHeightResizeType : IResizeType
{
public Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller)
{
int height = newSize.Height;

if (!resizeIfSmaller)
{
if (height > currentSize.Height) height = currentSize.Height;
}

int newWidth = CalcNewWidth(currentSize.Width, currentSize.Height, height);
return new Size(newWidth, height);
}
}

private class FixedWidthResizeType : IResizeType
{
public Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller)
{
int width = newSize.Width;

if (!resizeIfSmaller)
{
if (width > currentSize.Width) width = currentSize.Width;
}

int newHeight = CalcNewHeight(currentSize.Width, currentSize.Height, width);
return new Size(width, newHeight);
}
}

private class FitResizeType : IResizeType
{
public Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller)
{
int width = newSize.Width;
int height = newSize.Height;

int newWidth = currentSize.Width;
int newHeight = currentSize.Height;

if (!resizeIfSmaller) // break, if newSize allready fits in currentSize
if (currentSize.Height < height && currentSize.Width < width)
return new Size(currentSize.Width, currentSize.Height);

if(width != newWidth) // shrink or expand to width
{
newHeight = CalcNewHeight(currentSize.Width, currentSize.Height, width);
newWidth = width;
}
if (newHeight > height) //shrink to fit height, if neccesarry
{
newWidth = CalcNewWidth(newWidth, newHeight, height);
newHeight = height;
}

return new Size(newWidth, newHeight);
}
}

private class StretchedResizeType : IResizeType
{
public Size CalcNewSize(Size currentSize, Size newSize, bool resizeIfSmaller)
{
int w = newSize.Width;
int h = newSize.Height;

if (!resizeIfSmaller)
{
if (w > currentSize.Width) w = currentSize.Width;
if (h > currentSize.Height) h = currentSize.Height;
}

return new Size(w, h);
}
}
}
}

```

# antExec – Executing external processes in Groovy

Groovy is a nice language. I currently use it for writing maven plugins and for doing scripting tasks in the realm of build automation.

Poor mans integration with .NET or other systems is the command-line. Groovy has built-in support for that:

```"myprog".execute()

```

And if you need parameters:

```["cmd", "/C", "cd"].execute()

```

But there are some problems with how to wait for the process and retrieve the streams. Often you just want the output back – and you want to make sure that the command exited with no error.

There is also a ant-integration in groovy. So I wrote a little wrapper that makes using ant’s exec-task feasible:

```mixinAntExec() // has to be called once
// prints the stdout
// if the error code is != 0,
// it throws an exeption with
println ("myprog".antExec())

def result = ["myprog", "/fail"].antExec(false)
println (result.exitValue) // error code
println (result.error) // err out
println (result.text) // std out

```

This script can either be pasted to the bottom, or included on the script path:

```def mixinAntExec() {
String.metaClass.antExec = {failOnError=true -> antExec([delegate], failOnError)}
ArrayList.metaClass.antExec << {failOnError=true -> antExec(delegate, failOnError)}
}

def antExec(command, failOnError=true) {
def commandLiteral = command.collect{it.contains(' ') ? '"' + it + '"' : it}.join(' ')

println "ant exec with: \${commandLiteral}"

def ant = new AntBuilder()
ant.exec(outputproperty:"text",
errorproperty: "error",
resultproperty: "exitValue",
failonerror: false,
executable: command) {
if (command.size()>1)
arg(line:command[1..-1].collect{it.contains(' ') ? '"' + it + '"' : it}.join(' '))
}

def result = new Expando(
text: ant.project.properties.text,
error: ant.project.properties.error,
exitValue: ant.project.properties.exitValue as Integer,
toString: {text}
)

if (failOnError && result.exitValue != 0){
throw new Exception("""command failed with \${result.exitValue}
executed: \${commandLiteral}
error: \${result.error}
text: \${result.text}""")

}

return result
}

```