C# Bitmap.Save 方法中的 GDI+ 中发生一般错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15862810/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 18:11:57  来源:igfitidea点击:

A Generic error occurred in GDI+ in Bitmap.Save method

c#gdi+system.drawing

提问by donstack

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

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+."

导致异常“GDI+ 中发生一般错误。”

I have tried to give permission on folder, also tried to use a new separate bmp object when saving.

我曾尝试授予文件夹权限,也尝试在保存时使用新的单独 bmp 对象。

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();
    }

采纳答案by NSGaga-mostly-inactive

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

从文件构造 Bitmap 对象或 Image 对象时,该文件在对象的生命周期内保持锁定状态。因此,您无法更改图像并将其保存回其来源的同一文件。 http://support.microsoft.com/?id=814675

A generic error occurred in GDI+, JPEG Image to MemoryStream

GDI+, JPEG Image to MemoryStream 中发生一般错误

Image.Save(..) throws a GDI+ exception because the memory stream is closed

Image.Save(..) 抛出 GDI+ 异常,因为内存流已关闭

http://alperguc.blogspot.in/2008/11/c-generic-error-occurred-in-gdi.html

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);
    }
}

回答by Hans Passant

    // 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.

这是一种您迟早会后悔的编程风格。快敲门了,你忘记了。您没有处理newBitmap。在垃圾收集器运行之前,它会一直锁定文件。如果它没有运行,那么您第二次尝试保存到同一个文件时,您将获得 klaboom。GDI+ 异常太悲惨了,无法给出一个很好的诊断结果,因此会引起严重的头疼。除了提到这个错误的数以千计的谷歌搜索帖子之外。

Alwaysfavor using the usingstatement. Which never forgets to dispose an object, even if the code throws an exception.

总是倾向于使用using语句。即使代码抛出异常,它也永远不会忘记处理一个对象。

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.

尽管还不清楚为什么要创建新的位图,但保存 thumbBMP 应该已经足够了。Anyhoo,用爱给你其余的一次性物品一样。

回答by donstack

I got it working using FileStream, get help from these
http://alperguc.blogspot.in/2008/11/c-generic-error-occurred-in-gdi.htmlhttp://csharpdotnetfreak.blogspot.com/2010/02/resize-image-upload-ms-sql-database.html

我使用 FileStream 让它工作,从这些
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);

回答by Reg Edit

This error message is displayed if the path you pass to Bitmap.Save()is invalid (folder doesn't exist etc).

如果您传递到的路径Bitmap.Save()无效(文件夹不存在等),则会显示此错误消息。

回答by Ch?a bi?t

Create folder path image/thumbs on your hard disk => Problem solved!

在硬盘上创建文件夹路径图像/拇指 => 问题已解决!

回答by Palanikumar

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+".

就我而言,位图图像文件已存在于系统驱动器中,因此我的应用程序抛出错误“GDI+ 中发生通用错误”

  1. Verify that the destination folder exists
  2. Verify that there isn't already a file with the same name in the destination folder
  1. 验证目标文件夹是否存在
  2. 确认目标文件夹中不存在同名文件

回答by Jenny O'Reilly

For me it was a permission problem. Somebody removed write permissions on the folder for the user account under which the application was running.

对我来说,这是一个许可问题。有人删除了运行应用程序的用户帐户的文件夹的写入权限。

回答by Asad

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"

属性> 安全> 编辑> 添加--选择“所有人”并选中允许“完全控制”

回答by Anjan Kant

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 pathand it worked fine for me.

我遇到了同样的问题在 MVC 应用程序上工作时保存GDI+ 中发生一般错误,我收到此错误是因为我写了错误的路径来保存图像,我更正了保存路径,它对我来说很好用。

img1.Save(Server.MapPath("/Upload/test.png", System.Drawing.Imaging.ImageFormat.Png);


--Above code need one change, as you need to put close brackets on Server.MapPath() method after writing its param.

Like this-

像这样-

img1.Save(Server.MapPath("/Upload/test.png"), System.Drawing.Imaging.ImageFormat.Png);

回答by Balaji Dinakaran

    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);