【问题标题】:Creating very large bitmaps in c# (over 65 535pixels in size)在 C# 中创建非常大的位图(超过 65 535 像素)
【发布时间】:2017-05-12 16:32:24
【问题描述】:

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

我想过使用包含从 0 到 255 的灰度颜色的字节数组,但我不知道该怎么做。 (当然,图像是灰度颜色。)

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

【问题讨论】:

标签: c#


【解决方案1】:

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

要使用刚刚保存的字节数组创建位图,您必须创建一个具有所需大小的空位图,并使用 LockBitsUnlockBits 设置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 一个 1 锁定,从 byteArray (RawBitmapImage.Data) 复制适当的数据块并将它们复制到扫描中使用 Marshal.Copy 指向您的位图数据的指针(非常快,我尝试使用 200 000pixel * 5000pixel 进行图像处理,并且需要大约 200ms 来加载)。

创建完所有位图后,只需对 graphicsContext.DrawImage 进行多次绘制调用,然后将它们一一绘制,指定适当的源和目标到屏幕。

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

【讨论】:

  • 仅供参考,数组也不是无限大小的,它们只能通过使用从 0 开始的有符号整数来访问,因此最多可以容纳 2147483648 个元素。 (您还需要将 gcAllowVeryLargeObjects 设置为 true)
  • 谢谢!编辑了我的答案!我希望这对将来的其他人有用。
猜你喜欢
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-24
相关资源
最近更新 更多