Question For Reed Kimple

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
You have given a answer:
< Quoting from other link...... >
___________________________________________________________________________________________________________________
A Point is a data structure which represents a two dimensional vector of X and Y coordinate data. A colored dot on the screen is called a Pixel. By the title, I expected this thread to be about keeping score in a game.
If you want to perform per-pixel operations on an image, the fastest way to do so in VB.Net is through the use of the LockBits method. But per-pixel operations are slow, and the more pixels you have, the longer the operation will take. In the example by CrazyPennie, you can only fill a 800x600 image in 12ms using a single graphics operation like FillRectangle. It would take much longer to fill an 800x600 image per-pixel using SetPixel (more like 500ms). But that is exactly why the suggestion by CrazyPennie is so good... you must really think about per-pixel operations and whether or not you MUST do them, or if you can find a better way.
If you determine that you must perform per-pixel operations on an image, then use LockBits and deal with the raw pixel data in a byte array.
The following example shows you how to use LockBits and lets you see the difference between it and SetPixel. This code implements the per-pixel operation from your example:
For y = 0 To Height - 1
For x = 0 To Width - 1
Set Pixel at [X,Y] to Random Color
Next x
Next y
The time to generate an 800x600 random image on my laptop is about 46ms. A larger image will take longer, and a smaller image will be faster. The time will also be affected by the cpu power of the computer running the code.Option Strict On

Public Class Form1
Friend WithEvents Button1 As New Button With {.Dock = DockStyle.Top, .Text = "Generate Random Image"}
Friend WithEvents CheckBox1 As New CheckBox With {.Dock = DockStyle.Top, .Text = "Use SetPixel instead of LockBits"}
Friend PictureBox1 As New PictureBox With {.Dock = DockStyle.Fill, .BorderStyle = BorderStyle.Fixed3D}

Private _Colors() As Color = {Color.Red, Color.Orange, Color.Yellow, Color.Green, Color.Blue, Color.Indigo, Color.Violet}
Private _Random As New Random

Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Me.Size = New Size(1024, 768)
Me.Controls.Add(PictureBox1)
Me.Controls.Add(CheckBox1)
Me.Controls.Add(Button1)
End Sub

Private Sub Button1_Click(sender As Object, e As System.EventArgs) Handles Button1.Click
Dim img As New Bitmap(800, 600) create new image
Dim data As System.Drawing.Imaging.BitmapData = Nothing
Dim bytes((800 * 600 * 3) - 1) As Byte create byte array with 3 bytes per pixel

Dim useSetPixel As Boolean = CheckBox1.Checked
Dim sw As New Stopwatch

sw.Start()
If Not useSetPixel Then
get 24 bit-per-pixel (3 byte) color data for entire image
data = img.LockBits(New Rectangle(0, 0, 800, 600), Imaging.ImageLockMode.ReadWrite, Imaging.PixelFormat.Format24bppRgb)
copy raw color data to managed array
System.Runtime.InteropServices.Marshal.Copy(data.Scan0, bytes, 0, bytes.Length)
End If

For y As Integer = 0 To 599
For x As Integer = 0 To 799
Dim c As Color = GetRandomColor()
If Not useSetPixel Then
Dim i As Integer = (y * 800 * 3) + (x * 3) calculate pixel position in byte array
bytes(i) = c.B byte order is opposite color order, so RGB = Blue, Green, Red
bytes(i + 1) = c.G
bytes(i + 2) = c.R
Else
img.SetPixel(x, y, c)
End If
Next
Next

If Not useSetPixel Then
copy modified bytes from managed array back to raw color data
System.Runtime.InteropServices.Marshal.Copy(bytes, 0, data.Scan0, bytes.Length)
unlock the image (release raw color data)
img.UnlockBits(data)
End If
sw.Stop()

If PictureBox1.Image IsNot Nothing Then
clean up old image, if any
Dim tmp As Image = PictureBox1.Image
PictureBox1.Image = Nothing
tmp.Dispose()
End If

show new image and update result time
PictureBox1.Image = img
Me.Text = String.Format("Random Image Generated in: {0:n2} ms.", sw.Elapsed.TotalMilliseconds)
End Sub

Private Function GetRandomColor() As Color
Return _Colors(_Random.Next(0, _Colors.Length))
End Function
End Class


Reed Kimble - "When you do things right, people wont be sure youve done anything at all"
__________________________________________________________________________________________________
< Complete >
Can you convert your function to this:Class Screen
Public Screen()() as pixel
Public Function DrawScreen(Place as PictureBox,Screen()() as pixel)
me.screen = screen
-Add Code Block To Create Function-
End Function
End Class

Help neeeeeeeeeeeeeeeeeeeeeeeed
Allow time to reverse.

View the full article
 
Back
Top