Out of Memory Image.Fromfile

out of memory Image.FromFile

In the Image.FromFile documentation, an OutOfMemoryException can be throw if:

The file does not have a valid image format.

-or-

GDI+ does not support the pixel format of the file.

Check your image format.

Also, if you want to close the stream right after loading the image, you must make a copy of the image. Take a look here. GDI+ must keep the stream open for the lifetime of the image.

Out of memory on Image.FromFile

For some reason the watcher triggered the first time when the file had already been unlocked, but the next times the file was still being written, incomplete, which makes the OOM exception to makes sense as

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.

I added a method to check every 100ms if the file is unlocked.

Other thing I just noticed, it throw the exception when I copy the file and not when I move it.

Out Of Memory exception on System.Drawing.Image.FromFile()

It's worth knowing that OutOfMemoryException doesn't always really mean it's out of memory - particularly not when dealing with files. I believe it can also happen if you run out of handles for some reason.

Are you disposing of all your bitmaps after you're done with them? Does this happen repeatably for a single image?

System.Drawing.Image.FromFile System.OutOfMemoryException: Out of memory.

This seemed to fix my issue as it doesn't hold a reference to it this way.

using (var memoryStream = new MemoryStream(File.ReadAllBytes(path)))
{
using (var image = Image.FromStream(memoryStream))
{

byte[] bytes;



using (var memoryStream1 = new MemoryStream())
{
image.Save(memoryStream1, GetImageFormat(Path.GetExtension(path)));
bytes = memoryStream1.ToArray();
}


}
}
}

private ImageFormat GetImageFormat(string extension)
{
switch (extension.ToLower())
{
case ".png":
return ImageFormat.Png;
default:
return ImageFormat.Jpeg;
}
}

Out of memory on loading a Image with System.Drawing.Image

Is this C#? I think the answer may be here.

out of memory Image.FromFile

Top Answer from user: https://stackoverflow.com/users/31158/jordao

In the Image.FromFile documentation, an OutOfMemoryException can be throw if:

The file does not have a valid image format.


-or-


GDI+ does not support the pixel format of the file.


Check your image format.

Also, if you want to close the stream right after loading the image, you must make a copy of the image. Take a look here. GDI+ must keep the stream open for the lifetime of the image.

Another top answer and thread to consider then:

Out Of Memory exception on System.Drawing.Image.FromFile()

From user: https://stackoverflow.com/users/22656/jon-skeet

It's worth knowing that OutOfMemoryException doesn't always really mean it's out of memory - particularly not when dealing with files. I believe it can also happen if you run out of handles for some reason.

Are you disposing of all your bitmaps after you're done with them? Does this happen repeatably for a single image?

Also, I would add- have you saved this file out using your code and tried to view it in another image viewer? It may be corrupt if it is being created incorrectly.

Out Of Memory with Image.FromFile without stream

web.DownloadFileAsync(imageUrl, fileName); downloads in the background, so you have to wait for it to finish before trying to open the picture. You can subscribe to the OnDownloadFileCompleted event to know when the download is finished.

An alternative is just to replace with a synchronous download:

web.DownloadFile(imageUrl, fileName);

However, if you execute that from the main thread, you will freeze the UI while the picture is downloading. So, use with care.

c# Out of Memory Exception with System.Drawing.Image


Issue

You are building an object

  using (System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(sOriginalPath, true))

Then you are returning it...but it is already disposed of...you need to not dispose of the object by unwrapping it with a using...whatever consumes this will need to dispose of the object.

Other Issue

bitmap is also a memory leak and needs to be wrapped with a using or dispose called implicitly.


Final Function Example

