可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am working on to upload and save a thumbnail copy of that image in a thumbnail folder.
I am using following link:
http://weblogs.asp.net/markmcdonnell/archive/2008/03/09/resize-image-before-uploading-to-server.aspx
but
newBMP.Save(directory + "tn_" + filename);
is causing exception "A generic error occurred in GDI+."
I have tried to give permission on folder, also tried to use a new separate bmp object when saving.
Edit:
protected void ResizeAndSave(PropBannerImage objPropBannerImage) { // Create a bitmap of the content of the fileUpload control in memory Bitmap originalBMP = new Bitmap(fuImage.FileContent); // Calculate the new image dimensions int origWidth = originalBMP.Width; int origHeight = originalBMP.Height; int sngRatio = origWidth / origHeight; int thumbWidth = 100; int thumbHeight = thumbWidth / sngRatio; int bannerWidth = 100; int bannerHeight = bannerWidth / sngRatio; // Create a new bitmap which will hold the previous resized bitmap Bitmap thumbBMP = new Bitmap(originalBMP, thumbWidth, thumbHeight); Bitmap bannerBMP = new Bitmap(originalBMP, bannerWidth, bannerHeight); // Create a graphic based on the new bitmap Graphics oGraphics = Graphics.FromImage(thumbBMP); // Set the properties for the new graphic file oGraphics.SmoothingMode = SmoothingMode.AntiAlias; oGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic; // Draw the new graphic based on the resized bitmap oGraphics.DrawImage(originalBMP, 0, 0, thumbWidth, thumbHeight); Bitmap newBitmap = new Bitmap(thumbBMP); thumbBMP.Dispose(); thumbBMP = null; // Save the new graphic file to the server newBitmap.Save("~/image/thumbs/" + "t" + objPropBannerImage.ImageId, ImageFormat.Jpeg); oGraphics = Graphics.FromImage(bannerBMP); // Set the properties for the new graphic file oGraphics.SmoothingMode = SmoothingMode.AntiAlias; oGraphics.InterpolationMode = InterpolationMode.HighQualityBicubic; // Draw the new graphic based on the resized bitmap oGraphics.DrawImage(originalBMP, 0, 0, bannerWidth, bannerHeight); // Save the new graphic file to the server bannerBMP.Save("~/image/" + objPropBannerImage.ImageId + ".jpg"); // Once finished with the bitmap objects, we deallocate them. originalBMP.Dispose(); bannerBMP.Dispose(); oGraphics.Dispose(); }
回答1:
When either a Bitmap object or an Image object is constructed from a file, the file remains locked for the lifetime of the object. As a result, you cannot change an image and save it back to the same file where it originated. http://support.microsoft.com/?id=814675
A generic error occurred in GDI+, JPEG Image to MemoryStream
Image.Save(..) throws a GDI+ exception because the memory stream is closed
http://alperguc.blogspot.in/2008/11/c-generic-error-occurred-in-gdi.html
EDIT:
just writing from memory...
save to an 'intermediary' memory stream, that should work
e.g. try this one - replace
Bitmap newBitmap = new Bitmap(thumbBMP); thumbBMP.Dispose(); thumbBMP = null; newBitmap.Save("~/image/thumbs/" + "t" + objPropBannerImage.ImageId, ImageFormat.Jpeg);
with something like:
string outputFileName = "..."; using (MemoryStream memory = new MemoryStream()) { using (FileStream fs = new FileStream(outputFileName, FileMode.Create, FileAccess.ReadWrite)) { thumbBMP.Save(memory, ImageFormat.Jpeg); byte[] bytes = memory.ToArray(); fs.Write(bytes, 0, bytes.Length); } }
回答2:
This error message is also displayed if the path you pass to Bitmap.Save()
is invalid (folder doesn't exist etc).
回答3:
// Once finished with the bitmap objects, we deallocate them. originalBMP.Dispose(); bannerBMP.Dispose(); oGraphics.Dispose();
This is a programming style that you'll regret sooner or later. Sooner is knocking on the door, you forgot one. You are not disposing newBitmap. Which keeps a lock on the file until the garbage collector runs. If it doesn't run then the second time you try to save to the same file you'll get the klaboom. GDI+ exceptions are too miserable to give a good diagnostic so serious head-scratching ensues. Beyond the thousands of googlable posts that mention this mistake.
Always favor using the using statement. Which never forgets to dispose an object, even if the code throws an exception.
using (var newBitmap = new Bitmap(thumbBMP)) { newBitmap.Save("~/image/thumbs/" + "t" + objPropBannerImage.ImageId, ImageFormat.Jpeg); }
Albeit that it is very unclear why you even create a new bitmap, saving thumbBMP should already be good enough. Anyhoo, give the rest of your disposable objects the same using love.
回答4:
Check your folder's permission where the image is saved Right cLick on folder then go :
Properties > Security > Edit > Add-- select "everyone" and check Allow "Full Control"
回答5:
In my case the bitmap image file already existed in the system drive, so my app threw the error "A Generic error occured in GDI+".
- Verify that the destination folder exists
- Verify that there isn't already a file with the same name in the destination folder
回答6:
I was facing the same issue A generic error occurred in GDI+ on saving while working on MVC app, I was getting this error because I was writing wrong path to save image, I corrected saving path and it worked fine for me.
img1.Save(Server.MapPath("/Upload/test.png", System.Drawing.Imaging.ImageFormat.Png);
回答7:
I got it working using FileStream, get help from these
http://alperguc.blogspot.in/2008/11/c-generic-error-occurred-in-gdi.html http://csharpdotnetfreak.blogspot.com/2010/02/resize-image-upload-ms-sql-database.html
System.Drawing.Image imageToBeResized = System.Drawing.Image.FromStream(fuImage.PostedFile.InputStream); int imageHeight = imageToBeResized.Height; int imageWidth = imageToBeResized.Width; int maxHeight = 240; int maxWidth = 320; imageHeight = (imageHeight * maxWidth) / imageWidth; imageWidth = maxWidth; if (imageHeight > maxHeight) { imageWidth = (imageWidth * maxHeight) / imageHeight; imageHeight = maxHeight; } Bitmap bitmap = new Bitmap(imageToBeResized, imageWidth, imageHeight); System.IO.MemoryStream stream = new MemoryStream(); bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); stream.Position = 0; byte[] image = new byte[stream.Length + 1]; stream.Read(image, 0, image.Length); System.IO.FileStream fs = new System.IO.FileStream(Server.MapPath("~/image/a.jpg"), System.IO.FileMode.Create , System.IO.FileAccess.ReadWrite); fs.Write(image, 0, image.Length);
回答8:
Create folder path image/thumbs on your hard disk => Problem solved!
回答9:
For me it was a permission problem. Somebody removed write permissions on the folder for the user account under which the application was running.
回答10:
I used below logic while saving a .png format. This is to ensure the file is already existing or not.. if exist then saving it by adding 1 in the filename Bitmap btImage = new Bitmap("D:\\Oldfoldername\\filename.png"); string path="D:\\Newfoldername\\filename.png"; int Count=0; if (System.IO.File.Exists(path)) { do { path = "D:\\Newfoldername\\filename"+"_"+ ++Count + ".png"; } while (System.IO.File.Exists(path)); } btImage.Save(path, System.Drawing.Imaging.ImageFormat.Png);
回答11:
I encountered this error while trying to convert Tiff images to Jpeg. For me the issue stemmed from the tiff dimensions being too large. Anything up to around 62000 pixels was fine, anything above this size produced the error.
回答12:
I always check/test these:
- Does the path + filename contain illegal characters for the given filesystem?
- Does the file already exist? (Bad)
- Does the path already exist? (Good)
- If the path is relative: am I expecting it in the right parent directory (mostly
bin/Debug
;-) )? - Is the path writable for the program and as which user does it run? (Services can be tricky here!)
- Does the full path really, really not contain illegal chars? (some unicode chars are close to invisible)
I never had any problems with Bitmap.Save()
apart from this list.
回答13:
for me it was a path issue when saving the image.
int count = Directory.EnumerateFiles(System.Web.HttpContext.Current.Server.MapPath("~/images/savedimages"), "*").Count(); var img = Base64ToImage(imgRaw); string path = "images/savedimages/upImages" + (count + 1) + ".png"; img.Save(Path.Combine(System.Web.HttpContext.Current.Server.MapPath(path))); return path;
So I fixed it by adding the following forward slash
String path = "images/savedimages....
should be
String path = "/images/savedimages....
Hope that helps anyone stuck!