【问题标题】:GDI+ Exception on Bitmap.SaveBitmap.Save 上的 GDI+ 异常
【发布时间】:2015-11-02 19:34:05
【问题描述】:

我想保存调整大小后的图像,但出现 GDI+ 错误。代码:

        System.Drawing.Image image = System.Drawing.Image.FromFile(Server.MapPath(path));
        float aspectRatio = (float)image.Size.Width / (float)image.Size.Height;
        int newHeight = 200;
        int newWidth = Convert.ToInt32(aspectRatio * newHeight);
        System.Drawing.Bitmap thumbBitmap = new System.Drawing.Bitmap(newWidth, newHeight);
        System.Drawing.Graphics thumbGraph = System.Drawing.Graphics.FromImage(thumbBitmap);
        thumbGraph.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
        thumbGraph.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
        thumbGraph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
        var imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
        thumbGraph.DrawImage(image, imageRectangle);
        thumbBitmap.Save("~/images/galeria/thumb/" + FileUpload1.FileName);
        thumbGraph.Dispose();
        thumbBitmap.Dispose();
        image.Dispose();

错误是由这一行引起的:

thumbBitmap.Save("~/images/galeria/thumb/" + FileUpload1.FileName);

有什么办法解决这个问题吗?

编辑1:

System.Drawing.dll 中出现“System.Runtime.InteropServices.ExternalException”类型的异常,但未在用户代码中处理

附加信息:GDI+ 中出现一般错误。

【问题讨论】:

  • 请给我们完整的错误描述。
  • 调试器。断点。使用它们,也许,你能给我们完整的错误吗?
  • 确定是有效路径?有写权限吗?
  • 路径存在。 EDIT1 中的整个错误。

标签: c# bitmap save gdi+


【解决方案1】:

您的代码有几个问题:

thumbBitmap.Save("~/images/galeria/thumb/" + FileUpload1.FileName);
  1. 您只能在通过HttpServerUtility.MapPath(即this.Server.MapPath)的路径中使用~ 字符。 GDI 需要一个有效的 Win32 文件名。您需要先翻译文件名。
  2. 您不能信任上传文件的 FileName 属性:某些版本的 Internet Explorer 提供完整的本地文件名,这意味着您的路径将是无效的 .../galeria/thumb/D:\Me\myfile.jpg。其他网络浏览器通常会提供一个假名称,并且只保留文件扩展名。您也不能相信用户提供正确的扩展名。如果用户上传的恶意文件可以被解释为有效的位图,但它也是一个有效的 PHP 脚本,它会擦除​​您服务器的 HDD,会发生什么?
  3. 您应该始终更喜欢 using 块而不是显式调用 Dispose 方法。
  4. 导入 System.Drawing 命名空间,因此您无需在代码中指定完整的类型名称。
  5. 您将缩略图保存为位图,这些是未压缩的大文件。您应该将它们压缩为 JPEG 或 PNG 图像。您还使用原始图像的文件扩展名(您无法信任)保存图像。

以下是我将如何改进它:

using( Image image = Image.FromFile( Server.MapPath( path ) ) ) {

    float aspectRatio = (float)image.Size.Width / (float)image.Size.Height;
    int newHeight = 200;
    int newWidth = (ToInt32)( aspectRatio * newHeight );

    using( Bitmap thumbBitmap = new System.Drawing.Bitmap( newWidth, newHeight ) )
    using( Graphics thumbGraph = Graphics.FromImage( thumbBitmap ) ) {

        thumbGraph.CompositingQuality = CompositingQuality.HighQuality;
        thumbGraph.SmoothingMode = SmoothingMode.HighQuality;
        thumbGraph.InterpolationMode = InterpolationMode.HighQualityBicubic;

        Rectangle imageRectangle = new Rectangle(0, 0, newWidth, newHeight);
        thumbGraph.DrawImage( image, imageRectangle );

        String outputFileName = this.Server.MapPath( "~/images/galeria/thumb" );
        outputFileName = Path.Combine( outputFileName, Path.GetFileNameWithoutExtension( path ) ) + ".jpg";

        // Use code from here to save as a JPEG: https://msdn.microsoft.com/en-us/library/bb882583(v=vs.110).aspx
        thumbBitmap.Save( outputFileName, jpegEncoder, jpegEncoderParameters );
    }
}

【讨论】:

  • 它在 InterpolationMode 上给了我 GDI+ 错误,但如果我评论它,那么它在 Rectangle 上给出了 GDI+ 错误。
猜你喜欢
  • 2011-01-26
  • 2012-06-27
  • 2017-05-04
  • 2013-07-23
  • 2011-12-21
  • 1970-01-01
  • 2010-10-26
  • 1970-01-01
  • 2011-08-14
相关资源
最近更新 更多