.NET isotropic image drawing
Does anyone have an idea of how to resize an image isotropically? Meaning I give it a set width/height, and the image is scaled to fit at it's same proportions withi开发者_如何学Gon that box, even if there is whitespace around it?
found it:
public Image ResizeIsotropic(Image src, Size sz)
{
double d1 = sz.Width / (double)sz.Height;
double d2 = src.Width / (double)src.Height;
if (d1 > d2)
{
src = ResizeByHeight(src, sz.Height);
}
else
{
src = ResizeByWidth(src, sz.Width);
}
Image rtn = null;
using (Image thumbnail = new Bitmap(sz.Width, sz.Height, PixelFormat.Format32bppArgb))
{
using (Graphics graphic = System.Drawing.Graphics.FromImage(thumbnail))
{
graphic.FillRectangle(Brushes.White, 0, 0, sz.Width, sz.Height);
graphic.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphic.SmoothingMode = SmoothingMode.HighQuality;
graphic.PixelOffsetMode = PixelOffsetMode.HighQuality;
graphic.CompositingQuality = CompositingQuality.HighQuality;
graphic.DrawImage(src, (sz.Width - src.Width)/2, (sz.Height - src.Height)/2, src.Width, src.Height);
EncoderParameters encoderParameters;
encoderParameters = new EncoderParameters(1);
ImageCodecInfo jpginfo = GetImageCodecInfo(ImageFormat.Jpeg);
encoderParameters.Param[0] = new EncoderParameter(Encoder.Quality, Quality);
MemoryStream ms = new MemoryStream();
thumbnail.Save(ms, jpginfo, encoderParameters);
rtn = Image.FromStream(ms);
}
}
theImage = rtn;
return rtn;
}
private ImageCodecInfo GetImageCodecInfo(ImageFormat format)
{
ImageCodecInfo[] info = ImageCodecInfo.GetImageEncoders();
ImageCodecInfo jpginfo = null;
foreach (ImageCodecInfo i in info)
{
if (i.FormatID == format.Guid)
{
jpginfo = i;
break;
}
}
return jpginfo;
}
the ResizeByWidth and ResizeByHeight functions are other parts of a library i have, they do exactly what you'd think they do.
here are the results:
alt text http://imagebin.antiyes.com/images/0626614001263432575_87.jpg
Yes. First calculate the size so that the width fits in the box. Then check if the calculated height is larger than the box, in that case you calculate the size so that the height fits in the box instead.
While I believe John Boker's answer to be sufficient, this may be a more concise method of doing this:
static Bitmap ResizeIsotropic(Image img, Size newSize, Color backgroundColor)
{
int Width, Height;
if (img.Width >= img.Height)
{
Width = newSize.Width;
Height = (int)(img.Height / (img.Width / Width));
}
else
{
Height = newSize.Height;
Width = (int)(img.Width / (img.Height / Height));
}
Bitmap bmp = new Bitmap(newSize.Width, newSize.Height);
using (Graphics gfx = Graphics.FromImage(bmp))
{
gfx.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
gfx.Clear(backgroundColor);
gfx.DrawImage(img, (bmp.Width / 2) - (Width / 2), (bmp.Height / 2) - (Height / 2), Width, Height);
}
return bmp;
}
Then, to call it simply do:
Bitmap bmp = ResizeIsotropic(Image.FromFile(@"c:\yourImage.jpg"), new Size(512, 512), Color.Black);
bmp.Save(@"c:\test.bmp");
精彩评论