Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

I have a ListView displaying thumbnails created from the original images using the System.Drawing.Image.GetThumbnailImage method.

System.Drawing.Bitmap thumbnail = getThumbnail(original, imgList.ImageSize.Width, imgList.ImageSize.Height);

I implemented some private methods that preserve the image proportions in the thumbnail, just like the Windows Thubmnail view. However, unlike the Windows Thumbnails, my thumbnails are top-justified, rather than centered. Here is a cropped screenshot comparing the Windows Thumbnails (top) to my thumbnails (bottom):

 

http://home.san.rr.com/vagabondia/images/tmp/sample_v2.gif

 

In fact, it appears as if my 96h x 96w Bitmap is not part of my image despite my use of the Graphics.DrawImage method. The 96h x 96w dimension is determined by the ImageList.ImageSize height and width, respectively. However, passing those dimensions directly to the Image.GetThumbnailImage method causes non-square images to be distorted. So, I attempt to preserve the aspect ratio of the original image in the thumbnail.

private Bitmap getThumbnail(System.Drawing.Image img, int imgWidth, int imgHeight)
{
 decimal aspectRatio = getAspectRatio(img.Height, img.Width);
 int thumbWidth = imgWidth;
 int thumbHeight = imgHeight;

 if (img.Width > img.Height && img.Width != img.Height)
   thumbHeight = Convert.ToInt32(imgHeight * aspectRatio);
 else
   thumbWidth = Convert.ToInt32(imgWidth * aspectRatio);

 Image.GetThumbnailImageAbort thumbCallback = new Image.GetThumbnailImageAbort(thumbnailCallback);
 Image thumb = (Bitmap) img.GetThumbnailImage(thumbWidth, thumbHeight, thumbCallback, IntPtr.Zero);

 return thumb;
}

My getAspectRatio method is a simple one line routine that returns a decimal.

private decimal getAspectRatio(int imgHeight, int imgWidth)
{
 decimal aspectRatio = (decimal) System.Math.Min(imgHeight, imgWidth) / System.Math.Max(imgHeight, imgWidth);
 return aspectRatio;
}

The real problem seems to be when I attempt to draw my proportional thumbnail onto a 'blank' Bitmap with the same dimensions as the ImageList.ImageSize. This step does not appear to be happening correctly, or it is not producing the desired Windows-like thumbnail result.

private Bitmap preserveAspectRatio(int imgHeight, int imgWidth, System.Drawing.Image img)
{
 Bitmap bmpImage = new Bitmap(imgWidth, imgHeight);
 int xoffset = 0;
 int yoffset = 0;

 if (img.Width > img.Height)
   yoffset = getOffset(bmpImage.Height, img.Width);
 else
   xoffset = getOffset(bmpImage.Width, img.Height) + img.Height;

 Graphics grafix = Graphics.FromImage(bmpImage);
 grafix.DrawImage(img, xoffset, yoffset, img.Width, img.Height);
 return bmpImage;
}

My getOffset method is a simple one line routine that returns an integer.

private int getOffset(int max, int actual)
{
 int offset = (max - actual) / 2;
 return offset;
}

I thought my preserveAspectRatio routine would draw my proportional thumbnail onto the square bitmap to create a 'centered' proportional image, just like the Windows Thumbnail view. Apparently, there is something I'm not doing correctly.

 

Any help or suggestions would be greatly appreciated.

"Never ascribe to malice that which can adequately be explained by incompetence." -- Napolean Bonaparte
  • Leaders
Posted

PreserveAspectRatio(100, 50, someimagethatis200by100):

bmpImage is 100x50.

yoffset = GetOffset(50, 200) or 75.

And then draws the 200x100 image onto the 100x50 bitmap at 0,75... so

the image is clipped...

 

PreserveAspectRatio(400, 200, someimagethatis100by50):

bmpImage is 400x200.

yoffset = GetOffset(200, 100) that's 50.

And then draws the image onto the 200x100 bitmap at 0, 50

 

First of all:

grafix.DrawImage(img, xoffset, yoffset, img.Width, img.Height);

is the same as

grafix.DrawImage(img, xoffset, yoffset);

 

if (img.Width > img.Height && img.Width != img.Height)

is the same as

if (img.Width > img.Height)

 

On a more conceptual note, why aren't you changing the size of the image when you scale it?

If you are just trying to center the picture in the middle without scaling it, then you should just do GetOffset for both the widths and the heights:

xoffset = getOffset(bmpWidth, imgWidth)

yoffset = getOffset(bmpHeight, imgHeight)

Iceplug, USN

One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(

Posted

Thanks for the reply. When I went back to work (where I can only use Visual Basic.NET) and started implementing this code, I realized how bass-ackwards I was on tracking images and their respective sizes. Right now, I'm back on the data layer, but should be returning to the images later in the week.

 

Speaking of that, you wouldn't happen to know how to handle multipage tiffs, would you? I only need to display and print existing multipage tiff files. I don't need to create them or change the existing ones in any way.

 

Any tips are greatly appreciated.

"Never ascribe to malice that which can adequately be explained by incompetence." -- Napolean Bonaparte

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...