【问题标题】:Copy bytes in memory to an Array in VB.NET将内存中的字节复制到 VB.NET 中的数组
【发布时间】:2010-12-16 02:12:50
【问题描述】:

不幸的是,我在当前项目中无法使用 C#,所以我必须在没有 unsafe 关键字的情况下解决这个问题。

我有一个位图,我需要直接访问像素和通道值。我想超越 Marshal.ReadByte() 和 Marshal.WriteByte()(肯定超越 GetPixel 和 SetPixel)。

有没有办法将位图的所有像素数据放入一个可在 32 位和 64 位系统上工作的字节数组中?我想要与原始位图完全相同的布局,因此还需要包括每一行的填充(如果存在)。

元帅似乎没有类似的东西:

byte[] ReadBytes(IntPtr start, int offset, int count)

除非我完全错过了......

非常感谢任何帮助, 大卫

ps。到目前为止,我所有的图像都是 32BppPArgb 像素格式。

【问题讨论】:

  • 只是要明确一点:数据当前在内存中的情况如何?你能将它加载到 System.Drawing.BitMap 中,还是通过 MemoryStream 加载?
  • @Joel,它存储为常规的 Drawing.Bitmap,很可能是使用 GDI+ 图形对象从头开始生成的。
  • 绝对准确地说,在 99% 的情况下,它将是在资源中存储为 32BppArgb 位图的图像。该图像被绘制到相同尺寸的空白 32BppPArgb 位图上,因为它必须经常被显示在屏幕上。图像通常很小(24x24 像素),但我需要处理数百个,因此需要超快速访问...

标签: vb.net memory bitmap marshalling bytearray


【解决方案1】:

Marshal 确实有一个方法可以完全满足您的要求。见Marshall.Copy()

public static void Copy(
    IntPtr source,
    byte[] destination,
    int startIndex,
    int length
   )

从非托管内存复制数据 指向托管 8 位无符号的指针 整数数组。

还有其他方向的重载

【讨论】:

  • 太棒了!非常感谢。这确实正是我想要的。
【解决方案2】:

这样的事情可以吗? (未经测试):

Public Shared Function BytesFromBitmap(ByVal Image As Drawing.Bitmap) As Byte()
   Using buffer As New IO.MemoryStream()
        image.Save(result, Drawing.Imaging.ImageFormat.Bmp)

        Using rdr As New IO.BinaryReader(buffer)
            Return rdr.ReadBytes(buffer.Length)
        End Using
    End Using
End Function

它不会让您直接操作 Drawing.Bitmap 对象中的像素,但它可以让您将该位图复制到字节数组中,根据问题标题。

另一种选择是通过 BinaryFormatter 进行序列化,但我认为这仍然需要您通过 MemoryStream 传递它。

【讨论】:

  • 有趣的解决方案。它可能会起作用,但它只能完成一半的工作。如何让字节数组再次回到位图中?
  • System.Drawing.Bitmap.FromStream() 函数。
  • 您也可以直接对内存流进行一些更改,并在其中节省一些步骤。
【解决方案3】:

VB 不提供直接访问内存的方法。你有两个选择:

  1. 使用 Marshal 类
  2. 编写一个不安全的小型 C#(或 C++/CLI)库,仅处理这些操作并从您的 VB 代码中引用它。

好的,还有第三种选择。 VB.Net 本身并不支持直接内存访问,但可以实现。它只是丑陋且容易出错。尽管如此,如果您愿意付出努力,您可以尝试使用these techniques 结合前面提到的方法构建位图访问库。

【讨论】:

  • 如何使用 Marshal 类一次性将整个字节块复制到字节数组中?正如我在问题中指出的那样 Marshal.ReadByte 和 unsafe 目前不是一个选项。
  • 您不能使用 Marshal 类一次性完成所有操作 - 我建议您可能必须修改您的约束,因为它们似乎是互斥的。但是,我更新了我的答案以添加第三个(非常复杂的)选项。如果您决定走这条路,请与全世界分享您的纯 VB.Net 高性能位图库!
  • 很有趣,看起来它带有承诺。谢谢!
  • 链接到的文章是VB6。
【解决方案4】:

shf301 物有所值,但我想添加一个链接,指向有关快速像素数据访问的全面解释/教程。与其将图像保存到流中并访问内存中的文件,不如锁定位图,将像素数据复制出来,访问它,然后将其复制回来。这种技术的性能非常好。

代码是用 c# 编写的,但这种方法与语言无关且易于阅读。

http://ilab.ahemm.org/tutBitmap.html

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-10-05
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多