簡體   English   中英

從System.Drawing.Image在文件系統上創建一個新圖像?

[英]Create a new image on the file system from System.Drawing.Image?

好的,對不起,這可能是一個noob問題,但我有點卡住了。

所以我正在做的(在我的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+."

我知道圖像是“正常的”,因為我可以將它寫入瀏覽器並查看已調整大小的圖像,我只是在嘗試保存時才收到錯誤。 我有點新手,我完全錯了嗎? (嗯,我猜這很明顯,但你知道我的意思......)

請嘗試此代碼...我使用了相同的代碼來調整圖像和保存。 如果你有任何問題,請告訴我。

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

其中fupProduct是fileupload控件ID

您確定originalPath和newPath指向不同的文件嗎? 當您使用Image.FromFile時,文件將保持鎖定狀態,直到您在Image上調用Dispose,這可能會導致您提到的異常。 您可以這樣加載圖像:

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

此方法可確保在使用塊結束時關閉文件

支持原始圖像的原始流是否可能已關閉? 如果Bitmap后面的流已關閉,則會開始出現GDI +錯誤。 當我們在網站上添加圖像處理時,我遇到了很多。

如果在Visual Studio調試器中打開Bitmap對象,是否會看到異常而不是屬性的值? 如果是這樣,它不是保存操作的問題,但是GDI +層已經失去了處理對象的能力。

我發現的是我需要跟蹤屬於我的位圖的MemoryStream並將它們保存在一起。 調整圖像大小會產生帶有新位圖圖像的新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;
    }
}

現在,我正在處理上傳到我們網站的圖像,我發現當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;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM