How to tackle the Out Of Memory Exception Error? - c#

I have created a button where it can upload all the pic files as well as the doc files and the PDF files in the system.
Here is the code for the following:
if (dlg.ShowDialog() == DialogResult.OK)
{
pictureBox2.Image = Image.FromFile(dlg.FileName);
pictureBox2.SizeMode = PictureBoxSizeMode.Zoom;
currentFileName = dlg.FileName;
button2.Enabled = true;
}
}
But i have a error poping out when i want upload a doc files. First of all is it possible to upload a doc file? if yes, then i have a issues showing out of memory in the following line of code
pictureBox2.Image = Image.FromFile(dlg.FileName);

PictureBox control is used only for showing images in a WinForm application (take a look at MSDN). To show .doc file contents in your application you have to use word or some workaround (like posted here)

The reason why you get that error is because a doc file is not a valid image format.
This is outlined in the documentation: http://msdn.microsoft.com/en-us/library/stf701f5.aspx
it is possible to upload a doc file but not in the context you want, i.e. using Image.FromFile and assign it to a picture box object.

http://msdn.microsoft.com/en-us/library/stf701f5.aspx
Out of Memory exception covered in that topic.
The FromFile method will throw an exception if the file type is invalid.
You should do necessary checks on the file type's compatibility first, not to mention wrap a try catch around this method to ensure you're coding as defensively as possible.

Please take reference at the link from MSDN. It will throw OutOfmemoryException when you loading a picture have not appropriate format.
To resolve your problem you should check format of the picture file more than loading directly as above.
Please reference at here to know how can you detect format of an image file.
To loading PDF or Word document you should take reference here.

Related

Need help, Im trying to compress images [duplicate]

