在c#中创建非常大的位图(大小超过65 535像素)

时间:2017-05-12 16:32:24

标签: c#

我目前正在开发一个项目,要求图像大小超过80,000像素。我知道C#中的Bitmap最多只允许65,635个宽度。

我想过使用包含从0到255的灰度颜色的字节数组,但我不知道如何做到这一点。 (当然,图像采用灰度颜色。)

我如何生成那种文件/图像并将其保存在我的机器上以备将来使用?

1 个答案:

答案 0 :(得分:2)

我的解决方案是将图像保存为字节数组数据,其大小为2 147 483 648(取决于您使用的是32bpp图像还是8bpp,它可能会因 2 147 483 648像素而异 8bpp 的图像为536 870 912像素,32bpp 。您还可能必须允许gcAllowVeryLargeObjects为true才能启用该大小的数据。一旦完成,当您想要将图像显示到您的拥有自己的查看器/ winforms /或类似的东西,你必须实现一个位图数组,其中包含构成最终图像的多个位图。我建议拥有32个768像素的大图像,因为Graphics.DrawImage只允许你绘制最多32个768pixel。

要使用刚刚保存的字节数组创建位图,您必须创建一个所需大小的空位图,并使用 LockBits UnlockBits 来设置byteArray数据直接进入您的位图。你可以使用这样的东西来完成工作:

BitmapData bmpData = m_ImageArray[range.Item1].LockBits(new Rectangle(0, 0, m_ImageArray[range.Item1].Width, m_ImageArray[range.Item1].Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
              IntPtr scan = bmpData.Scan0;

              for (int i = 0; i < m_ImageArray[range.Item1].Height; i++)
              {
                 System.Runtime.InteropServices.Marshal.Copy(RawBitmapImage.Data, i * ImageWidth + range.Item1 * firstBitmapWidth, scan, m_ImageArray[range.Item1].Width);
                 scan += bmpData.Stride;
              }

              m_ImageArray[range.Item1].UnlockBits(bmpData);

上面的代码是将数组1的每个位图的lockBits加1,从byteArray( RawBitmapImage.Data )复制适当的数据块并将它们复制到扫描中,即使用 Marshal.Copy 指向您的位图数据的指针(非常快,我尝试使用 200 000pixel * 5000像素的图像并且需要 200ms 来加载)。

一旦创建了所有位图,只需对graphicsContext.DrawImage进行多次绘制调用,然后逐个绘制它们,指定屏幕的相应源和目标。

如果您需要任何帮助,或有任何问题,请随时发表评论!