[.net] Drawing to a bitmap in vb.net

Started by
4 comments, last by Nik02 16 years ago
I'm currently working on a chip 8 emulator and I'm trying to set the color of every pixel in a bitmap that i created. For some reason, this code doesn't loop through the whole bitmap, only a small portion of it. I think it has something to do with the bitmap being 24bit. Is there anyway to change this?


Dim bmp As New Bitmap(64, 32)

        ' Lock the bitmap's bits.  
        Dim rect As New Rectangle(0, 0, bmp.Width, bmp.Height)
        Dim bmpData As System.Drawing.Imaging.BitmapData = bmp.LockBits(rect, _
            Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat)

        ' Get the address of the first line.
        Dim ptr As IntPtr = bmpData.Scan0

        ' Declare an array to hold the bytes of the bitmap.
        ' This code is specific to a bitmap with 24 bits per pixels.
        Dim bytes As Integer = bmp.Width * bmp.Height
        Dim rgbValues(bytes - 1) As Byte

        ' Copy the RGB values into the array.
        System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes)

        'set each pixel
         For i As Integer = 0 To 31
            For j As Integer = 0 To 63
                rgbValues(n) = pixel(j,i)
                n += 1
            Next j
        Next i

        ' Copy the RGB values back to the bitmap
        System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes)

        ' Unlock the bits.
        bmp.UnlockBits(bmpData)
Advertisement
You need to take into account that for a 24bpp image, each pixel is represented by 3 bytes instead of one. Your inline comment contradicts the fact that the logic seems to assume one-byte pixels.

You can explicitly request a bitmap of desired depth by specifying the pixel format in the Bitmap constructor. I recommend 32-bit alignment for several reasons.

As a side note: it is more optimal to fill your scanlines in the inner loop, and step the scanline pitch at the outer loop. This is due to the fact that adjacent pixels of a given scanline are also adjacent to each other in memory, and it is faster to access the memory if it is physically adjacent. Things like this do really matter in an application like an emulator, even though in usual programming tasks this might be considered a pre-mature optimization.

Niko Suni

So when the bitmap is 24bpp, how do i calculate where each scanline ends?
Don't forget that each line is bmpData.Stride wide.
To get the beginning of each line you have to mutiply the line counter with bmpData.Sride.

Quote:Original post by juergen1969
Don't forget that each line is bmpData.Stride wide.
To get the beginning of each line you have to mutiply the line counter with bmpData.Sride.



Thanks, but then how can I find and change the color of individual pixels, say like 23x12 or something?
Pixel [23,12] can be found in memory by multiplying the row index (12) with the pitch (memory width of a scanline) and adding (column index (23) * bytes per pixel) to it. In case of 24-bit (or 3-byte) pixels, the pixel would start here and also occupy the next two bytes, after which we would be on the next pixel. Having found the pixel, it is just the matter of modifying its bytes to change the color at said pixel.

Niko Suni

This topic is closed to new replies.

Advertisement