Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create thumbnails of images and store them in cache

I have a WPF application that has a list box of images. Right now I am using BitmapImage and BitmapCacheOption.OnLoad to load the images.

The problem is that when there are a lot of images, the RAM usage sky rockets due to the size of the images.

How can I create thumbnail images of the originals to display in the list box?

It probably has to be cached since the image files in the directory may be deleted or modified while the application is running.

like image 510
MBU Avatar asked Dec 31 '10 00:12

MBU


People also ask

How do I create a thumbnail cache?

In the Pool, right-click the video file and select Generate Thumbnail Cache. In the Project window, right-click the video event, and select Media > Generate Thumbnail Cache.

What is a thumbnail cache file?

These thumbnail cache files help Windows display thumbnails instantly without delay. In Windows 10, thumbnail cache files are stored under C:\Users\UserName \AppData\Local\Microsoft\Windows\Explorer.

Should images be cached?

Generally yes, images should be cached in at least memory, and depending on your app (how likely is it to be reused,etc) in memory and storage. If you want to support your 3rd point (displaying when offline), you need to do storage caching, and memory caching is optional but probably a good idea.

What are thumbnails for images?

A thumbnail is a small image representation of a larger image, usually intended to make it easier and faster to look at or manage a group of larger images. Graphic designers and photographers typically use this term.


2 Answers

The problem is that when there are a lot of images, the RAM usage sky rockets due to the size of the images.

C# example from: http://msdn.microsoft.com/en-us/library/ms748873.aspx

// Create source
BitmapImage myBitmapImage = new BitmapImage();

// BitmapImage.UriSource must be in a BeginInit/EndInit block
myBitmapImage.BeginInit();
myBitmapImage.UriSource = new Uri(@"C:\Water Lilies.jpg");

// To save significant application memory, set the DecodePixelWidth or  
// DecodePixelHeight of the BitmapImage value of the image source to the desired 
// height or width of the rendered image. If you don't do this, the application will 
// cache the image as though it were rendered as its normal size rather then just 
// the size that is displayed.
// Note: In order to preserve aspect ratio, set DecodePixelWidth
// or DecodePixelHeight but not both.
myBitmapImage.DecodePixelWidth = 200;
myBitmapImage.EndInit();
//
//when you are ready to render the BitmapImage, do:
imageThumb.Source = myBitmapImage;

Note the DecodePixelWidth and DecodePixelHeight properties to cache the image at the desired reduced pixel size. Use both to stretch the image to fit the thumbnail size.

like image 81
Dan Randolph Avatar answered Sep 25 '22 03:09

Dan Randolph


You can create decent thumb bitmaps using InterpolationMode.HighQualityBicubic

   Bitmap bitmap = ...
   Bitmap thumbBitmap = new System.Drawing.Bitmap(thumbWidth, thumbHeight);
   using (Graphics g = Graphics.FromImage(thumbBitmap))
   {
      g.InterpolationMode = InterpolationMode.HighQualityBicubic;
      g.DrawImage(bitmap, 0, 0, thumbWidth, thumbHeight);
   }

If you are creating the thumbs in a background thread just save them into a memory stream which you can then lazily use to create the BitmapImage when requested:

   _ms = new MemoryStream();
   thumbBitmap.Save(_ms, ImageFormat.Png);
   _ms.Position = 0;
   ImageLoaded = true;


    //thumb image property of this class, use in binding  
    public BitmapImage ThumbImage
    {
        get
        {
            if (_thumbImage == null && ImageLoaded)
            {
                BitmapImage bi = new BitmapImage();
                bi.BeginInit();
                bi.StreamSource = _ms;
                bi.EndInit();
                _thumbImage = bi;
            }
            return _thumbImage;
        }
    }
like image 33
BrokenGlass Avatar answered Sep 26 '22 03:09

BrokenGlass