Recently, I encountered a problem in Image Scaling. When I saved the scaled image as png, the following error occurs:
A generic error occurred in GDI +.
Description:
An unhandled exception occurred during the execution of the current web
Request. Please review the stack trace for more information about the error and
Where it originated in the code.
Exception Details:
System. Runtime. InteropServices. ExternalException: A generic error occurred
In GDI +.
Source Error:
Line 42: catch (Exception ex) Line 43: { Line 44: throw ex; Line 45: } Line 46: finally |
No message is provided for this exception. For some reason, ex. InnerException is null. It seems that MS hides the specific exception from us.
My code:
1 ...........
2 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
3 g.DrawImage(bitmap, 0, 0, originWidth, originHeight);
4
5 try
6 {
7 bitmap.Save(stream, ImageFormat.Png);
8 }
9 catch (Exception ex)
10 {
11 throw ex;
12 }
13 finally
14 {
15 bitmap.Dispose();
16 g.Dispose();
17 originImg.Dispose();
18 }
Because I directly output the image to outputstream in a handler (this is the root cause of the problem ). Problem: At first, I thought it was the reason why bitmap was locked and it could not be saved. So I used a temporary bitmap for the transition. See the specific code:
Bitmap tempBitmap = new Bitmap (originImage );
Bitmap bitmap = new Bitmap (tempBitmap );
// Release the temporary bitmap and save it again
TempBitmap. Dispose ();
Bitmap. Save (bitmap, 0, 0, width, height)
This method is not effective. I also thought about the permission issue and the result was also ruled out!
If it is not saved as PNG, try other formats. Of course, when it is changed to Jpeg format, you will find that the image can be output normally. This must have something to do with the image format. I found something:
Png's are a special case. Their encoder requires a bi-directional
Stream. The solution is to stream to a memory stream first and write
The contents of that memory stream to OutputStream afterwards.
Generally, a two-way stream is required for the PNG decoder. The solution is to write data to the memeory stream first, and then write the memory stream to the outputstream.
We know Response. outputStream is a one-way stream that cannot read data back (the CanSeek attribute of MS is false). It may be that png needs to write data back during decoding, because the CanSeek attribute is false, all data cannot be written back, which leads to this problem.
Use MemoryStream for transfer
using (MemoryStream ms =new MemoryStream())
{
bitmap.Save(ms,ImageFormat.Png);
ms.WriteTo(stream);
}
Proportional scaling code:
private Size GetNewSize(int originWidth, int originHeight, int toWidth, int toHeight)
{
int w, h;
if ((double)originWidth / (double)toWidth < (double)originHeight / (double)toHeight)
{
h = toHeight;
w = originWidth * toHeight / originHeight;
}
else
{
w = toWidth;
h = originHeight * toWidth / originWidth ;
}
return new Size(w, h);
}
To solve the problem, you must locate the problem step by step and try to solve it again!