当前位置:  开发笔记 > 编程语言 > 正文

将位图保存到MemoryStream时,GDI +中发生了一般错误

如何解决《将位图保存到MemoryStream时,GDI+中发生了一般错误》经验,为你挑选了1个好方法。

我有一些代码可以在几台机器上完美运行(开发,QA,UAT).不幸的是,在生产中我得到"GDI +中出现了一般错误" bmp.Save(ms, ImageFormat.Png);因此,我假设你无法重现问题,但也许有人可以发现我的错误.

一些注释,我已经搜索了很多常见的解决方案,请注意这是保存到一个MemoryStream所以大多数人建议不适用的文件权限问题,"bmp在打开时锁定"解决方案也是如此,因为我,'我在别的地方写作.最后,这不是因为png需要可搜索的流,因为它MemoryStream是可搜索的.

请注意,如果我将其更改为ImageFormat.Jpeg工作正常.我只对PNG有问题.我发现HKEY_CLASSES_ROOT\CLSID\{FAE3D380-FEA4-4623-8C75-C6B61110B681}由于权限,提到注册表项可能是问题所在.因此,我设置密钥以允许Everyone对此密钥具有读取访问权限,无需更改.

public static MemoryStream GenerateImage(string text)
{
    MemoryStream ms = new MemoryStream();
    using (Bitmap bmp = new Bitmap(400,400))
    {
        bmp.Save(ms, ImageFormat.Png);
        ms.Position = 0;
    }
    return ms;
}

这是完整的堆栈跟踪:

[ExternalException(0x80004005):GDI +中发生一般错误.]
System.Drawing.Image.Save(Stream stream,ImageCodecInfo encoder,EncoderParameters encoderParams)+616457
WP.Tools.Img.GenerateImage(String text)+383

注意:我的问题已经列举了拟议副本中的解决方案.没有问题.如果它们也会因JPEG而失败.



1> Cee McSharpf..:

在.NET参考源代码在这里,在保存到数据流的情况下,会从原生方法GdipSaveImageToStream呼叫的状态值:

public void Save(Stream stream, ImageCodecInfo encoder, EncoderParameters encoderParams) {

    ...

    if (!saved)
    {
        status = SafeNativeMethods.Gdip.GdipSaveImageToStream(new HandleRef(this,nativeImage),new UnsafeNativeMethods.ComStreamFromDataStream(stream),ref g,new HandleRef(encoderParams, encoderParamsMemory));
    }

    ...

}

此状态值是用于从该方法引发异常的唯一API返回值.当我们进一步研究StatusException函数时,它根据状态代码决定抛出什么类型的异常,我们只找到一个可能的状态值来导致你得到的ExternalException(来自Gdiplus.cs,第3167行):

switch (status)
{
    case GenericError:
        return new ExternalException(SR.GetString(SR.GdiplusGenericError), E_FAIL);

    ...
}

0x80004005是"未指定的错误",SR.GdiplusGenericError是文本"GDI +中发生一般错误".你得到了.这排除了我们可能怀疑的其他几种可能性(这将导致不同的例外),即:

内存不足

对象忙

缓冲不足

win32error

valueoverflow

unknownimageformat

找不到属性/不支持

unsupportedgdiplusversion

本机方法驻留在gdiplus.dll中.长话短说,修补你的生产服务器,修复.NET框架.更多细节:

    在已知良好的机器和生产机器之间比较%windir%\ system32中该dll的版本.该DLL有数百个依赖项,因此即使文件本身的版本匹配,请参阅修补您的操作系统.

    PNG格式的内置编解码器是Windows的WIC组件的一部分,驻留在WindowsCodecs.dllWindowsCodecsExt.dll中 - 也检查这些库的版本.您提到的注册表项也应指向WindowsCodecsExt.dll.

    不是基于recherche,只是想法:您是通过虚拟化/远程桌面连接访问生产服务器吗?如果可以,请尝试控制台会话.尝试不同的屏幕分辨率和颜色深度.尝试调试/发布版本.确保您确实已在发布版本配置中清除了DEBUG检查.尝试构建x64和MSIL.如果您在生产中使用NGEN,请尝试不使用.

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有