我最近安装了 Windows 8.1 来尝试,但我的宠物项目在它上面崩溃了(相同的二进制文件在一台 Win7 和两台 Win8 机器上运行良好)。
在 BitmapImage.EndInit 中抛出 OutOfMemoryException:
public static BitmapImage GetResourceImage(string resourcePath, int decodePixelWidth = 0, int decodePixelHeight = 0)
{
var image = new BitmapImage();
var moduleName = Assembly.GetExecutingAssembly().GetName().Name;
var resourceLocation = string.Format("pack://application:,,,/{0};component/Resources/{1}", moduleName, resourcePath);
image.BeginInit();
image.UriSource = new Uri(resourceLocation);
image.DecodePixelWidth = decodePixelWidth;
image.DecodePixelHeight = decodePixelHeight;
image.EndInit();
image.Freeze();
return image;
}
- 崩溃时进程的任务管理器读数:27MB 内存、302 个句柄、12 个线程、36 个用户对象、34 个 GDI 对象、5.3 GB 可用内存
- 平台目标是 x86(需要使用 native DLL)
- 针对不同(随机)图像多次调用方法(资源中有约 250 个 bmp 文件)
- decodePixelWidth/Height 是随机的,但在有效范围内
- 异常发生在不同的资源路径和大小
- 只有当 DecodePixelWidth 或 DecodePixelHeight 不为 0 时才会发生异常
- 如果我注释掉 DecodePixelWidth 和 DecodePixelHeight setter 并让它加载到原始大小,则不会发生异常
据我通过谷歌搜索了解到,它与 GDI 内部结构有关,但我找不到修复或解决方法。有什么想法(除了使用其他机制来解码和/或调整图像大小——我只需要原始像素数据)?
完整的项目源代码可以在这里找到(链接是相关文件):https://code.google.com/p/lander-net/source/browse/trunk/csharp/LanderNet/Util/BitmapUtils.cs
更新: 我尝试使用 TransformedBitmap 来调整大小,它失败并出现相同的异常。
最佳答案
我已经创建了一个单独的项目并隔离了问题。 看起来像是 GDI 中一个非常奇怪的错误,带有 256 色位图(我所有的图像都是 256 色位图,取 self 用 QBasic 编写的学生时代游戏)。
- png 和 24 位位图没有问题
- 加载 24 位位图后,调整 256 色位图大小的问题似乎消失了
所以我的问题通过将所有内容都转换为 PNG 得到解决。
错误已发布到 Microsoft Connect:https://connect.microsoft.com/VisualStudio/feedback/details/812641/bitmapsource-fails-with-outofmemoryexception-on-8-bit-bitmaps
下面是代码。
internal class Program
{
public static BitmapSource GetResourceImage(string resourcePath, int decodePixelWidth = 0,
int decodePixelHeight = 0)
{
var image = new BitmapImage();
var moduleName = Assembly.GetExecutingAssembly().GetName().Name;
var resourceLocation = string.Format("pack://application:,,,/{0};component/Resources/{1}", moduleName, resourcePath);
image.BeginInit();
image.UriSource = new Uri(resourceLocation);
image.DecodePixelWidth = decodePixelWidth;
image.DecodePixelHeight = decodePixelHeight;
image.EndInit();
image.Freeze();
return image;
}
private static void Main()
{
new Application(); // register pack uri scheme
//GetResourceImage("Z40100.png");
//GetResourceImage("Z40100.bmp");
//GetResourceImage("Z40100_256color.bmp");
//GetResourceImage("Z40100_24bit.bmp");
// Uncomment the following line to fix the crash (or any of the two lines above)
//GetResourceImage("Z40100_24bit.bmp", 50, 50);
//GetResourceImage("Z40100_256color.bmp", 50, 50);
GetResourceImage("Z40100.bmp", 50, 50);
// GetResourceImage("Z40100.png", 50, 50);
}
}
关于c# - BitmapImage OutOfMemoryException 仅在 Windows 8.1 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20872510/