1

I'm trying to load some 20 images in my WPF application. Only the first image loads completely. Other images are loading partially. When i used breakpoint to debug i tried to load each image after 2 seconds and that worked well.

Code

Images will be loaded like,

foreach (string path in ImagesCollection)
   {
      DisplayImage = LoadImage(path);
   }

Load image method,

 MemoryStream mem;

 if (!string.IsNullOrEmpty(path) && (File.Exists(path)))
     {

         FileInfo ImageFile = new FileInfo(path);
         ImageFile.Refresh();
         if (mem != null)
           {
              mem.Dispose();
           }
         using (var stream = ImageFile.OpenRead())
            {
               mem = new MemoryStream();

               stream.CopyTo(mem);

            }
         mem.Position = 0;
         ImageFrame = BitmapFrame.Create(mem);

     }

Screenshot:

enter image description here

I believe Dispose or a new instance makes the image doesn't load. Kindly help.

A Coder
  • 3,039
  • 7
  • 58
  • 129
  • 1
    Is there any reason why you're not using `BitmapFrame.Create(new Uri(path))` without all the stream copying? – Clemens Aug 05 '16 at 07:08
  • @Clemens No, the image is loaded at multiple places and there is also a edit and save functionality in MS paint . using the `new Uri(path)` throws `Access violation error`? Not sure. – A Coder Aug 05 '16 at 07:18
  • @HenkHolterman Could you please reform that? – A Coder Aug 05 '16 at 07:18
  • BitmapFrame.Create(stream) loads asynchronously, and the memorystream gets to be destroyed because going out of scope before the loading completes. One way out is to use the OnLoad cache option. (in stead of the default OnDemand). Use BitmapFrame.Create(mem, BitmapCreateOptions.None, BitmapCacheOptions.OnLoad) – oreubens Aug 05 '16 at 07:54
  • @oreubens This creates me `Out of memory exception` frequently when i try to load a image file of size >5Mb. – A Coder Aug 05 '16 at 08:03
  • @Clemens, the reason for the memory stream is he needs to release the file locks on the file stream – MikeT Aug 05 '16 at 12:04

1 Answers1

1

The documentation for BitmapFrame.Create state "The bitmapStream can be closed after the frame is created only when the OnLoad cache option is used. The default OnDemand cache option retains the stream until the frame is needed"

This means you cannot re-use the MemoryStream once you've passed it to the BitmapFrame. This is the source of the error.

For efficiency just pass the FileStream. Load image method

if (!string.IsNullOrEmpty(path) && (File.Exists(path)))
{

    var stream = ImageFile.OpenRead())
    ImageFrame = BitmapFrame.Create(stream);
}
PhillipH
  • 6,182
  • 1
  • 15
  • 25
  • This creates me `Out of memory exception` frequently when i try to load a image file of size >5Mb. – A Coder Aug 05 '16 at 10:07
  • Then I suggest you pass the FileStream of the image into the BitmapFrame.Create. By reading it into a MemoryStream you are creating unnecessary memory pressure. The ImageFrame will cache for performance for you. – PhillipH Aug 05 '16 at 10:20
  • Don't the stream want to be closed or disposed? Will this create memory leaks anywhere? Or is that okay to use the `BitmapFrame` inside a `using`? – A Coder Aug 05 '16 at 11:18
  • Please consult the documentation on the use of BitmapFrame.Create() to find out how and when you close the Stream you have passed in. For efficiency the BitmapFrame doesn't immediately read your stream. – PhillipH Aug 05 '16 at 11:27
  • Thanks, Since i get `Sharing violation error` during the edit of an image and `Out of memory exception` during my load, i'm bit confused with the code. This answer gives me `Sharing violation error` during the save of an image – A Coder Aug 05 '16 at 11:29
  • Ok - this is a different question - your code doesn't indicate any kind of editing. Please post as a different problem. – PhillipH Aug 05 '16 at 11:31