Image resizing ninjitsu

by Jesse 30. September 2008 07:10

System.Drawing.Images has this cool method, GetThumbnailImage which sounds promising on paper until you use it -- then its a disappointment.  It takes a straight int value, which is whatever you come up with, plug it in and bam, you got an image ...that doesn't follow aspect ratio or anything that you might consider useful.  Well, I think there should be an overload on this method, one that DOES keep that aspect ratio, so I created one.  I'm sure others have, but oh well, I like mine.

First off, I came up with a number that was acceptable to handle an image that was big enough to even bother with -- 320x240 is TV resolution, so I thought that was a good start.  I also came up with a number of 100x100 for a good thumbnail size, but those are treated as maximum values, so no resulting value will exceed 100 in either width or height.  I determined finding a percentage was the best way to get this value right, everytime, regardless of how large the image is.  If you take the largest value, divide it out to get a percentage, there's no possible way the other value will exceed 100.  The formula, if you will, ends up being percent = (Desired Size) / (Largest Value) -- I'm off to start setting this up.  Also, other code will determine that the origional file meets our needs -- its larger than any thumbnail we will make and write up some code to do this...

System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(upload1.FileContent);
int width, height;
if (bmp.Height > 320 || bmp.Width > 240)
{ }
else
{
    width = bmp.Width;
    height = bmp.Height;
}

Remember again our thumbnail's desired size is 100x100 max, so technically we could say bmp.Height > 100 and bmp.width > 100 but for practicality purposes, 320x240 is good enough.  Now we need a bit of code to determine percentage.  Note that int will NOT fit the bill on this, so I picked float.  It's precise enough for what we want to accomplish, and leads me to the following method.

private float DeterminePercentageForResize(int height, int width)
{
     int highestValue;
     if (height > width)
         
highestValue = height;
    
else
         
highestValue = width;

     float percent = 100 / (float)highestValue;

     if (percent > 1 && percent != 0)
          
throw new Exception("Percent cannot be greater than 1 or equal to zero");
    
else 
          return percent;
}

the line that says float percent = 100 / (float)highestValue; is where our 100x100 comes in.  You could pull that out into a constant and change it to whatever you want, as long as it is NOT larger than the original.  We also throw an exception that our percentage cannot be 1 (otherwise, whats the point?) and 0 (multiply by 0 == 0, also meaningless and will probably make me angry).  I now have a float value which is actually desireable, because we need to multiply our percentage by the width/height of the original image ... 

{
float percent = DeterminePercentageForResize(bmp.Height, bmp.Width);

float floatWidth = (float)bmp.Width * percent;
float floatHeight = (float)bmp.Height * percent;

width = Convert.ToInt32(floatWidth);
height = Convert.ToInt32(floatHeight);
}

now we pass over our newly created integers into width/height as such ...

System.Drawing.Image thumb = bmp.GetThumbnailImage(width, height, thumbcall, IntPtr.Zero);
thumb.Save(FileLocation + upload1.FileName);

final code looks something like this... (reference reasons, "thumbnailcallback" comes from MSDN from one of their examples)

private void MakeMeAGoodThumbnail()
{

System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(upload1.FileContent);
int width, height;
if (bmp.Height > 320 || bmp.Width > 240)
{
     float percent = DeterminePercentageForResize(bmp.Height, bmp.Width);

     float floatWidth = (float)bmp.Width * percent; 
     float floatHeight = (float)bmp.Height * percent;

     width = Convert.ToInt32(floatWidth);
     height = Convert.ToInt32(floatHeight);
}

else
{
    width = bmp.Width;
    height = bmp.Height;
}

System.Drawing.Image thumb = bmp.GetThumbnailImage(width, height, thumbcall, IntPtr.Zero);
thumb.Save(FileLocation + upload1.FileName);

}

private float DeterminePercentageForResize(int height, int width)
{
     int highestValue;
     if (height > width)
         
highestValue = height;
    
else
         
highestValue = width;

     float percent = 100 / (float)highestValue;

     if (percent > 1 && percent != 0)
          
throw new Exception("Percent cannot be greater than 1 or equal to zero");
    
else 
          return percent;
}

public bool ThumbnailCallback()
{
     return false;
}

Currently rated 4.5 by 2 people

  • Currently 4.5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags:

.Net

Comments

Add comment


(Will show your Gravatar icon)  

  Country flag

biuquote
  • Comment
  • Preview
Loading



Powered by BlogEngine.NET 1.4.5.0
Theme by Mads Kristensen

About the author

Like the description says, at my core, I'm a scientist and engineer.  I came from humble beginnings on a 486DX2 Packard Hell playing doom2 on IPX to in a small time retail shop and got into hardware (ISO layers FTW!) and it was all downhill from there.  I'm infinitely curious about almost everything and always wanting to know.

Some of the stuff I'm currently into/researching...

Sitefinity

Ninject

Subsonic

Java

Currently working on ...
i did the hundred 
and some extra stuff

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's, their brother nor their dog's view in anyway.  At all.  Ever.

© Copyright 2007-2008