Here is an example that uses Marshal.Copy
to move the entire bitmap at once. The bitmap format must be Format8bppIndexed
so that you can move the raw data directly into the bitmap object rather than convert each pixel to 24bpp manually. The 8bpp indexed format can actually display any 8-bit subset of 24-bit colours so you need to define a colour palette for the image. I'm assuming you want greyscale, so the palette is just a 1:1 map.
For this you'll need the following imports :
Imports System.Drawing.Imaging
Imports System.Runtime.InteropServices
Then :
Function ConvertBytesToBitmap(ByVal inBytes() As Byte, _
ByVal imgWidth As Integer, _
ByVal imgHeight As Integer) As Bitmap
Dim b As New Bitmap(imgWidth, imgHeight, PixelFormat.Format8bppIndexed)
' Define a greyscale colour palette
Dim ncp As ColorPalette = b.Palette
Dim i As Integer
For i = 0 To 255
ncp.Entries(i) = Color.FromArgb(255, i, i, i)
Next
b.Palette = ncp
' Copy the bytes to the bitmap's data region
Dim BoundsRect As New Rectangle(0, 0, imgWidth, imgHeight)
Dim bmpData As BitmapData = b.LockBits(BoundsRect, _
ImageLockMode.WriteOnly, _
b.PixelFormat)
' Bitmap.Scan0 returns a pointer to the image data array
' The data format is a 1D array, row-major format
Dim ptr As IntPtr = bmpData.Scan0
Dim numberOfBytes As Integer = bmpData.Stride * b.Height
Marshal.Copy(inBytes, 0, ptr, numberOfBytes)
b.UnlockBits(bmpData)
Return b
End Function
To show an example of usage, I've chosen a 400x200 pixel image and have filled it with a horizontal gradient :
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim i As Integer
Dim j As Integer
' Create example image buffer for 400x200px image
Dim imgBuffer(79999) As Byte
' Fill example image buffer with horizontal gradient
For i = 0 To 199
For j = 0 To 399
imgBuffer(j + i * 400) = 255 * j / 400
Next
Next
PictureBox1.Image = ConvertBytesToBitmap(imgBuffer, 400, 200)
End Sub
The function above is not fully optimized for your purposes, of course. You could skip re-creating the greyscale palette each time and save a copy, either passing it in as an argument or building it into a class, etc. This could save a bit of time. Still, this should be several thousands of times faster than the code you are using, even if you create the colour palette each time.