我最近安装了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文件),该方法被多次调用。
  • encodePixelWidth/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色位图的一个非常奇怪的错误(我的所有图像都是从我用QBasic编写的上学日游戏中拍摄的256色位图)。

  • 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# - 仅在Windows 8.1中为BitmapImage OutOfMemoryException,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/20872510/

  • 10-09 22:04