public System.Drawing.Image GetImage(string sOriginalPath, string sLogoPath)
{
System.Drawing.Image imgOriginal = System.Drawing.Image.FromFile(sOriginalPath, true);
using (System.Drawing.Image imgLogo = System.Drawing.Image.FromFile(sLogoPath, true)) //This is where it throws the exception
{
using (Graphics gra = Graphics.FromImage(imgOriginal))
{
using(Bitmap bmLogo = new Bitmap(imgLogo))
{
int nWidth = bmLogo.Size.Width;
int nHeight = bmLogo.Size.Height;
int nLeft = (imgOriginal.Width / 2) - (nWidth / 2);
int nTop = (imgOriginal.Height / 2) - (nHeight / 2);
gra.DrawImage(bmLogo, nLeft, nTop, nWidth, nHeight);
}
}
}
return imgOriginal;
}

Example Console App Demo

I've tested the below and it worked as expected.

using System.Drawing;

namespace SO_Test
{
class Program
{
static void Main(string[] args)
{
using(Image newImage = GetImage("C:\\Users\\username\\Pictures\\image.png", "C:\\Users\\username\\Pictures\\watermark.jpg"))
{
newImage.Save("C:\\Users\\username\\Pictures\\newImage.png");
}
}

static Image GetImage(string sOriginalPath, string sLogoPath)
{
Image imgOriginal = Image.FromFile(sOriginalPath, true);
using (Image imgLogo = Image.FromFile(sLogoPath, true)) //This is where it throws the exception
{
using (Graphics gra = Graphics.FromImage(imgOriginal))
{
using (Bitmap bmLogo = new Bitmap(imgLogo))
{
int nWidth = bmLogo.Size.Width;
int nHeight = bmLogo.Size.Height;
int nLeft = (imgOriginal.Width/2) - (nWidth/2);
int nTop = (imgOriginal.Height/2) - (nHeight/2);
gra.DrawImage(bmLogo, nLeft, nTop, nWidth, nHeight);
}
}
}
return imgOriginal;
}
}
}

Is there a reason Image.FromFile throws an OutOfMemoryException for an invalid image format?

No, it is history. GDI+ was written quite a while before .NET ever came around. The SDK wrapper for it was written in C++. Exceptions are iffy in C++, not everybody buys into them. Google doesn't for example. So to keep it compatible it reports problems with error codes. That just never scales well, library programmers make it a goal to intentionally limit the number of possible error codes, it lessen the burden on the client programmer having to report them.

GDI+ has this problem in spades, it defines only 20 error codes. That is not much for such a large chunk of code with so many external dependencies. Which in itself is a problem, there are a gazillion ways to mess up an image file. No way that a library's error reporting can be fine-grained enough to cover them all. The fact that these error codes were picked long before .NET defined standard Exception derived types certainly didn't help.

The Status::OutOfMemory error code got overloaded to mean different things. Sometimes it really does mean out of memory, it can't allocate enough space to store the bitmap bits. Sadly, an image file format problem is reported by the same error code. The friction here is that it cannot possibly decide if the width * height * pixels it read from the image file is a problem because there isn't enough storage available for the bitmap. Or if the data in the image file is junk. It assumes that image file is not junk, fair call, that's another program's problem. So OOM is what it reports.

For completeness, these are the error codes:

enum Status
{
Ok = 0,
GenericError = 1,
InvalidParameter = 2,
OutOfMemory = 3,
ObjectBusy = 4,
InsufficientBuffer = 5,
NotImplemented = 6,
Win32Error = 7,
WrongState = 8,
Aborted = 9,
FileNotFound = 10,
ValueOverflow = 11,
AccessDenied = 12,
UnknownImageFormat = 13,
FontFamilyNotFound = 14,
FontStyleNotFound = 15,
NotTrueTypeFont = 16,
UnsupportedGdiplusVersion = 17,
GdiplusNotInitialized = 18,
PropertyNotFound = 19,
PropertyNotSupported = 20,
#if (GDIPVER >= 0x0110)
ProfileNotFound = 21,
#endif //(GDIPVER >= 0x0110)
};


Related Topics



Leave a reply



Submit