zoukankan      html  css  js  c++  java
  • 在绘图时把image保存为PNG格式时出理的gdi+ general error

     最近在做图片缩放时遇到的一个问题,当我把缩放之后的图片另存为png格式时,出现gdi+ general error,详细的异常描述如下:

    A generic error occurred in GDI+.

    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

    Exception Details: System.Runtime.InteropServices.ExternalException: A generic error occurred in GDI+.

    Source Error:

    Line 42:             catch (Exception ex)
    Line 43: {
    Line 44: throw ex;
    Line 45: }
    Line 46: finally

      这个异常什么消息都没提供给我,莫名其妙,ex.InnerException为null,看来MS对我们隐藏了具体的异常。

    我的代码:

    1 ...........
    2 g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
    3 g.DrawImage(bitmap, 0, 0, originWidth, originHeight);
    4
    5 try
    6 {
    7 bitmap.Save(stream, ImageFormat.Png);
    8 }
    9 catch (Exception ex)
    10 {
    11 throw ex;
    12 }
    13 finally
    14 {
    15 bitmap.Dispose();
    16 g.Dispose();
    17 originImg.Dispose();
    18 }

      由于我是在一个handler中直接把输出图片至outputstream(这个是问题产生的根本原因)。题外话:刚开始还以为是bitmap锁住的原因导致不能保存,于是采用一个临时bitmap来过渡一下。看具体代码:

    Bitmap tempBitmap = new Bitmap(originImage);
    Bitmap bitmap
    = new Bitmap(tempBitmap );



    //释放临时bitmap后,再save
    tempBitmap .Dispose();

    bitmap.Save(bitmap ,
    0,0,width,height)

    这个方法不起效,我还想到是不是权限的问题,结果也被排除了!

    既然不然保存为PNG,不妨试试其它的格式,当然换在Jpeg格式时,发现可以正常输出图片。这肯定有图片跟图片格式有关系了,搜索到一些东西:

    Png's are a special case. Their encoder requires a bi-directional stream. The solution is to stream to a memory stream first and write the contents of that memory stream to OutputStream afterwards.

    大概意思是对PNG解码器需要一个双向流,解决方法是先把数据写入memeory stream,然后再把memory stream写入至outputstream。

    我们知道Response.OutputStream是一个单向流,无法向回读取数据(MS他的CanSeek属性为false),可能是png在解码的时候还需要往回写数据,由于CanSeek属性为false,所有不能往回写数据,导致这个问题吧。

    用MemoryStream来中转一下

              using (MemoryStream ms =new MemoryStream())
    {

    bitmap.Save(ms,ImageFormat.Png);
    ms.WriteTo(stream);
    }

    等比缩放代码:

    private Size GetNewSize(int originWidth, int originHeight, int toWidth, int toHeight)
    {

    int w, h;
    if ((double)originWidth / (double)toWidth < (double)originHeight / (double)toHeight)
    {
    h
    = toHeight;
    w
    = originWidth * toHeight / originHeight;
    }
    else
    {
    w
    = toWidth;
    h
    = originHeight * toWidth / originWidth ;
    }
    return new Size(w, h);
    }

    解决问题一定要一步一步来定位问题,然后再去尝试解决!

  • 相关阅读:
    libxml2 解析文档的例子
    FreeRTOS之任务优先级的分配
    idea中快速重写父类方法
    组件里面调用组建的方法
    sproot 注解学习记录 (含给实现类起名字的方法)
    直播技术没有那么神秘,你也可以DIY
    Java服务端API接口统一加密和解密
    把对象交给spring管理的3种方法及经典应用
    Dart空安全的底层原理与适配
    Dart 中 final和const 区别
  • 原文地址:https://www.cnblogs.com/repository/p/2019004.html
Copyright © 2011-2022 走看看