English 中文(简体)
How to thumbnail faster in c#
原标题:

I m trying to thumb an image as fast as possible regardless of the usage of resources to be used in my ImageList and listview and this is currently how i m doing it but it seems to be slow:

public Image toThumbs(string file, int width, int height)
        {
            image = null;
            aspectRatio = 1;
            fullSizeImg = null;
            try
            {
                fullSizeImg = Image.FromFile(file);
                float w = fullSizeImg.Width;
                float h = fullSizeImg.Height;
                aspectRatio = w / h;

                int xp = width;
                int yp = height;

                if (fullSizeImg.Width > width && fullSizeImg.Height > height)
                {
                    if ((float)xp / yp > aspectRatio)
                    {
                        xp = (int)(yp * aspectRatio);
                    }
                    else
                    {
                        yp = (int)(xp / aspectRatio);
                    }
                }
                else if (fullSizeImg.Width != 0 && fullSizeImg.Height != 0)
                {
                    xp = fullSizeImg.Width;
                    yp = fullSizeImg.Height;
                }

                image = new Bitmap(width, height);
                graphics = Graphics.FromImage(image);
                graphics.FillRectangle(Brushes.White, ((width - xp) / 2), (height - yp), xp, yp);
                graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
                graphics.DrawImage(fullSizeImg, new Rectangle(((width - xp) / 2), (height - yp), xp, yp));
                graphics.Dispose();
                fullSizeImg.Dispose();
            }
            catch (Exception)
            {
                image = null;
            }
            return image;
        }

I m not sure if the computation is the one that is slowing down the thumbnailing or maybe the classes itself that are being used are slow, if that is the case then what other alternatives can be use maybe a different computation or i need to import other classes or is there a third party libraries that can be used or i need to do a dll import or something? Please help me.

Edit: Just found a solution here http://www.vbforums.com/showthread.php?t=342386 it extracts a thumbnail from a file without reading the whole file. I was able to reduce the time about 40% when i used this.

问题回答

Your calculations happen in fractions of a second. The call to DrawImage is most likely the slowest part of this (as that one is doing the scaling).

If you re needing this thumbnail image exactly once then I don t see much room for improvement here. If you re calling that method on the same image more than once, you should cache the thumbnails.

I use this mechanism which seems to be very fast.

               BitmapFrame bi = BitmapFrame.Create(new Uri(value.ToString()), BitmapCreateOptions.DelayCreation, BitmapCacheOption.OnDemand);

            // If this is a photo there should be a thumbnail image, this is VERY fast
            if (bi.Thumbnail != null)
            {
                return bi.Thumbnail;
            }
            else
            {
                // No thumbnail so make our own (Not so fast)
                BitmapImage bi2 = new BitmapImage();
                bi2.BeginInit();
                bi2.DecodePixelWidth = 100;
                bi2.CacheOption = BitmapCacheOption.OnLoad;
                bi2.UriSource = new Uri(value.ToString());
                bi2.EndInit();
                return bi2;
            }

Hope this helps.

Out of curiosity, have you tried the GetThumbnailImage method on System.Drawing.Bitmap? It might at least be worth comparing to your current implementation.

This may seem like to much of an obvious answer but have you tried just using Image.GetThumbnailImage()?

You don t get as much control over the quality of the result but if speed is your main concern?

Your thumbnail extraction that gets you the big speed up relies on the image having a thumbnail already embedded in it.

To speed up the original you might find that changing:-

graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;

to

graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.Low;

Might help.





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签