4

わかりました、申し訳ありませんが、これはおそらく初心者の質問ですが、私はちょっと立ち往生しています。

したがって、(asp.netアプリケーションで)実行しているのは、ファイルシステムから画像をロードすることです。

System.Drawing.Image tempImage;
tempImage = System.Drawing.Image.FromFile(HttpContext.Server.MapPath(originalPath));

次に、サイズ変更を行います。

tempImage = my awesomeResizingFunction(tempImage, newSize);

これを使用して、別の場所のファイルシステムに保存する予定です。

string newPath = "/myAwesomePath/newImageName.jpg";
tempImage.Save(newPath);

そして私が得るのはこのエラーです:

"A generic error occurred in GDI+."

ブラウザに書き込んでサイズ変更された画像を表示できるため、画像が「OK」であることがわかります。保存しようとするとエラーが発生するだけです。私はちょっと新しくて立ち往生しています、私はこれを完全に間違っていますか?(まあ、それは明らかだと思いますが、あなたは私が何を意味するか知っています...)

4

3 に答える 3

8

このコードを試してください...画像のサイズ変更と保存に同じコードを使用しました。

    System.Drawing.Bitmap bmpOut = new System.Drawing.Bitmap(NewWidth, NewHeight);
    System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bmpOut);
    g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
    g.FillRectangle(System.Drawing.Brushes.White, 0, 0, NewWidth, NewHeight);
    g.DrawImage(new System.Drawing.Bitmap(fupProduct.PostedFile.InputStream), 0, 0, NewWidth, NewHeight);
    MemoryStream stream = new MemoryStream();
    switch (fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.') + 1).ToLower())
    {
        case "jpg":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            break;
        case "jpeg":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg);
            break;
        case "tiff":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Tiff);
            break;
        case "png":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Png);
            break;
        case "gif":
            bmpOut.Save(stream, System.Drawing.Imaging.ImageFormat.Gif);
            break;
    }
    String saveImagePath = Server.MapPath("../") + "Images/Thumbnail/" + fupProduct.FileName.Substring(fupProduct.FileName.IndexOf('.'));
    bmpOut.Save(saveImagePath);

fupProductfileuploadコントロールIDはどこですか

于 2009-08-05T13:16:14.177 に答える
6

originalPathとnewPathが異なるファイルを指していることを確認しますか?Image.FromFileを使用する場合、画像に対してDisposeを呼び出すまでファイルはロックされたままになります。これにより、前述の例外が発生する可能性があります。代わりにそのような画像をロードすることができます:

Image tempImage = null;
using (FileStream fs = new FileStream(originalPath, FileMode.Open, FileAccess.Read))
{
    tempImage = Image.FromStream(fs);
}
...

このアプローチにより、usingブロックの最後でファイルが閉じられることが保証されます

于 2009-08-04T22:15:23.227 に答える
0

元の画像を裏付ける元のストリームが閉じられている可能性はありますか?ビットマップの背後にあるストリームが閉じられている場合、GDI+エラーが発生し始めます。私たちのウェブサイトに画像処理を追加したとき、私はこれにたくさん遭遇しました。

Visual Studioデバッガーでビットマップオブジェクトを開くと、プロパティの値の代わりに例外が表示されますか?その場合、保存操作に問題はありませんが、GDI+レイヤーはオブジェクトを処理する機能を失っています。

私が見つけたのは、ビットマップに属するMemoryStreamsを追跡し、それらをすべて一緒に保持する必要があるということでした。画像のサイズを変更すると、新しいビットマップ画像を含む新しいMemoryStreamが作成されました。

私はこの単純なクラスを作成することになりました(ここで不要ないくつかの余分なプロパティをトリミングしました):

public class UploadedImage : IDisposable
{
    private Bitmap _img = null;
    private Stream _baseStream = null;


    /// <summary>
    /// The image object.  This must always belong to BaseStream, or weird things can happen.
    /// </summary>
    public Bitmap Img
    {
        [DebuggerStepThrough]
        get { return _img; }
        [DebuggerStepThrough]
        set { _img = value; }
    }

    /// <summary>
    /// The stream that stores the image.  This must ALWAYS belong to Img, or weird things can happen.
    /// </summary>
    public Stream BaseStream
    {
        [DebuggerStepThrough]
        get { return _baseStream; }
        [DebuggerStepThrough]
        set { _baseStream = value; }
    }

    [DebuggerStepThrough]
    public void Dispose()
    {
        if (Img != null)
            Img.Dispose();

        if (BaseStream != null)
            BaseStream.Close();

        _attached = false;
    }
}

今、私はWebサイトにアップロードされた画像を処理していましたが、Asp.Netがリクエストに添付されたストリームをリサイクルすると、突然の画像操作がすべて飛び出し始めたことがわかりました。したがって、これが最善の方法であるかどうかにかかわらず、私の解決策は、アップロードストリームから自分のMemoryStreamにデータをコピーし、そこから画像をロードして、両方をこのコンテナに貼り付けることでした。また、古い画像から新しい画像を作成する場合は常に、ストリームと画像を一緒に保持していました。

これがお役に立てば幸いです。

編集:私はあなたが画像のサイズ変更をどのように行っているかを見ることにも興味があります。これは、私が行った方法の抜粋です。

temp = new Bitmap(newWidth, newHeight, PIXEL_FORMAT);
temp.SetResolution(newHorizontalRes, newVerticalRes);
gr = Graphics.FromImage(temp);

//
// This copies the active frame from 'img' to the new 'temp' bitmap.
// Also resizes it and makes it super shiny.  Sparkle on, mr image dude.
// 
Rectangle rect = new Rectangle(0, 0, newWidth, newHeight);
gr.InterpolationMode = InterpolationMode.HighQualityBicubic;
gr.SmoothingMode = SmoothingMode.HighSpeed;
gr.PageUnit = GraphicsUnit.Pixel;
gr.DrawImage(img, rect);

//
// Image copied onto the new bitmap.  Save the bitmap to a fresh memory stream.
//
retval = new UploadedImage();
retval.BaseStream = (Stream)(new MemoryStream());

temp.Save(retval.BaseStream, ImageFormat.Jpeg);
retval.Img = temp;
于 2009-08-04T22:02:28.493 に答える