无法在C#中保存非常大的位图对象

时间:2016-01-09 23:14:59

标签: c# .net bitmap drawing gdi+

我目前正在尝试创建一个程序,将多个图像拼接在一起以创建一个大图像(在x64中)。图像分辨率约为3000x7500,总共约为35左右。

我已经设法达到了我能够通过VirtualAlloc在内存中创建位图的地步

        UIntPtr dataSize = new UIntPtr((ulong)stride * (ulong)height);
        IntPtr p = VirtualAlloc(IntPtr.Zero, dataSize, AllocationType.COMMIT | AllocationType.RESERVE, MemoryProtection.READWRITE);            
        using (Bitmap bmpStitched = new Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format32bppRgb, p))

使用这个位图对象,我可以完成我想要的所有操作,在较小的文件子集上测试它以验证它是否有效。但是,当我来保存位图对象时,我得到了可怕的'GDI +中发生了一般错误'。例外。

有没有办法让图像保存?我尝试了不同的扩展,并将其转换为字节数组,但保存到内存流会遇到同样的异常。

编辑: 继下面的评论之后,堆栈跟踪是:

    at System.Drawing.Image.Save(String filename, ImageCodecInfo encoder, EncoderParameters encoderParams)
       at PictureStitcher.PictureStitcher.StitchFiles(FileInfo[] files, String strTargetFile) 
in c:\Users\Chris\Documents\Save as Picture\PictureStitcher\PictureStitcher\PictureStitcher\PictureStitcher.cs:line 186

使用失败的代码:

        int bytesPerPixel = 4;
        int padding = 4 - ((width * bytesPerPixel) % 4);
        padding = (padding == 4 ? 0 : padding);
        int stride = (width * bytesPerPixel) + padding;
        UInt32[] pixels = new UInt32[width * height];
        GCHandle gchPixels = GCHandle.Alloc(pixels, GCHandleType.Pinned);

        UIntPtr dataSize = new UIntPtr((ulong)stride * (ulong)height);
        IntPtr p = VirtualAlloc(IntPtr.Zero, dataSize, AllocationType.COMMIT | AllocationType.RESERVE, MemoryProtection.READWRITE);            
        using (Bitmap bmpStitched = new Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format32bppRgb, p))
        {
          using (Graphics g = Graphics.FromImage(bmpStitched))
          {
            g.Clear(SystemColors.AppWorkspace);
            foreach (FileInfo file in files)
            {
              Console.WriteLine(file.FullName);
              using (Image img = Image.FromFile(file.FullName))
              {
                if (nIndex == 0)
                {
                  g.DrawImage(img, new Point(0, 0));
                  nIndex++;
                  width = img.Width;
                }
                else
                {
                  g.DrawImage(img, new Point(width, 0));
                  width += img.Width;
                }
              }
            }
          }

          System.GC.Collect();
          System.GC.WaitForPendingFinalizers();

          bmpStitched.Save(strTargetFile, imgFormat);
          bmpStitched.Dispose();

在'bmpStitched.Save(strTargetFile,imgFormat);'上抛出异常线。

非常感谢, 克里斯

0 个答案:

没有答案