web-dev-qa-db-ja.com

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

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

このエラーメッセージは、Bitmap.Save()に渡すパスが無効な場合(フォルダが存在しないなど)にも表示されます。

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

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

これは、遅かれ早かれ後悔するプログラミングスタイルです。すぐにドアをノックしている、あなたは1つを忘れました。破棄していませんnewBitmap。ガベージコレクターが実行されるまでファイルのロックを保持します。実行されない場合、同じファイルに2回保存しようとすると、klaboomが表示されます。 GDI +の例外は悲惨すぎるため、優れた診断結果を得るには非常に深刻です。この間違いに言及する何千ものグーグル投稿を超えて。

常にusingステートメントの使用を支持します。コードが例外をスローした場合でも、オブジェクトの破棄を忘れることはありません。

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

なぜ新しいビットマップを作成するのかは非常に明確ではありませんが、thumbBMPを保存するだけで十分なはずです。とにかく、愛を使って残りの使い捨てオブジェクトに同じものを与えてください。

9
Hans Passant

私の場合、ビットマップイメージファイルは既にシステムドライブに存在していましたなので、アプリはエラーをスローしました"GDI +で一般的なエラーが発生しました"

  1. 宛先フォルダーが存在することを確認します
  2. 宛先フォルダーに同じ名前のファイルがまだないことを確認します
7
Palanikumar

画像が保存されているフォルダの許可を確認し、右クリックしてフォルダを選択してください:

[プロパティ]> [セキュリティ]> [編集]> [追加]-[全員]を選択し、[フルコントロールを許可]をオンにします

7
Asad

私は同じ問題に直面していましたMVCアプリで作業中に保存時にGDI +で一般的なエラーが発生しました画像の保存、I保存パスを修正し、私にとってはうまくいきました。

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);
5
Anjan Kant

私は常にこれらをチェック/テストします:

  • パス+ファイル名には、指定されたファイルシステムの不正な文字が含まれていますか?
  • ファイルはすでに存在しますか? (悪い)
  • パスはすでに存在しますか? (良い)
  • パスが相対パスの場合:正しい親ディレクトリ(ほとんどがbin/Debug ;-))にあると思いますか?
  • プログラムのパスは書き込み可能で、どのユーザーとして実行されますか? (サービスはここで注意が必要です!)
  • 絶対パスは本当に、実際には違法な文字を含んでいませんか? (一部のユニコード文字は不可視に近い)

このリスト以外では、Bitmap.Save()に問題はありませんでした。

2

私にとっては、許可の問題でした。誰かが、アプリケーションが実行されていたユーザーアカウントのフォルダーに対する書き込み権限を削除しました。

1
Jenny O'Reilly

FileStreamを使用して動作するようになった、これらからの助けを得る
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

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

同じ例外で別の問題が発生しました。

要するに:

.Saveを呼び出す前に、BitmapのオブジェクトStreamが破棄されていないことを確認してください。

詳細:

以下の方法でBitmapから構築されたMemoryStreamオブジェクトを返すメソッドがありました。

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

誰かが返された画像を使用してファイルとして保存しました

image.Save(path);

問題は、GDI +例外をスローして、イメージを保存しようとしたときに元のストリームが既に破棄されていたことです。

この問題の修正は、ストリーム自体を破棄せずにBitmapオブジェクトを返すが、Bitmapを返すことでした。

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

   return image;
}

その後:

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

ハードディスクにフォルダパスイメージ/サムを作成=>問題は解決しました!

0
Chưa biết

Tiff画像をJpegに変換しようとしたときにこのエラーが発生しました。私にとってこの問題は、tiffの寸法が大きすぎることに起因していました。約62000ピクセルまでは問題なく、このサイズを超えるとエラーが発生しました。

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

私にとっては、画像を保存するときのパスの問題でした。

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;

そこで、次のスラッシュを追加して修正しました

String path = "images/savedimages....

あるべき

String path = "/images/savedimages....

誰もが動けなくなることを願っています!

0
imBlue