使用WebImage.Resize时内存不足异常

时间:2011-03-11 10:14:58

标签: c# asp.net-mvc-3

我正在使用MVC3中的WebImage来调整图像大小。基本上,这样做的目的是创建上载文件的缩略图。我无法控制文件的大小,因此我需要创建文件的缩略图以加快“预览”网站的速度。

我有一些文件需要上传和大小,大约4Mb,这在上传时不是问题。我遇到的问题是创建缩略图。我先上传文件,然后保存在服务器上,然后为缩略图创建一个新的WebImage对象。

// Save a thumbnail of the file
WebImage image = new WebImage(savedFileName);

// Resize the image
image.Resize(135, 150, true);

// Save the thumbnail
image.Save(FileName);   // <<--- Out of memory exception here

// Dispose of the image
image = null;

当我尝试保存文件时,出现内存不足异常。关于如何解决这个问题的任何想法?

5 个答案:

答案 0 :(得分:8)

由于WebImage中存在错误,我不得不求助于以下代码:

// Save a thumbnail of the file
byte[] fileBytes = System.IO.File.ReadAllBytes(savedFileName);

System.Drawing.Image i;
using (MemoryStream ms = new MemoryStream())
{
    ms.Write(fileBytes, 0, fileBytes.Length);
    i = System.Drawing.Image.FromStream(ms);
}

// Create the thumbnail
System.Drawing.Image thumbnail = i.GetThumbnailImage(135, 150, () => false, IntPtr.Zero);

答案 1 :(得分:4)

我自己使用WebImage Resize遇到了这个问题,发现问题是JPG图像实际上是CMYK图像。将PS中的图像模式更改为RGB不仅减小了WebImage Resize方法正在使用的文件大小,而且执行速度也更快。

对于网络使用,我尝试确保所有JPG图像都是RGB并以基本格式保存(而不是渐进式)。这可以防止发生许多小错误和错误。

答案 2 :(得分:3)

当我尝试调整大小并保存使用CMYK颜色空间的JPG图像时,我从WebImage.Save()获得了一个OutOfMemoryException。

我找到的解决方法是将图像保存到磁盘并在调整大小之前重新加载它。

var logoWebImage = new WebImage(newLogo.InputStream);
// Start workaround: Save and reload to avoid OutOfMemoryException when image color space is CMYK.
logoWebImage.Save(filePath: DataFilePaths.LogoImageFile, imageFormat: "png");
logoWebImage = new WebImage(DataFilePaths.LogoImageFile);
// End workaround
logoWebImage.Resize(300, 300, preserveAspectRatio: true, preventEnlarge: true);
logoWebImage.Save(filePath: DataFilePaths.LogoImageFile, imageFormat: "png");

这是一个丑陋的解决方法,但在输入图像是徽标图像时尤其需要它。因为设计师经常提供使用CMYK色彩空间的徽标图像,因为它更适合打印。

答案 3 :(得分:0)

好的,这看起来像是MVC3中的一个错误。当GDI +尝试访问不存在的位置的像素时,您得到的错误只是标准GDI +错误

我认为在计算宽高比时,问题出现在像素的四舍五入中,所以我认为如果您将135, 150更改为例如136, 151则会有效。

我可能稍后会看一下他们的代码中的错误并发布给他们。


更新 - 可能的解决方法

尝试传递true第4个参数:

// Resize the image
image.Resize(135, 150, true, true);

我实际上可以在代码中看到错误:

    if (num3 > num4)
    {
        height = (int) Math.Round((double) ((num4 * image.Height) / 100.0));
    }
    else if (num3 < num4)
    {
        width = (int) Math.Round((double) ((num3 * image.Width) / 100.0));
    }

答案 4 :(得分:0)

我最终将此作为解决方法:

    public static Image ScaleImage(string fileName, int maxWidth, int maxHeight)
    {
        var image = Image.FromFile(fileName);
        var ratioX = (double)maxWidth / image.Width;
        var ratioY = (double)maxHeight / image.Height;
        var ratio = Math.Min(ratioX, ratioY);

        var newWidth = (int)(image.Width * ratio);
        var newHeight = (int)(image.Height * ratio);

        var newImage = new Bitmap(newWidth, newHeight);
        var g = Graphics.FromImage(newImage);
        g.Clear(Color.White); // matters for transparent images
        g.DrawImage(image, 0, 0, newWidth, newHeight);
        return newImage;
    }