3

我正在使用 ImageResizer 库在 ASP.NET MVC 4 项目中进行一些简单的图像大小调整和旋转。问题是,当我使用它处理 32-bpp CMYK JPEG 文件时,它失败并出现 ArgumentException,但仅在我的(Windows Server 2008 R2)服务器上 - 它在我的(Windows Vista)笔记本电脑上运行良好。

有问题的 JPEG 文件不是太大 (700x500) 或其他非标准文件 - 所有 Web 浏览器和 Paint 都可以很好地打开它们,即使在有问题的服务器本身上也是如此。JPEG 是使用 ImageMagick 生成的,如果我要求 ImageMagick 使用 RGB 颜色空间(-colorspace sRGB.) ,一切正常

奇怪的是,在所有情况下调整图像大小都可以正常工作,但如果我尝试在服务器上调整图像大小和旋转图像,它就会失败。

看起来一些较低级别的 Win32 或 GDI+ 函数调用在这里失败了 - 这是堆栈跟踪的相关部分:

[ArgumentException: Parameter is not valid.]
   System.Drawing.Graphics.CheckErrorStatus(Int32 status) +1621285
   System.Drawing.Graphics.DrawImage(Image image, PointF[] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr, DrawImageAbort callback, Int32 callbackData) +727
   System.Drawing.Graphics.DrawImage(Image image, PointF[] destPoints, RectangleF srcRect, GraphicsUnit srcUnit, ImageAttributes imageAttr) +73
   ImageResizer.ImageBuilder.RenderImage(ImageState s) +763
   ImageResizer.ImageBuilder.Render(ImageState s) +174
   ImageResizer.ImageBuilder.Process(ImageState s) +105
   ImageResizer.ImageBuilder.buildToBitmap(Bitmap source, ResizeSettings settings, Boolean transparencySupported) +276
   ImageResizer.ImageBuilder.buildToStream(Bitmap source, Stream dest, ResizeSettings settings) +149
   ImageResizer.ImageBuilder.BuildJob(ImageJob job) +940
   ImageResizer.ImageBuilder.Build(ImageJob job) +223

有任何想法吗?

4

1 回答 1

0

经过更多的研究和测试,我发现只有Bitmap.RotateFlip在源位图上调用该方法时才会出现问题,然后才将其绘制到目标位图上以进行裁剪和调整大小。

我最终不得不自己使用普通的旧代码重新编写代码System.Drawing,因为无法更改 ImageResizer 库的行为。具体来说,我编写了自己的旋转函数,它使用变换矩阵来做同样的事情。

    private Bitmap RotateImage(Bitmap source, float angle)
    {
        if (angle == 0) return (Bitmap)source.Clone();

        Bitmap target;
        using (GraphicsPath path = new GraphicsPath())
        using (Matrix matrix = new Matrix())
        {
            path.AddRectangle(new RectangleF(0.0f, 0.0f, source.Width, source.Height));
            matrix.Rotate(angle);
            RectangleF rect = path.GetBounds(matrix);

            target = new Bitmap((int)Math.Round(rect.Width), (int)Math.Round(rect.Height));
            target.SetResolution(source.HorizontalResolution, source.VerticalResolution);

            using (Graphics g = Graphics.FromImage(target))
            {
                g.TranslateTransform(-rect.X, -rect.Y);
                g.RotateTransform(angle);
                g.InterpolationMode = InterpolationMode.HighQualityBicubic;
                g.DrawImageUnscaled(source, 0, 0);
            }
        }
        return target;
    }

我本来想从源头设置PixelFormatBitmap的 - 但这样做会在遇到有问题的 CMYK JPEG 文件时引发奇怪的 GDI+“内存不足”错误。这让我想知道这种奇怪的行为是否与这个GDI+ 错误/怪癖有关,它在 Windows 7/Server 2008 R2 和 Windows Vista/Server 2008 上返回不同ImageFlags的值。PixelFormat

于 2012-11-25T00:44:37.330 回答