developer tip

Bitmap.Save 메서드의 GDI +에서 일반 오류가 발생했습니다.

copycodes 2020. 12. 28. 08:26
반응형

Bitmap.Save 메서드의 GDI +에서 일반 오류가 발생했습니다.


해당 이미지의 썸네일 사본을 썸네일 폴더에 업로드하고 저장하기 위해 노력하고 있습니다.

다음 링크를 사용하고 있습니다.

http://weblogs.asp.net/markmcdonnell/archive/2008/03/09/resize-image-before-uploading-to-server.aspx

그러나

newBMP.Save(directory + "tn_" + filename);   

"GDI +에서 일반 오류가 발생했습니다."예외가 발생합니다.

폴더에 대한 권한을 부여하려고 시도했으며 저장할 때 새로운 별도의 bmp 개체를 사용하려고했습니다.

편집하다:

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

Bitmap 객체 또는 Image 객체가 파일에서 생성되면 파일은 객체의 수명 동안 잠긴 상태로 유지됩니다. 따라서 이미지를 변경하고 원본과 동일한 파일에 다시 저장할 수 없습니다. http://support.microsoft.com/?id=814675

GDI +, JPEG Image to MemoryStream에서 일반 오류가 발생했습니다.

Image.Save (..)에서 메모리 스트림이 닫혀 있기 때문에 GDI + 예외가 발생합니다.

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

편집 :
메모리에서 쓰기 ...

작동해야하는 '중간'메모리 스트림에 저장

예를 들어 이것을 시도-교체

    Bitmap newBitmap = new Bitmap(thumbBMP);
    thumbBMP.Dispose();
    thumbBMP = null;
    newBitmap.Save("~/image/thumbs/" + "t" + objPropBannerImage.ImageId, ImageFormat.Jpeg);

다음과 같이

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

이 오류 메시지는 전달한 경로 Bitmap.Save()가 유효하지 않은 경우 (폴더가없는 경우 등) 표시됩니다.


    // Once finished with the bitmap objects, we deallocate them.
    originalBMP.Dispose();

    bannerBMP.Dispose();
    oGraphics.Dispose();

조만간 후회하게 될 프로그래밍 스타일입니다. 곧 문을 두드리고 있습니다. 당신은 하나를 잊었습니다. newBitmap을 폐기하지 않습니다 . 가비지 수집기가 실행될 때까지 파일에 대한 잠금을 유지합니다. 실행되지 않으면 두 번째로 동일한 파일에 저장하려고하면 klaboom이 나타납니다. GDI + 예외는 너무 비참해서 좋은 진단을 내릴 수 없으므로 심각한 머리 긁힘이 뒤 따릅니다. 이 실수를 언급하는 수천 개의 googlable 게시물을 넘어서.

항상 using 문을 사용하는 것이 좋습니다. 코드에서 예외가 발생하더라도 객체를 처리하는 것을 잊지 않습니다.

using (var newBitmap = new Bitmap(thumbBMP)) {
    newBitmap.Save("~/image/thumbs/" + "t" + objPropBannerImage.ImageId, ImageFormat.Jpeg);
}

새 비트 맵을 만드는 이유는 명확하지 않지만 thumbBMP를 저장하는 것만으로도 충분합니다. Anyhoo, 사랑을 사용하여 나머지 일회용 물건을 동일하게 제공하십시오.


제 경우 에는 비트 맵 이미지 파일이 시스템 드라이브에 이미 존재 했기 때문에 내 앱에서 "A Generic error generated in GDI +"오류가 발생했습니다 .

  1. 대상 폴더가 있는지 확인
  2. 대상 폴더에 같은 이름의 파일이 없는지 확인

이미지가 저장된 폴더의 권한을 확인하십시오. 폴더를 오른쪽 클릭하고 이동하십시오.

속성> 보안> 편집> 추가- "모든 사람"을 선택하고 "모든 권한"허용을 선택합니다.


동일한 문제에 직면 했습니다 . 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.

이렇게-

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

나는 항상 다음을 확인 / 테스트합니다.

  • 경로 + 파일 이름에 지정된 파일 시스템에 대한 잘못된 문자가 포함되어 있습니까?
  • 파일이 이미 존재합니까? (나쁜)
  • 경로가 이미 존재합니까? (좋은)
  • 경로가 상대적인 경우 : 올바른 상위 디렉토리 (대부분 bin/Debug;-)) 에서 예상 합니까?
  • 프로그램에 대해 쓰기 가능한 경로이며 어떤 사용자가 실행합니까? (서비스는 여기에서 까다로울 수 있습니다!)
  • 전체 경로에 실제로 불법 문자가 포함되어 있지 않습니까? (일부 유니 코드 문자는 보이지 않는 것에 가깝습니다)

Bitmap.Save()이 목록 외에는 문제가 없었습니다 .


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

저에게는 권한 문제였습니다. 누군가 응용 프로그램이 실행중인 사용자 계정의 폴더에 대한 쓰기 권한을 제거했습니다.


하드 디스크에 폴더 경로 이미지 / 썸 만들기 => 문제 해결!


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

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.


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!


I had a different issue with the same exception.

In short:

Make sure that the Bitmap's object Stream is not being disposed before calling .Save .

Full story:

There was a method that returned a Bitmap object, built from a MemoryStream in the following way:

private Bitmap getImage(byte[] imageBinaryData){
    .
    .
    .
    Bitmap image;
    using (var stream = new MemoryStream(imageBinaryData))
    {
        image = new Bitmap(stream);
    }
    return image;
}

then someone used the returned image to save it as a file

image.Save(path);

The problem was that the original stream was already disposed when trying to save the image, throwing the GDI+ exeption.

A fix to this problem was to return the Bitmap without disposing the stream itself but the returned Bitmap object.

private Bitmap getImage(byte[] imageBinaryData){
   .
   .
   .
   Bitmap image;
   var stream = new MemoryStream(imageBinaryData))
   image = new Bitmap(stream);

   return image;
}

then:

using (var image = getImage(binData))
{
   image.Save(path);
}

from msdn: public void Save (string filename); which is quite surprising to me because we dont just have to pass in the filename, we have to pass the filename along with the path for example: MyDirectory/MyImage.jpeg, here MyImage.jpeg does not actually exist yet, but our file will be saved with this name.

Another important point here is that if you are using Save() in a web application then use Server.MapPath() along with it which basically just returns the physical path for the virtual path which is passed in. Something like: image.Save(Server.MapPath("~/images/im111.jpeg"));

ReferenceURL : https://stackoverflow.com/questions/15862810/a-generic-error-occurred-in-gdi-in-bitmap-save-method

반응형