VagabondSW Posted July 10, 2005 Posted July 10, 2005 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. Quote "Never ascribe to malice that which can adequately be explained by incompetence." -- Napolean Bonaparte
Leaders Iceplug Posted July 11, 2005 Leaders Posted July 11, 2005 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) Quote Iceplug, USN One of my coworkers thinks that I believe that drawing bullets is the most efficient way of drawing bullets. Whatever!!! :-(
VagabondSW Posted July 13, 2005 Author Posted July 13, 2005 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. Quote "Never ascribe to malice that which can adequately be explained by incompetence." -- Napolean Bonaparte
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.