Search code examples
c#windows-8

Is there a way to keep a png/jpg image from being converted to a bitmap image


I'm making a C#/WPF/Windows 8 App store app and I'm trying to load up some PNGs/JPGs to display them in view. The images are all reasonably high resolution, but the file sizes are normally only around 200k or so. The problem is that when I load them up using the BitmapImage class (which is the only one I can find) the total memory used jumps up to 100s of megs. From what I can tell it takes the png/jpb and converts it to a bitmap image, which massively increases the memory usage. So far I haven't found a way around this, although it seems like there should be a simple solution.

Is there something really obvious I'm missing?

My code below

private async Task TestFunction(IReadOnlyList<StorageFile> files)
{
  var images = new ObservableCollection<Image>();
  imagePanel.ItemsSource = coverImages;
  foreach (var file in files)
  {

    var bitmap = new BitmapImage();
    var item = await file.OpenAsync(FileAccessMode.Read);
    bitmap.SetSource(item);
    var image = new Image();
    image.Source = bitmap;
    image.Height = 200;

    images.Add(image);
  }
}

Solution

  • If the image on disk is in compressed format (and most image file formats use some form of compression), the in-memory footprint will be larger.

    If the image is 100x100 pixels in size and uses 8bits for colour depth, the raw data for that image would take up 100x100=10,000 bytes and that's the amount of data that has to be rendered to the screen.

    If your looking for a way to reduce memorty usage in your WPF application there are a few option you can try.

    1. Don't cache the images in memory, or selecting the best time to load the images, using the BitmapCacheOption e.g: bitmap.CacheOption = BitmapCacheOption.None this will fill the image as needed from disk, if the images are only 200k the performance drop should not be too bad, but it will not be as fast as caching

    2. Make sure you not rendering images bigger than they need to be, If the Element you are displaying the image on is 200x200 and the image is 1024x768 you can set the DecodePixelWidth, this will create the Bitmap to the size you define instead of its actual size. e.g: bitmap.DecodePixelWidth = 200