好吧,我很抱歉,这可能是一个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+."

我知道图像是“OK”,因为我可以写出来给浏览器,看看调整后的图像,当我试图挽救它,我只能得到错误。我有点新卡,我在做这完全错了吗? (嗯,我想这是显而易见的,但你知道我的意思...)

有帮助吗?

解决方案

PLZ试试这个代码...我已经使用了相同的代码调整图像和保存。如果你有任何问题,然后PLZ让我知道。

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是文件上传控制ID

其他提示

您确保originalPath和NEWPATH指向不同的文件?当您使用Image.FromFile,该文件保持锁定状态,直到你调用Dispose的形象,这可能会导致你提到的异常。你可以加载图像那样来代替:

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

这个方法保证了该文件在使用块的末尾

关闭

是否有可能在原始流支持原始图象已被关闭?如果一个位图背后的流已关闭,你开始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;
    }
}

现在,我正在处理上传到我们网站上的图像,以及我发现的是,当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归因
不隶属于 StackOverflow
scroll top