English 中文(简体)
Copy bytes in memory to an Array in VB.NET
原标题:

unfortunately I cannot resort to C# in my current project, so I ll have to solve this without the unsafe keyword.

I ve got a bitmap, and I need to access the pixels and channel values directly. I d like to go beyond Marshal.ReadByte() and Marshal.WriteByte() (and definitely beyond GetPixel and SetPixel).

Is there a way to put all the pixel data of the bitmap into a Byte array that works on both 32 and 64 bit systems? I want the exact same layout as the original bitmap, so the padding for each row (if it exists) also needs to be included.

Marshal doesn t seem to have something akin to:

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

Unless I totally missed it...

Any help greatly appreciated, David

ps. So far all my images are in 32BppPArgb pixelformat.

最佳回答

Marshal does have a Method that does exactly what you are asking. See Marshall.Copy()

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

Copies data from an unmanaged memory pointer to a managed 8-bit unsigned integer array.

And there are overloads to go the other direction as well

问题回答

Would something like this do? (untested):

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

It won t let you manipulate the pixels in a Drawing.Bitmap object directly, but it will let you copy that bitmap to a byte array, as per the question title.

Another option is serialization via the BinaryFormatter, but I think that will still require you to pass it through a MemoryStream.

VB does not offer methods for direct memory access. You have two choices:

  1. Use the Marshal class
  2. Write a small unsafe C# (or C++/CLI) library that handles only these operations and reference it from your VB code.

Alright, there is a third option. VB.Net does not inherently support direct memory access, but it can be accomplished. It s just ugly and prone to errors. Nonetheless, if you re willing to put in the effort, you can try building a bitmap access library using these techniques combined with the approach referenced previously.

shf301 is right on the money, but I d like to add a link to a comprehensive explanation/tutorial on fast pixel data access. Rather than saving the image to a stream and accessing a file-in-memory, it would be better to lock the bitmap, copy pixel data out, access it, and copy it back in. The performance of this technique is pretty good.

Code is in c#, but the approach is language-neutral and easy to read.

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





相关问题
Is Shared ReadOnly lazyloaded?

I was wondering when I write Shared ReadOnly Variable As DataType = New DataType() Or alternatively Shared ReadOnly Variable As New DataType() Is it lazy loaded or as the instance initializes? ...

Entertaining a baby with VB.NET

I would like to write a little application in VB.NET that will detect a baby s cry. How would I get started with such an application?

Choose Enter Rather than Pressing Ok button

I have many fields in the page and the last field is a dropdown with list of values. When I select an item in a dropdown and press Enter, it doesn t do the "Ok". Instead I have to manually click on Ok ...

ALT Key Shortcuts Hidden

I am using VS2008 and creating forms. By default, the underscore of the character in a textbox when using an ampersand is not shown when I run the application. ex. "&Goto Here" is not ...

Set Select command in code

On button Click I want to Set the Select command of a Gridview. I do this and then databind the grid but it doesn t work. What am i doing wrong? protected void bttnView_Click(object sender, ...

Hover tooltip on specific words in rich text box?

I m trying to create something like a tooltip suddenly hoovering over the mouse pointer when specific words in the richt text box is hovered over. How can this be done?

热门标签