3

The following line throws an OutOfMemoryException when loading a large image

System.Drawing.Image img = System.Drawing.Image.FromFile(filepath);

I tried with a 8280x6208 8,76 MB image file and lots of other smaller images, that works fine.

But when I try with a 10328x7760 6,44 MB image file, it throws the OutOfMemoryException.

I also tried opening the file in photoshop and save it with worse quality (1,32 MB), but with the same dimensions, it throws the OutOfMemoryException.

I tried upscaling another smaller image to 10328x7760 and that throws the OutOfMemoryException too.

So I'm pretty sure it's an actual out of memory problem and my question is:

Can I increase the memory somehow?

I'm using Windows 8.1 64 bit with 8GB RAM, Visual Studio 2013 with IIS Express. It's a Web Application project.

EDIT: I don't think it's a format issue as suggested, I tried with a 10000x10000 black image and a 5000x5000 black image. The 10000 throws OOM, the 5000 don't.

brian
  • 31
  • 1
  • 4
  • @AshkanMobayenKhiabani: What form? He never mentioned a form... – Ian Apr 02 '15 at 15:52
  • OOM with an 1.32mb image on a system with reasonable free resources is likely a file/pixel format issue (as is documented to happen in such cases) – Alex K. Apr 02 '15 at 15:53
  • 10328x7760 is still only 76MB of raw ARGB values. Something else must be up. Can you reduce the problem to a short snippet that you can post here so we can try to reproduce it? – Cameron Apr 02 '15 at 15:53
  • @Ashkan Mobayen Khiabani It's a ASP.NET Web Application project – brian Apr 02 '15 at 15:55
  • @edtheprogrammerguy So I guess I should look into changing the pixel format? – brian Apr 02 '15 at 16:01
  • @brian - I tried your code in Visual Studio 2012 on Windows 8.1 with a .jpg of 10000x10000 (size is 1.5 MB) and also with a .png of the same dimensions (398k). In neither case did the code throw an exception. Both loaded without problem. What is your image file format? I did get the exception, however with a 20000x20000 .png (1.5 MB) – edtheprogrammerguy Apr 02 '15 at 17:34
  • @edtheprogrammerguy it's .jpg – brian Apr 02 '15 at 17:43

3 Answers3

3

Compile it as "Any CPU" and untick the "Prefer 32-bit" in Visual studio solution build configuration.

It's not that you don't have memory, it's that .NET application runs as 32-bit process by default, and it does not have enough memory.

Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • 2
    I doubt the 76MB that the image takes uncopmressed is causing the application to exceed the ~3.5GB 32-bit limit... – Cameron Apr 02 '15 at 15:54
  • Thank you! This solved my problem! I would never have thought of that... no idea how you arrived at that solution, but I love you for it non the less! – pookie Sep 18 '16 at 19:28
3

From In the Image.FromFile documentation we can read that :

If the file does not have a valid image format or if GDI+ does not support the pixel format of the file, this method throws an OutOfMemoryException exception.

You might want to try to use alternative method Image.FromStream. You shouldn't get the exception

var fs = new FileStream(filepath, FileMode.Open, FileAccess.Read)
var img = Image.FromStream(fs)
fs.Dispose()
Tomasz Jaskuλa
  • 15,723
  • 5
  • 46
  • 73
  • But I tried upscaling another smaller image (that didn't throw the exception before) to 10328x7760 and that throws the oom exception. The format should be the same when I just resize and image in photoshop, right? – brian Apr 02 '15 at 16:22
  • I tried your method, it also throws OOM Exception on var img = Image.FromStream(fs) – brian Apr 02 '15 at 16:30
  • 1
    Strange, have you tried to pass another argument like that `var img = Image.FromStream(fs, true)` it means that it applies color correction according to color management information that is embedded in the data stream. Do you get the exception when debugging step by step ? Also when you use `img` after `fs.Dispose()` you can get OOM Ex – Tomasz Jaskuλa Apr 02 '15 at 16:39
  • Nope doesn't work, I just tested with a complete black image at 10.000x10.000 and a 5.000x5.000 also complete black image. The one with 10k throws OOM exception the 5k doesn't. – brian Apr 02 '15 at 16:45
  • Ok, I'll look into it and get back – Tomasz Jaskuλa Apr 02 '15 at 16:47
0

I was able to get it to load into a System.Windows.Controls.Image object with the following code.

            Stream imageStreamSource = new FileStream("largeImage.jpg", FileMode.Open, FileAccess.Read, FileShare.Read);               
            JpegBitmapDecoder decoder = new JpegBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
            BitmapSource bitmapSource = decoder.Frames[0];
            System.Windows.Controls.Image myImage = new System.Windows.Controls.Image();
            myImage.Source = bitmapSource;

Don't forget to Dispose the Stream when you are done with it.

edtheprogrammerguy
  • 5,957
  • 6
  • 28
  • 47