Frobot
Frobot

Reputation: 1283

Editing bitmap in memory using C++

I have a two dimensional array of data that I want to display as an image.
The plan goes something like this -
Create a bitmap using CreateCompatibleBitmap (this results in a solid black bitmap and I can display this with no problems)
Edit the pixels of this bitmap to match my data
BitBlt the bitmap to the window

I think that I need a pointer to the place in memory where the pixel data begins. I've tried many different methods of doing this and googled it for 3 days and still haven't been able to even edit a single pixel.
Using a loop of SetPixel(HDC, x, y, Color) to set each pixel works but VERY slowly. I have accomplished this in C# by locking the bitmap and editing the bits, but I am new to C++ and can't seem to figure out how to do something similar.

I have mostly been trying to use memset(p, value, length) For "p" I have tried using the handle returned from CreateCompatibleBitmap, the DC for the bitmap, and the DC for the window. I have tried all sorts of values for the value and length.
I'm not sure if this is the right thing to use though.

I don't have to use a bitmap, that's just the only thing I know to do. Actually it would be awesome to find a way to directly change the main window's DC. I do want to avoid libraries though. I am doing this purely for learning C++.

Upvotes: 1

Views: 2806

Answers (2)

Frobot
Frobot

Reputation: 1283

This took QUITE a bit of research so I'll post exactly how it is done for anyone else who may be looking. This colors every pixel red.

hDC = BeginPaint(hWnd, &Ps);

    const int
        width = 400,
        height = 400,
        size = width * height * 3;
    byte * data;
    data = new byte[size];
    for (int i = 0; i < size; i += 3)
    {
        data[i] = 0; 
        data[i + 1] = 0;
        data[i + 2] = 255;
    }

    BITMAPINFOHEADER bmih;
    bmih.biBitCount = 24;
    bmih.biClrImportant = 0;
    bmih.biClrUsed = 0;
    bmih.biCompression = BI_RGB;
    bmih.biWidth = width;
    bmih.biHeight = height;
    bmih.biPlanes = 1;
    bmih.biSize = 40;
    bmih.biSizeImage = size;

    BITMAPINFO bmpi;
    bmpi.bmiHeader = bmih;
    SetDIBitsToDevice(hDC, 0, 0, width, height, 0, 0, 0, height, data, &bmpi, DIB_RGB_COLORS);
    delete[] data;

Upvotes: 1

MichaelCMS
MichaelCMS

Reputation: 4763

memset can be used on the actually RGB information array (but you need to also know the format of the bitmap, if a pixel has 32 or 24 bits ).

From a bit of research on msdn, it seems that what you want to get is the BITMAP structure : http://msdn.microsoft.com/en-us/library/k1sf4cx2.aspx

There you have the bmBits on which you can memset.

How to get there from your function ?

Well, CreateCompatibleBitmap returns a HBITMAP structure and it seems you can get BITMAP from HBITMAP with the following code :

BITMAP bmp;
GetObject(hBmp, sizeof(BITMAP), &bmp); 

This however seems to get a you copy of the existing bitmap info, which only solves your memset problem (you can now set the bitmap information with memset, eventhou I don't see any other use for memeset besides making the bmp all white or black).

There should be a function that allows you to set the DC bites to a bitmap thou, so you should be able to use the new bitmap as a parameter.

Upvotes: 0

Related Questions