GDI+ exception when saving image in PNG format - c#

An ASP.NET application on my server starts throwing GDI+ exception after running for several days. After I restart the server, all works fine for a couple of days and then suddenly this exception occurs again. After the first time it occurs, it occurs every time I try to save a PNG image, until I restart again.
When I try to save the image in JPEG, it works fine.
When I run this code from my project, it fails:
var path = #"C:\Project\images\logo.png";
var image = Image.FromFile(path);
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png); // Fails here on GDI+ exception.
//image.Save(ms, ImageFormat.Jpeg); // JPEG works somehow
}
Again: When I restart remote desktop and run this code, it works for a couple of days and at some moment suddenly starts to fail over and over.
I tried:
To make a console application with the same code and run it in the RDP where the project is. It worked fine!
Lots of different variations of codes that were suggested in more then 10 articles I read on this topic.
GCI.Collect() – no help.
Checked all the folders that has write permissions (maybe there is something with the IIS?).
More.
I think that it should be some configuration that suddenly changes due to something and I can’t understand what can it be.

After I restart the server all works fine for a couple of days and then suddenly this exception occurs and after the first time it occurs it will occur everytime I try to save the PNG image, until I will restart again.
Sounds like a memory leak to me. What .NET version is this compiled to? What server OS this running on?
You can start by enclosing your image in a using block:
var path = #"C:\Project\images\logo.png";
using (Image image = Image.FromFile(path))
{
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png);
}
}
This link I believe is relevant to your case.

It throw GDI+ error because one of your object not disposed, so better dispose used object.
If you are getting that error , then I can say that your application doesn't have a write permission on some directory.
GDI+ limits the height of an image to 65534
Always favor using the using statement. Which never forgets to dispose an object, even if the code throws an exception.
var path = #"C:\Project\images\logo.png";
using (Image image = Image.FromFile(path))
{
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png); //fails here on GDI+ exception.
//image.Save(ms, ImageFormat.Jpeg); //Jpeg Works somehow
}
}
The FromFile method locks the file, so use the Image.FromStream() method for reading the image:
byte[] bytes = System.IO.File.ReadAllBytes(filename);
System.IO.MemoryStream ms = new System.IO.MemoryStream(bytes);
using (var ms = new MemoryStream())
{
image.Save(ms, ImageFormat.Png); //fails here on GDI+ exception.
//image.Save(ms, ImageFormat.Jpeg); //Jpeg Works somehow
}

Basically, if you have disposable objects... Dispose them !
Image is disposable and as bitmap does, it uses windows resources.
If you do not dispose, the windows resources are not freed till you shut down your application. So you need to dispose any image instantiated.

Related

ReadTimeout exception with MemoryStream

