Bitmap.Save上的GDI +异常

时间:2015-11-02 19:34:06

标签: c# bitmap save gdi+

我想保存已调整大小的图片,但我收到了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);

有任何想法如何解决这个问题?

EDIT1:

类型' System.Runtime.InteropServices.ExternalException'的例外情况发生在System.Drawing.dll中但未在用户代码中处理

其他信息:GDI +中发生了一般性错误。

1 个答案:

答案 0 :(得分:2)

您的代码有几个问题:

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无效。其他Web浏览器通常会提供虚假名称并仅保留文件扩展名。您也无法信任用户提供正确的扩展名。如果用户上传可被解释为有效位图的恶意文件,但是也是一个擦除服务器硬盘的有效PHP脚本会发生什么?
  3. 除了明确调用using方法之外,您应该总是更喜欢Dispose块。
  4. 导入System.Drawing命名空间,因此您未在代码中指定完整的类型名称。
  5. 您将缩略图保存为位图,这些是大型未压缩文件。您应该将它们压缩为JPEG或PNG图像。您还使用原始图像的文件扩展名保存图像(您无法信任)。
  6. 以下是我如何改进它:

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