Faster image processing?

J

Jeremy

I am defining a bitmap pixel by pixel, and I searched through the documentation,
but could not find an obvious fast way to do what I want. My first attempt used
the underlying graphics object to draw 1 by 1 rectangles. This was SLOOOOOOW.
It took about 1800 milliseconds for a bitmap that was pretty small. Using the
following code, I got it down to 500 milliseconds, but that is still pretty slow.

For y As Integer = 0 To bmp.Height - 1
For x As Integer = 0 To bmp.Width - 1
bmp.SetPixel(x, y, SomeColor)
Next
Next

I'm looking for something like Java's MemoryImageSource class where I can just
create an array of values, then create an Image from that. Any ideas?
 
H

Herfried K. Wagner [MVP]

* (e-mail address removed) (Jeremy) scripsit:
I am defining a bitmap pixel by pixel, and I searched through the documentation,
but could not find an obvious fast way to do what I want. My first attempt used
the underlying graphics object to draw 1 by 1 rectangles. This was SLOOOOOOW.
It took about 1800 milliseconds for a bitmap that was pretty small. Using the
following code, I got it down to 500 milliseconds, but that is still pretty slow.

For y As Integer = 0 To bmp.Height - 1
For x As Integer = 0 To bmp.Width - 1
bmp.SetPixel(x, y, SomeColor)
Next
Next

<URL:http://www.google.de/groups?q=dotnet+lockbits+vb+marshal.copy>
 
J

Jeremy

Thanks everyone for your help! This code runs in about 25 ms, which is
more than acceptable.
Private Sub Draw1()
Dim lStart, lEnd As Integer

lStart = Environment.TickCount
If bmpDouble Is Nothing Then
bmpDouble = New Bitmap(Panel1.Width, Panel1.Height,
System.Drawing.Imaging.PixelFormat.Format32bppArgb)
ReDim buffer(bmpDouble.Width * 4 * bmpDouble.Height)
End If

Dim bmd As System.Drawing.Imaging.BitmapData

With bmpDouble
bmd = .LockBits(New Rectangle(0, 0, .Width, .Height), _
Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format32bppRgb)
For y As Integer = 0 To .Height - 1
For x As Integer = 0 To .Width - 1
Dim bufferIndex, Argb As Integer
Argb = Colors((Values(y, x) Mod 255 + iOffset) Mod 255).ToArgb
buffer(bufferIndex) = CByte((Argb And &HFF0000) \ CInt(2 ^ 16))
buffer(bufferIndex + 1) = CByte((Argb And &HFF00) \ CInt(2 ^ 8))
buffer(bufferIndex + 2) = CByte(Argb And &HFF)
bufferIndex += 4
Next
Next
Runtime.InteropServices.Marshal.Copy(buffer, 0, bmd.Scan0, _
.Width * 4 * .Height)
.UnlockBits(bmd)
End With

lEnd = Environment.TickCount
lblDrawTime.Text = CStr(lEnd - lStart)
gMain.DrawImage(bmpDouble, 0, 0)

End Sub
 
A

Armin Zingler

Jeremy said:
buffer(bufferIndex) = CByte((Argb And &HFF0000) \ CInt(2
^ 16))

dividing by &H10000...
buffer(bufferIndex + 1) = CByte((Argb And &HFF00) \ CInt(2 ^
8)) buffer(bufferIndex + 2) = CByte(Argb And &HFF)

resp. by &H100

would be even faster.

In VB 2003, use >> 16 resp. >> 8. Should be more faster.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top