The following method throws this exception
System.IO.Stream)(ms)).ReadTimeout threw an exception of type
System.InvalidOperationException'
This is the method:
private static byte[] ImageToByteArraybyMemoryStream(Bitmap bmp)
{
using (MemoryStream ms = new MemoryStream()) {
bmp.Save(ms, bmp.RawFormat);
return ms.ToArray();
}
}
however, this error doesn't occur all the time. I'll try to explain in short what happens:
I load a bitmap from a file, display it and store it in Dictionary<int,Bitmap>
When application is closed, i write bitmap to apps config-file as byte[] (and there's no exception)
On start of app i load bitmap from config-file and display it
When user changes application-data (like resizing or moving the bitmap) i rewrite the config-file the same way as i did when bitmap was loaded from file and this exception occurs.
i just googled "generic gdi+ error" others also got a problem with the bmp.Save Method. the workaround for them is to create a new Bitmap from the one you wanna save and then save this copy.
...
Bitmap copy = new Bitmap(bmp);
copy.Save(ms, copy.RawfFormat);
...
Maybe this also works for you, i can not tell you the reason for this error, its reffered to as a bug on other sites.
Other Post discussing this Problem
I faced this issue and it took a while to understand that, the object that uploaded the image did not release its located memory and lock it! and the garbage collection didn't dispose of that object, therefore the API could not stream the image.
somehow it works for the first time then it will raise the error.
Solution:
I used HttpPostFileBase to upload the image, and after it has done I set it to null
and that's it!

Loading saved byte array to memory stream causes out of memory exception

At some point in my program the user selects a bitmap to use as the background image of a Panel object. When the user does this, the program immediately draws the panel with the background image and everything works fine. When the user clicks "Save", the following code saves the bitmap to a DataTable object.
MyDataSet.MyDataTableRow myDataRow = MyDataSet.MyDataTableRow.NewMyDataTableRow(); //has a byte[] column named BackgroundImageByteArray
using (MemoryStream stream = new MemoryStream())
{
this.Panel.BackgroundImage.Save(stream, ImageFormat.Bmp);
myDataRow.BackgroundImageByteArray = stream.ToArray();
}
Everything works fine, there is no out of memory exception with this stream, even though it contains all the image bytes. However, when the application launches and loads saved data, the following code throws an Out of Memory Exception:
using (MemoryStream stream = new MemoryStream(myDataRow.BackGroundImageByteArray))
{
this.Panel.BackgroundImage = Image.FromStream(stream);
}
The streams are the same length. I don't understand how one throws an out of memory exception and the other doesn't. How can I load this bitmap?
P.S. I've also tried
using (MemoryStream stream = new MemoryStream(myDataRow.BackgroundImageByteArray.Length))
{
stream.Write(myDataRow.BackgroundImageByteArray, 0, myDataRow.BackgroundImageByteArray.Length); //throw OoM exception here.
}
The issue I think is here:
myDataRow.BackgroundImageByteArray = stream.ToArray();
Stream.ToArray() . Be advised, this will convert the stream to an array of bytes with length = stream.Length. Stream.Legnth is size of the buffer of the stream, which is going to be larger than the actual data that is loaded into it. You can solve this by using Stream.ReadByte() in a while loop until it returns a -1, indicating the end of the data within the stream.
You might give this library a look.
http://arraysegments.codeplex.com/
Project Description
Lightweight extension methods for ArraySegment, particularly useful for byte arrays.
Supports .NET 4.0 (client and full), .NET 4.5, Metro/WinRT, Silverlight 4 and 5, Windows Phone 7 and 7.5, all portable library profiles, and XBox.

how i can save image in picturebox without generic error [duplicate]

This seems to be a bit of an infamous error all over the web. So much so that I have been unable to find an answer to my problem as my scenario doesn't fit. An exception gets thrown when I save the image to the stream.
Weirdly this works perfectly with a png but gives the above error with jpg and gif which is rather confusing.
Most similar problem out there relate to saving images to files without permissions. Ironically the solution is to use a memory stream as I am doing....
public static byte[] ConvertImageToByteArray(Image imageToConvert)
{
using (var ms = new MemoryStream())
{
ImageFormat format;
switch (imageToConvert.MimeType())
{
case "image/png":
format = ImageFormat.Png;
break;
case "image/gif":
format = ImageFormat.Gif;
break;
default:
format = ImageFormat.Jpeg;
break;
}
imageToConvert.Save(ms, format);
return ms.ToArray();
}
}
More detail to the exception. The reason this causes so many issues is the lack of explanation :(
System.Runtime.InteropServices.ExternalException was unhandled by user code
Message="A generic error occurred in GDI+."
Source="System.Drawing"
ErrorCode=-2147467259
StackTrace:
at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams)
at System.Drawing.Image.Save(Stream stream, ImageFormat format)
at Caldoo.Infrastructure.PhotoEditor.ConvertImageToByteArray(Image imageToConvert) in C:\Users\Ian\SVN\Caldoo\Caldoo.Coordinator\PhotoEditor.cs:line 139
at Caldoo.Web.Controllers.PictureController.Croppable() in C:\Users\Ian\SVN\Caldoo\Caldoo.Web\Controllers\PictureController.cs:line 132
at lambda_method(ExecutionScope , ControllerBase , Object[] )
at System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters)
at System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters)
at System.Web.Mvc.ControllerActionInvoker.<>c__DisplayClassa.<InvokeActionMethodWithFilters>b__7()
at System.Web.Mvc.ControllerActionInvoker.InvokeActionMethodFilter(IActionFilter filter, ActionExecutingContext preContext, Func`1 continuation)
InnerException:
OK things I have tried so far.
Cloning the image and working on that.
Retrieving the encoder for that MIME passing that with jpeg quality setting.
OK I seem to have found the cause just by sheer luck and its nothing wrong with that particular method, it's further back up the call stack.
Earlier I resize the image and as part of that method I return the resized object as follows. I have inserted two calls to the above method and a direct save to a file.
// At this point the new bitmap has no MimeType
// Need to output to memory stream
using (var m = new MemoryStream())
{
dst.Save(m, format);
var img = Image.FromStream(m);
//TEST
img.Save("C:\\test.jpg");
var bytes = PhotoEditor.ConvertImageToByteArray(img);
return img;
}
It appears that the memory stream that the object was created on has to be open at the time the object is saved. I am not sure why this is. Is anyone able to enlighten me and how I can get around this.
I only return from a stream because after using the resize code similar to this the destination file has an unknown mime type (img.RawFormat.Guid) and Id like the Mime type to be correct on all image objects as it makes it hard write generic handling code otherwise.
EDIT
This didn't come up in my initial search but here's the answer from Jon Skeet
If you are getting that error , then I can say that your application doesn't have a write permission on some directory.
For example, if you are trying to save the Image from the memory stream to the file system , you may get that error.
Please if you are using XP, make sure to add write permission for the aspnet account on that folder.
If you are using windows server (2003,2008) or Vista, make sure that add write permission for the Network service account.
Hope it help some one.
I'll add this cause of the error as well in hopes it helps some future internet traveler. :)
GDI+ limits the maximum height of an image to 65500
We do some basic image resizing, but in resizing we try to maintain aspect ratio. We have a QA guy who's a little too good at this job; he decided to test this with a ONE pixel wide photo that was 480 pixels tall. When the image was scaled to meet our dimensions, the height was north of 68,000 pixels and our app exploded with A generic error occurred in GDI+.
You can verify this yourself with test:
int width = 480;
var height = UInt16.MaxValue - 36; //succeeds at 65499, 65500
try
{
while(true)
{
var image = new Bitmap(width, height);
using(MemoryStream ms = new MemoryStream())
{
//error will throw from here
image.Save(ms, ImageFormat.Jpeg);
}
height += 1;
}
}
catch(Exception ex)
{
//explodes at 65501 with "A generic error occurred in GDI+."
}
It's too bad there's not a friendly .net ArgumentException thrown in the constructor of Bitmap.
This article explains in detail what exactly happens: Bitmap and Image constructor dependencies
In short, for a lifetime of an Image constructed from a stream, the stream must not be destroyed.
So, instead of
using (var strm = new ... ) {
myImage = Image.FromStream(strm);
}
try this
Stream imageStream;
...
imageStream = new ...;
myImage = Image.FromStream(strm);
and close imageStream at the form close or web page close.
You'll also get this exception if you try to save to an invalid path or if there's a permissions issue.
If you're not 100% sure that the file path is available and permissions are correct then try writing a to a text file. This takes just a few seconds to rule out what would be a very simple fix.
var img = System.Drawing.Image.FromStream(incomingStream);
// img.Save(path);
System.IO.File.WriteAllText(path, "Testing valid path & permissions.");
And don't forget to clean up your file.
Save image to bitmap variable
using (var ms = new MemoryStream())
{
Bitmap bmp = new Bitmap(imageToConvert);
bmp.Save(ms, format);
return ms.ToArray();
}
Just in case if someone is doing as stupid stuff as I was.
1. make sure path does exist.
2. make sure you have permissions to write.
3. make sure your path is correct, in my case I was missing file name in the TargetPath :(
it should have said, your path sucks than "A generic error occurred in GDI+"
I also got this error when saving JPEGs, but only for certain images.
My final code:
try
{
img.SaveJpeg(tmpFile, quality); // This is always successful for say image1.jpg, but always throws the GDI+ exception for image2.jpg
}
catch (Exception ex)
{
// Try HU's method: Convert it to a Bitmap first
img = new Bitmap(img);
img.SaveJpeg(tmpFile, quality); // This is always successful
}
I didn't create the images so I can't tell what the difference is.
I'd appreciate if anyone could explain that.
This is my SaveJpeg function just FYI:
private static void SaveJpeg(this Image img, string filename, int quality)
{
EncoderParameter qualityParam = new EncoderParameter(Encoder.Quality, (long)quality);
ImageCodecInfo jpegCodec = GetEncoderInfo("image/jpeg");
EncoderParameters encoderParams = new EncoderParameters(1);
encoderParams.Param[0] = qualityParam;
img.Save(filename, jpegCodec, encoderParams);
}
private static ImageCodecInfo GetEncoderInfo(string mimeType)
{
var encoders = ImageCodecInfo.GetImageEncoders();
var encoder = encoders.SingleOrDefault(c => string.Equals(c.MimeType, mimeType, StringComparison.InvariantCultureIgnoreCase));
if (encoder == null) throw new Exception($"Encoder not found for mime type {mimeType}");
return encoder;
}
I found that if one of the parent folders where I was saving the file had a trailing space then GDI+ would throw the generic exception.
In other words, if I tried to save to "C:\Documents and Settings\myusername\Local Settings\Temp\ABC DEF M1 Trended Values \Images\picture.png" then it threw the generic exception.
My folder name was being generated from a file name that happened to have a trailing space so it was easy to .Trim() that and move on.
if your code is as follows then also this error occurs
private Image GetImage(byte[] byteArray)
{
using (var stream = new MemoryStream(byteArray))
{
return Image.FromStream(stream);
}
}
The correct one is
private Image GetImage(byte[] byteArray)
{
var stream = new MemoryStream(byteArray))
return Image.FromStream(stream);
}
This may be because we are returning from the using block
Had a very similar problem and also tried cloning the image which doesn't work. I found that the best solution was to create a new Bitmap object from the image that was loaded from the memory stream. That way the stream can be disposed of e.g.
using (var m = new MemoryStream())
{
var img = new Bitmap(Image.FromStream(m));
return img;
}
Hope this helps.
This is an expansion / qualification of Fred's response which stated: "GDI limits the height of an image to 65534". We ran into this issue with one of our .NET applications, and having seen the post, our outsourcing team raised their hands in the air and said they couldn't fix the problem without major changes.
Based on my testing, it's possible to create / manipulate images with a height larger than 65534, but the issue arises when saving to a stream or file IN CERTAIN FORMATS. In the following code, the t.Save() method call throws our friend the generic exception when the pixel height is 65501 for me. For reasons of curiosity, I repeated the test for width, and the same limit applied to saving.
for (int i = 65498; i <= 100000; i++)
{
using (Bitmap t = new Bitmap(800, i))
using (Graphics gBmp = Graphics.FromImage(t))
{
Color green = Color.FromArgb(0x40, 0, 0xff, 0);
using (Brush greenBrush = new SolidBrush(green))
{
// draw a green rectangle to the bitmap in memory
gBmp.FillRectangle(greenBrush, 0, 0, 799, i);
if (File.Exists("c:\\temp\\i.jpg"))
{
File.Delete("c:\\temp\\i.jpg");
}
t.Save("c:\\temp\\i.jpg", ImageFormat.Jpeg);
}
}
GC.Collect();
}
The same error also occurs if you write to a memory stream.
To get round it, you can repeat the above code and substitute ImageFormat.Tiff or ImageFormat.Bmp for ImageFormat.Jpeg.
This runs up to heights / widths of 100,000 for me - I didn't test the limits. As it happens .Tiff was a viable option for us.
BE WARNED
The in memory TIFF streams / files consume more memory than their JPG counterparts.
Error occurring because of Permission. make sure folder have ALL THE PERMISSION.
public Image Base64ToImage(string base64String)
{
// Convert Base64 String to byte[]
byte[] imageBytes = Convert.FromBase64String(base64String);
MemoryStream ms = new MemoryStream(imageBytes, 0,
imageBytes.Length);
// Convert byte[] to Image
ms.Write(imageBytes, 0, imageBytes.Length);
Image image = Image.FromStream(ms, true);
return image;
}
img.Save("YOUR PATH TO SAVE IMAGE")
SOLVED - I had this exact problem. The fix, for me, was to up the disk quota for IUSR on the IIS server. In this instance, we have a catalog app with images of items and such. The upload quota for the "Anonymous Web User" was set to 100MB, which is the default for this particular hosting company's IIS servers. I upped it to 400MB and was able to upload images without error.
This might not be your issue, but if it is, it's an easy fix.
In my case the problem was in the path I was saving (the root C:\). Changing it to D:\111\ made the exception go away.
Another cause for this error - the path you indicate in the Save method of the Bitmap instance doesn't exist or you haven't supplied a full / valid path.
Just had this error because I was passing in a filename and not a full path!
It happens!
My turn!
using (System.Drawing.Image img = Bitmap.FromFile(fileName))
{
... do some manipulation of img ...
img.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg);
}
Got it on the .Save... because the using() is holding the file open, so I can't overwrite it. Maybe this will help someone in the future.
Same problem I was facing. But in my case, I was trying to save file in C drive and it was not accessible. So I tried it to save in D drive which was fully accessible and I succeeded.
So first check your folders in which you are trying to save. You must have all (read and write) rights for that particular folder.
Simple, create a new instance of Bitmap solves the problem.
string imagePath = Path.Combine(Environment.CurrentDirectory, $"Bhatti{i}.png");
Bitmap bitmap = new Bitmap(image);
bitmap.Save(imagePath);
I notice that your "jpeg" case is actually:
default:
format = ImageFormat.Jpeg;
break;
Are you sure that the format is jpeg and not something else?
I'd try:
case "image/jpg": // or "image/jpeg" !
format = ImageFormat.Jpeg;
break;
Or check what imageToConvert.MimeType() is actually returning.
UPDATE
Is there any other initialisation you need to do to the MemoryStream object?
I had this issue on a test server but not on the live server.
I was writing the image to a stream, so it wasn't a permission issue.
I'd been directly deploying some of the .dll's to the test server.
Deploying the entire solution fixed the issue, so it was probably a weird compilation mismatch
Just to throw another possible solution on the pile, I'll mention the case I ran into with this error message. The method Bitmap.Save would throw this exception when saving an bitmap I had transformed and was displaying. I discovered it would not throw the exception if the statement had a breakpoint on it, nor would it if the Bitmap.Save was preceeded by Thread.Sleep(500) so I suppose there is some sort of resource contention going on.
Simply copying the image to a new Bitmap object was enough to prevent this exception from appearing:
new Bitmap(oldbitmap).Save(filename);
One other cause of this error and that solve my problème is that your application doesn't have a write permission on some directory.
so to complete the answer of savindra : https://stackoverflow.com/a/7426516/6444829.
Here is how you Grant File Access to IIS_IUSERS
To provide access to an ASP.NET application, you must grant access to the IIs_IUSERS.
To grant read, write, and modify permissions to a specific File or Folder
In Windows Explorer, locate and select the required file.
Right click the file, and then click Properties.
In the Properties dialog box, click the Security tab.
On the Security tab, examine the list of users.
(If your application is running as a Network Service, add the network service account in the list and grant it the permission.
In the Properties dialog box, click IIs_IUSERS, and in the Permissions for NETWORK SERVICE section, select the Read, Write, and Modify permissions.
Click Apply, and then click OK.
this worked for me in my IIS of windows server 2016 and local IIS windows 10.
We had a similar problem on generating a PDF or resize image using ImageProcessor lib on production server.
Recycle the application pool fix the issue.
If you are trying to save an image to a remote location be sure to add the NETWORK_SERVICE user account into the security settings and give that user read and write permissions. Otherwise it is not going to work.
byte[] bts = (byte[])page1.EnhMetaFileBits;
using (var ms = new MemoryStream(bts))
{
var image = System.Drawing.Image.FromStream(ms);
System.Drawing.Image img = image.GetThumbnailImage(200, 260, null, IntPtr.Zero);
img.Save(NewPath, System.Drawing.Imaging.ImageFormat.Png);
}
I also get this error because i'm trying to save images with the same name of previous saved images.
Make sure that you don't save images with duplicate name.
Use for thar for example a 'Random' function (How does C#'s random number generator work?)
or for example generate a Guid (http://betterexplained.com/articles/the-quick-guide-to-guids/)
in my case, path was wrong
just use this
String path = Server.MapPath("~/last_img.png");//Path
For me I was using the Image.Save(Stream, ImageCodecInfo, EncoderParameters) and apparently this was causing the infamous A generic error occurred in GDI+ error.
I was trying to use EncoderParameter to save the jpegs in 100% quality. This was working perfectly on "my machine" (doh!) and not on production.
When I used the Image.Save(Stream, ImageFormat) instead, the error disappeared! So like an idiot I continued to use the latter although it saves them in default quality which I assume is just 50%.
Hope this info helps someone.
I encountered the problem too. The problem was due to the loading stream being disposed. But I did not dispose it, it was inside .Net framework. All I had to do was use:
image_instance = Image.FromFile(file_name);
instead of
image_instance.Load(file_name);
image_instance is of type System.Windows.Forms.PictureBox!
PictureBox's Load() disposes the stream which the image was loaded from, and I did not know that.

A Generic error occurs at GDI+ at Bitmap.Save() after using SaveFileDialog

I use the following code block with some more code inside the using block:
using (System.Drawing.Bitmap tempImg =
(System.Drawing.Bitmap)tempObj.GetData(System.Windows.Forms.DataFormats.Bitmap))
{
// ...
tempImg.Save("..\\..\\testdata\\tempImg.bmp", ImageFormat.Bmp);
// ...
}
But I still get the error:
A Generic Error occured at GDI+
only after I make some action which is not related to the code inside the using block. In other times this works well.
Also the tempImg.bmp is a temporary file, so I delete the tempImg.bmp within the using block itself.
Since the tempImg is inside the using and this it's disposed, I think the locking problem should be solved.
Can someone please let me know what is the mistake in this code?
Edit:
System.Drawing.Image to System.Drawing.Bitmap as the type of tempImg.
Edit:
I have identified I get this error only after SaveFileDialog is created and user clicks on 'Save'.
Finally I could find what was wrong in my code and would like to mention it here as I think it may be useful to someone....
As I have given a relative path in tempImg.Save, and after the user clicks 'Save' in SaveFileDialog, the actual path for tempImg.Save become :
Path specified by SaveFileDialog + the relative path
automatically.
Thus if the path does not exist, this error occurs.
Thanks every one for the answers.
I also had once this problem- it happens because the bitmap locks and you can't save it( if you want I can find the exact explanation) so anyway a fix around is this:
Create a new bitmap the size of the original bitmap you have- copy the original bitmap to the new created bitmap and then dispose the original bitmap and save the new one.
Bitmap bm3 = new Bitmap(bm2);
And then save.
This is usually an indicator that something else, potentially some other thread in your own application, already has the target file that you're trying to save locked at the file system level. If you look at the inner exception I believe it should mention this. If it's not directly in the InnerException Another way to confirm this (or discover what it might really be instead) is to turn on first chance exceptions in the debugger and watch for what exception is being thrown "underneath" Save and then being turned into this generic exception.
Tried all the solutions given here, but in vain. Found the solution eventually.
Dispose any Graphics applied on image: g.dispose();
Make sure save path exists: System.IO.Directory.Exists(dir);
Is this an ASP.NET application?
A Generic Error occured at GDI+ in asp.net mostly because of missing target folder / access permissions.
Also your code could be simplified to :
using (Image image= dataObject.GetImage())
{
if (image != null)
{
image.Save("test.bmp");
}
}
In my case it was an ASP.NET application in which I replaced a single DLL, and I had to simply re-start the application pool after deployment. Then it worked fine.
This is code sample from Microsoft Forums.
// new image with transparent Alpha layer
using (var bitmap = new Bitmap(330, 18, PixelFormat.Format32bppArgb))
{
using (var graphics = Graphics.FromImage(bitmap))
{
// add some anti-aliasing
graphics.SmoothingMode = SmoothingMode.AntiAlias;
using (var font = new Font("Arial", 14.0f, GraphicsUnit.Pixel))
{
using (var brush = new SolidBrush(Color.White))
{
// draw it
graphics.DrawString(user.Email, font, brush, 0, 0);
}
}
}
// setup the response
Response.Clear();
Response.ContentType = "image/png";
Response.BufferOutput = true;
// write it to the output stream
bitmap.Save(Response.OutputStream, ImageFormat.Png);
Response.Flush();
}
I am trying to save image from resource and it gives me too GDI error when I directly use the method Bitmap.Save(filepath).
I think We can use the same below code for any other bitmap image by cloning it.
Private void SaveResourceImage() {
object resBmpObject = Resource.Image1.Clone();//Bitmap Image from resource file
//object resBmpObject = anyBmpImage.clone(); //for image other than resource image
Bitmap resBmpImage = (Bitmap)resBmpObject;
resBmpImage.Save(destFilePath, System.Drawing.Imaging.ImageFormat.Png);
resBmpImage.dispose();
}
Dispose your bitMap object after save image:
bitMap.Dispose()
oimg.Dispose()
bitMap = Nothing
oimg = Nothing
In my case, i was saving the bitmap file on the same location as the source,
So that's the problem.
I save the bitmap to the new location and all fine now.
I was facing the same issue, by changing image type ".bmp" to ".png" its work form me

Handling Corrupted JPEGs in C#

We have a process that pulls images from a remote server. Most of the time, we're good to go, the images are valid, we don't timeout, etc. However, every once and awhile we see this error similar to this:
Unhandled Exception: System.Runtime.InteropServices.ExternalException: A generic
error occurred in GDI+.
at System.Drawing.Image.Save(Stream stream, ImageCodecInfo encoder, EncoderPa
rameters encoderParams)
at ConsoleApplication1.Program.Main(String[] args) in C:\images\ConsoleApplic
ation1\ConsoleApplication1\Program.cs:line 24
After not being able to reproduce it locally, we looked closer at the image, and realized that there were artifacts, making us suspect corruption.
Created an ugly little unit test with only the image in question, and was unable to reproduce the error on Windows 7 as was expected. But after running our unit test on Windows Server 2008, we see this error every time.
Is there a way to specify non-strictness for jpegs when writing them? Some sort of check/fix we can use?
Unit test snippet:
var r = ReadFile("C:\\images\\ConsoleApplication1\\test.jpg");
using (var imgStream = new MemoryStream(r))
{
using (var ms = new MemoryStream())
{
var guid = Guid.NewGuid();
var fileName = "C:\\images\\ConsoleApplication1\\t" + guid + ".jpg";
Image.FromStream(imgStream).Save(ms, ImageFormat.Jpeg);
using (FileStream fs = File.Create(fileName))
{
fs.Write(ms.GetBuffer(), 0, ms.GetBuffer().Length);
}
}
}
AFAIK, no, there is no way to ask GDI+ to be more lenient when decoding JPG files. In any application where you have consumers uploading arbitrary JPG files you will see a number of these Generic error in GDI+ exceptions being thrown all the time. You could try using WPF to read your image instead, but I suspect it too will object to corrupt images.
Maybe it's not answer to your direct question, but why would't you pull image and its md5 (or any other hash) that can verify correctnes of this image?

Categories

Resources