Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# GDI+;中发生一般性错误;将位图保存到MemoryStream时_C#_Gdi+ - Fatal编程技术网

C# GDI+;中发生一般性错误;将位图保存到MemoryStream时

C# GDI+;中发生一般性错误;将位图保存到MemoryStream时,c#,gdi+,C#,Gdi+,我有一些代码可以在多台机器上完美运行(开发、QA、UAT)。不幸的是,在生产过程中,我在bmp.Save(ms,ImageFormat.Png)上看到了“GDI+中发生的一般错误”

我有一些代码可以在多台机器上完美运行(开发、QA、UAT)。不幸的是,在生产过程中,我在
bmp.Save(ms,ImageFormat.Png)上看到了“GDI+中发生的一般错误”
注意,我已经搜索了很多常见的解决方案,注意这是保存到
MemoryStream
,因此大多数人建议的文件权限问题不适用,也不适用“打开时锁定bmp”解决方案,因为我在其他地方写。最后,这并不是因为png需要可搜索的流,因为
MemoryStream
是可搜索的

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

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;
}
以下是完整的堆栈跟踪:

[外部异常(0x80004005):GDI+中发生一般错误。]
System.Drawing.Image.Save(流、ImageCodeInfo编码器、, 编码器参数编码器参数)+616457
WP.Tools.Img.GenerateImage(字符串 正文)+383


注:我的问题已经列举了建议副本中的解决方案。没有问题。如果他们是,JPEG也会失败

在“保存到流”的情况下,.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行):

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

  • 内存不足
  • 对象忙
  • 缓冲区不足
  • Win32错误
  • 价值溢出
  • 未知图像格式
  • 未找到/不支持属性
  • 不受支持的幻觉
本机方法位于gdiplus.dll中。长话短说,请修补生产服务器,.NET framework。更多详情:

  • 比较%windir%\system32中已知良好机器和生产机器之间的dll版本。dll有数百个依赖项,因此即使文件本身的版本匹配,也要查看以修补操作系统
  • PNG格式的内置编解码器是windows的WIC组件的一部分,位于WindowsCodecs.dllWindowsCodecExt.dll中-同时检查这些库的版本。您提到的注册表项还应指向WindowsCodecsExt.dll
  • 不是基于recherche,只是想法:您是否通过虚拟化/远程桌面连接访问生产服务器?如果可以,请尝试控制台会话。尝试不同的屏幕分辨率和颜色深度。尝试调试/发布版本。确保在发布版本配置中确实清除了调试检查。尝试构建x64和MSIL。如果您在生产中使用NGEN,请尝试不使用

  • 可能重复的相关:@Thomas Weller我不认为这是相同的问题。首先,我没有在任何地方释放内存,其次,如果这是问题所在,我希望jpeg也会失败,而不仅仅是png。如果不加载bg.png,而是在内存中创建一个新位图,会发生什么?这样我们可以缩小问题的范围。另一个链接:。请注意关于
    的部分,记住PNG图像是“特殊的”
    。我非常感谢您提供的详细信息。肯定在那里学到了一些东西。我会看看我是否能证实这些事情。在此期间,我已经切换到JPEG,因为它是一个生产应用程序,我需要它来工作。但是,我确实想看看能否让PNG正常工作,因为这将是一个更好的解决方案。我的下一个建议是在新的位图(…)构造函数中尝试奇数个像素:-)
    switch (status)
    {
        case GenericError:
            return new ExternalException(SR.GetString(SR.GdiplusGenericError), E_FAIL);
    
        ...
    }