Sign in to follow this  

[.net] Drawing to a bitmap in

Recommended Posts

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.

Share this post

Link to post
Share on other sites
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.

Share this post

Link to post
Share on other sites
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?

Share this post

Link to post
Share on other sites
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.

Share this post

Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this