Having a code that works for ages when loading and storing images, I discovered that I have one single image that breaks this code:
const string i1Path = #"c:\my\i1.jpg";
const string i2Path = #"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
i.Save(i2Path, ImageFormat.Jpeg);
The exception is:
System.Runtime.InteropServices.ExternalException occurred
A generic error occurred in GDI+.
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at ...
As far as I can see, there is nothing special about the image. It is approx 250 pixels in size and can be opened in e.g. Windows Image Viewer or Paint.NET:
(Since the image above, after being uploaded to Stack Overflow does not produce the error anymore, I've put the original image here)
What I discovered is that upon calling the Save method, the destination image file is being created with zero bytes.
I am really clueless on what causes the error.
My questions:
Can you think of any special thing that would hinder .NET from saving the image?
Is there any way (beside panicing) to narrow down these kind of errors?
While I still did not find out the reason what exactly caused the error when saving the image, I found a workaround to apply:
const string i1Path = #"c:\my\i1.jpg";
const string i2Path = #"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
var i2 = new Bitmap(i);
i2.Save(i2Path, ImageFormat.Jpeg);
I.e. by copying the image internally into a Bitmap instance and saving this image instead of the original image, the error disappeared.
I'm assuming that by copying it, the erroneous parts the caused the original Save call to fail are being removed an/or normalized, thus enabling the save operation to succeed.
Interestingly, the so stored image has a smaller file on disk (16 kB) than its original source (26 kB).
First of all make sure, that the desired folder has Read/Write permissions. Changing the permissions solved this problem for me.
Solution is here, you must dispose image object to release the memory on the server.
Try use using statement. Make sure destination directory on server exists too.
The reason may be that the image is loaded lazily and the loading process is not yet finished when you try to save it.
Following what's said in this blog post (assuming you're German by the picture you linked in your question) provides a possible solution. Also this SO question's accepted answer indicates this is due to the fact the image file you're trying to save to is locked.
EDIT
For Ulysses Alves, from the linked blog entry: If you load an image using Image.FromFile() it remains locked until it is disposed of. This prevents calls to Save().
pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
pictureBox1.Image.Save("C:\\test\\test2.jpg");
The above code throws an error.
To make it work, you need to copy the image. The following code works:
pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
Image copy = pictureBox1.Image;
copy.Save("C:\\test\\test2.jpg")
I found this question because I also faced the similar error and the file was actually created with zero length (if you don't see any file, first check the permissions to write into folder as other answers suggest). Although my code was slightly different (I use stream to read the image from memory, not from file), I think my answer may be helpful to anyone facing similar problem.
It may looks counter-intuitive, but you can't really dispose memory stream until you finish with image.
NOT WORKING:
Image patternImage;
using (var ms = new MemoryStream(patternBytes)) {
patternImage = new Bitmap(ms);
}
patternImage.Save(patternFile, ImageFormat.Jpeg);
Just don't dispose the stream until you done with image.
WORKS:
using (var ms = new MemoryStream(patternBytes)) {
patternImage = new Bitmap(ms);
patternImage.Save(patternFile, ImageFormat.Jpeg);
}
What is misleading:
Error message doesn't really tell you anything
You can see the image properties, like width and height, but can't
save it
my solution was to make, write temp content (File.WriteAllText) just before saving the file
Here is the code:
var i = Image.FromFile(i1Path);
File.WriteAllText(i2Path, "empty"); // <---- magic goes here
i.Save(i2Path, ImageFormat.Jpeg);
Please try and let me know
In my case I have accidentally deleted the directory where image was getting stored.
Key Information:
// Using System.Drawing.Imaging:
new Bitmap(image).Save(memoryStream, ImageFormat.Jpeg);
You MUST Cast the Image to a Bitmap to Save it.
Using:
// Using System.Drawing.Imaging:
image.Save(memoryStream, ImageFormat.Jpeg);
WILL throw the Error:
Generic GDI+ error when saving an image
Just use the visual studio as administrator or run the application created by the code as administrator it should work smoothly.
It is user access rights issue.
I faced the same and resolved it by running visual studio as administrator.
In my case, I set validateImageData to false:
Image.FromStream(stream, validateImageData: false);
solution:
Image.FromStream(stream, validateImageData: true);
Open in the program
const string i1Path = #"c:\my\i1.jpg";
const string i2Path = #"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
i.Save(i2Path, ImageFormat.Jpeg);
i.Dispose();

PieChart.SaveImage(path,imageFormate) show exception on saving image 2nd time

I am using Chart Control of .NET 4.0 framework in Windows Forms Application i have been saving Pie Chart image on location through PieChart.SaveImage(Path,ChartImageFormat.Png), when i create doc file with Microsoft.Office.Interop.Word i paste that image in that document. it proceed first time very well and .doc created successfully, but i try to save pie chart 2nd time during win forms Running it give an System.IO.Exception
"The process cannot access the file 'path' because it is being used by
another process."
When i terminate program and run it again it over wright previous image but when i want to save image 2nd time during program running it gives same Exception
This is how i am saving image
private Void SavePieChart()
{
string PieChartPath= Application.StartupPath + #"\Chart.png";
PieChart.SaveImage(PieChartPath, ChartImageFormat.Png);
}
I searched, but did not find any efficient solution which solve my problem,
If anything doing wrong Kindly Point out my mistake, or any helping link to solve this. .
EDIT 1
This is where I am pasting that image in Doc file
System.Drawing.Image PieChart =System.Drawing.Image.FromFile(PieChartPath);
oHeader1 = oDoc.Content.Paragraphs.Add(ref oMissing);
Logothread = new Thread(() => Clipboard.SetImage(PieChart));
Logothread.SetApartmentState(ApartmentState.STA); //Set the thread to STA
Logothread.Start();
Logothread.Join();
oHeader1.Range.Paste();
oHeader1.Range.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphCenter;
oHeader1.Range.InsertParagraphAfter();
Thanks in advance
Problem is when i wast pasting image in doc file i was take image like
System.Drawing.Image PieChart =System.Drawing.Image.FromFile(PieChartPath);
as Reza and Taw described FromFile() keeps the file in use so that's why when i try to save image 2nd time it shows exception the file is already in process,
The i use FromStram() add this into my code
byte[] DataBytes= System.IO.File.ReadAllBytes(PieChartPath);
System.IO.MemoryStream ms = new System.IO.MemoryStream(DataBytes);
System.Drawing.Image PieChart = System.Drawing.Image.FromStream(ms);

How can i load image to pictureBox from string array the last index file?

I tried this:
string[] files = System.IO.Directory.GetFiles(combinedsatelliteimagesdir);
NumericComparer ns = new NumericComparer();
Array.Sort(files, ns);
pictureBox1.Image = Image.FromFile(files[files.Length -1]);
But i'm getting out of memory exception on the line:
pictureBox1.Image = Image.FromFile(files[files.Length -1]);
the variable files contain 847 indexs for example the first index look like:
C:\Users\user\AppData\Local\mws\My Weather Station\satelliteImages\SatImage0.GIF
From msdn, you get OutOfMemoryException if
The file does not have a valid image format.
-or-
GDI+ does not support the pixel format of the file.
You probably reading some non-image file.
Regarding thumbs.db:
Thumbs.db is an image cache which makes thumbnail viewing faster. The file is automatically created in Windows Vista, 7 and 8 whenever images are encountered in a folder. It's usually hidden but can appear, disappear and is often impossible to delete
try this one
pictureBox1.Image = Image.FromFile(#files[files.Length - 1]);
By the way, are you sure that last file is every time a picture? No hidden "desktop.ini" or something else?

How to find reason for Generic GDI+ error when saving an image?

Having a code that works for ages when loading and storing images, I discovered that I have one single image that breaks this code:
const string i1Path = #"c:\my\i1.jpg";
const string i2Path = #"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
i.Save(i2Path, ImageFormat.Jpeg);
The exception is:
System.Runtime.InteropServices.ExternalException occurred
A generic error occurred in GDI+.
at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(String filename, ImageFormat format)
at ...
As far as I can see, there is nothing special about the image. It is approx 250 pixels in size and can be opened in e.g. Windows Image Viewer or Paint.NET:
(Since the image above, after being uploaded to Stack Overflow does not produce the error anymore, I've put the original image here)
What I discovered is that upon calling the Save method, the destination image file is being created with zero bytes.
I am really clueless on what causes the error.
My questions:
Can you think of any special thing that would hinder .NET from saving the image?
Is there any way (beside panicing) to narrow down these kind of errors?
While I still did not find out the reason what exactly caused the error when saving the image, I found a workaround to apply:
const string i1Path = #"c:\my\i1.jpg";
const string i2Path = #"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
var i2 = new Bitmap(i);
i2.Save(i2Path, ImageFormat.Jpeg);
I.e. by copying the image internally into a Bitmap instance and saving this image instead of the original image, the error disappeared.
I'm assuming that by copying it, the erroneous parts the caused the original Save call to fail are being removed an/or normalized, thus enabling the save operation to succeed.
Interestingly, the so stored image has a smaller file on disk (16 kB) than its original source (26 kB).
First of all make sure, that the desired folder has Read/Write permissions. Changing the permissions solved this problem for me.
Solution is here, you must dispose image object to release the memory on the server.
Try use using statement. Make sure destination directory on server exists too.
The reason may be that the image is loaded lazily and the loading process is not yet finished when you try to save it.
Following what's said in this blog post (assuming you're German by the picture you linked in your question) provides a possible solution. Also this SO question's accepted answer indicates this is due to the fact the image file you're trying to save to is locked.
EDIT
For Ulysses Alves, from the linked blog entry: If you load an image using Image.FromFile() it remains locked until it is disposed of. This prevents calls to Save().
pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
pictureBox1.Image.Save("C:\\test\\test2.jpg");
The above code throws an error.
To make it work, you need to copy the image. The following code works:
pictureBox1.Image = Image.FromFile("C:\\test\\test1.jpg");
Image copy = pictureBox1.Image;
copy.Save("C:\\test\\test2.jpg")
I found this question because I also faced the similar error and the file was actually created with zero length (if you don't see any file, first check the permissions to write into folder as other answers suggest). Although my code was slightly different (I use stream to read the image from memory, not from file), I think my answer may be helpful to anyone facing similar problem.
It may looks counter-intuitive, but you can't really dispose memory stream until you finish with image.
NOT WORKING:
Image patternImage;
using (var ms = new MemoryStream(patternBytes)) {
patternImage = new Bitmap(ms);
}
patternImage.Save(patternFile, ImageFormat.Jpeg);
Just don't dispose the stream until you done with image.
WORKS:
using (var ms = new MemoryStream(patternBytes)) {
patternImage = new Bitmap(ms);
patternImage.Save(patternFile, ImageFormat.Jpeg);
}
What is misleading:
Error message doesn't really tell you anything
You can see the image properties, like width and height, but can't
save it
my solution was to make, write temp content (File.WriteAllText) just before saving the file
Here is the code:
var i = Image.FromFile(i1Path);
File.WriteAllText(i2Path, "empty"); // <---- magic goes here
i.Save(i2Path, ImageFormat.Jpeg);
Please try and let me know
In my case I have accidentally deleted the directory where image was getting stored.
Key Information:
// Using System.Drawing.Imaging:
new Bitmap(image).Save(memoryStream, ImageFormat.Jpeg);
You MUST Cast the Image to a Bitmap to Save it.
Using:
// Using System.Drawing.Imaging:
image.Save(memoryStream, ImageFormat.Jpeg);
WILL throw the Error:
Generic GDI+ error when saving an image
Just use the visual studio as administrator or run the application created by the code as administrator it should work smoothly.
It is user access rights issue.
I faced the same and resolved it by running visual studio as administrator.
In my case, I set validateImageData to false:
Image.FromStream(stream, validateImageData: false);
solution:
Image.FromStream(stream, validateImageData: true);
Open in the program
const string i1Path = #"c:\my\i1.jpg";
const string i2Path = #"c:\my\i2.jpg";
var i = Image.FromFile(i1Path);
i.Save(i2Path, ImageFormat.Jpeg);
i.Dispose();

Implementing IDisposable in File.Delete method?

I want to delete a file on my computer but the app throws an exception that The directory is busy. My first thought is to implement a dispose method in my class which does a file delete.
Knows anybody how to do this?
It's actually a Picturebox which displays a image and if you click on a button beside the image you can remove it, thus deleting it. It's propably that which blocks my filepath.
picobx.Image = Image.FromFile(//path)
Is there any solution to this?
PS. I want to dispose the resource so that I can delete...
do like this:
File.Delete(// path )
The Image.FromFile method actually locks the file thats why you can't delete it. The best would be to read the image as a byte array using bytes = File.ReadBytes(filename), create a memorystream from the byte array, pass the memory stream to Image.FromStream to display the image and then delete it with the button click.
OK - I see what you are tring to do.
Image itself implements IDisposable. You don't need to implement IDisposable yourself, you just have to make sure you either call Dispose on your image, or use the "using" syntax.
The problem is that until the image - the returned reference from Image.FromFile(//path) - is disposed of, it still locks the underlying file so you will always get the exception "The process cannot access the file"
What you intend to do is the following, I suppose:
try {
File.Delete(yourFile);
}
catch (IOException ex) {
// Do something with the exception here, like showing the user that the file can't be deleted)
}
A file that i.e. is in use or in an directory with insufficient rights can't be deleted. So if you get an error, you should look why the file is in use / not accessible, whatever.
Based on your edit, I suggest to do the following:
Image myImage = Image.FromFile(//path);
picobx.Image = myImage;
//click button
picobx.Image = null;
myImage.Dispose();
File.Delete(//path);
As you have suggested you will need to dispose of the image before you can delete it something like this:
Image i = this.pictureBox1.Image;
this.pictureBox1.Image = null;
i.Dispose();
File.Delete(filePath);
Edit I posted this without reading his new edit: I see you're using Image.FromFile.
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're going to have to dispose of the Image before you can delete it.
Image.FromFile
The file remains locked until the Image is disposed.
private Image image;
in your image load function:
image = Image.FromFile("path");
picobx.Image = image;
this goes in your delete method;
image.Dispose;
File.Delete("path");
--- No longer relevant ---
If you're reading the file from a stream and converting the stream to an image. Then you try and delete the file without closing the stream you will get an IOException.
System.IO.IOException: The process cannot access the file 'File Here' because it is being used by another process..
and example of what could be causing this
StreamReader file = new StreamReader(#"C:\trans.txt");
file.ReadToEnd();
File.Delete(#"C:\trans.txt");

Categories

Resources