Thread: create Winapi Bitmaps Manually Using Pixel Arrays

  1. #1
    Registered User
    Join Date
    Nov 2006
    Posts
    4

    Cool Create 16/24BPP HBITMAP from pixel array


    Hi. I'm interesting in creating 16/24BPP WinAPI Bitmaps manually for a custom
    image file format. My CreateBitmap(...) code works for 32BPP, but not 16/24BPP.


    Code:
    /* Create 32BPP HBITMAP manually from pixel array */
    
    #pragma optimize("t", on)
    #define WIN32_LEAN_AND_MEAN
    #include <windows.h>
    
    #define name "Create HBITMAP"
    int screenw, screenh;
    HINSTANCE instance;
    HWND window;
    HDC sdc;
    LRESULT CALLBACK wproc(HWND w, UINT m, WPARAM wp, LPARAM lp);
    
    HBITMAP hbmp;
    
    const unsigned w=0xFFFFFF, b=0, y=0xFFFF00; // colors: white, black, yellow
    unsigned bmp[] = {  // example 8x8 face image
    w,w,b,b,b,b,w,w,
    w,b,y,y,y,y,b,w,
    b,y,b,y,y,b,y,b,
    b,y,b,y,y,b,y,b,
    b,y,y,y,y,y,y,b,
    b,y,b,b,b,b,y,b,
    w,b,y,y,y,y,b,w,
    w,w,b,b,b,b,w,w };
    
    int WINAPI WinMain(HINSTANCE hi, HINSTANCE na, PSTR c, int na2) {
    instance = hi;
    screenw = GetSystemMetrics(SM_CXSCREEN);
    screenh = GetSystemMetrics(SM_CYSCREEN);
    WNDCLASSEX wc = { 0x30, 0x23, wproc, 0, 0, hi, 0, (HCURSOR) LoadCursor(0,
    IDC_ARROW), (HBRUSH) GetStockObject(WHITE_BRUSH), 0, name, 0 };
    if (!RegisterClassEx(&wc) || !(window = CreateWindowEx(0, name, name,
    WS_POPUP|WS_VISIBLE, screenw/2-4, screenh/2-4, 8, 8, 0, 0, hi, 0)))
    return 1;
    
    hbmp = CreateBitmap(8, 8, 32, 1, bmp);
    
    MSG msg;
    for (;;) {
    if (!GetMessage(&msg, 0, 0, 0))
    return msg.wParam;
    TranslateMessage(&msg);
    DispatchMessage(&msg);
    }
    return msg.wParam;
    }
    
    LRESULT CALLBACK wproc(HWND w, UINT m, WPARAM wp, LPARAM lp) {
    if (m == WM_KEYDOWN && wp == VK_ESCAPE)
    PostQuitMessage(0);
    else if (m == WM_PAINT) {
    HDC dc = GetDC(window),
    mdc = CreateCompatibleDC(dc);
    SelectObject(mdc, hbmp);
    BitBlt(dc, 0, 0, 8, 8, mdc, 0, 0, SRCCOPY);
    ReleaseDC(window, dc);
    DeleteDC(mdc);
    }
    return DefWindowProc(w, m, wp, lp);
    }

    Here is a quote from MSDN:

    For a 16 bpp or 32 bpp non-palletized image, the color table must be three entries long; the entries must specify the value of the red, green, and blue (RGB) bitmasks. Because GDI ignores the color table for 24-bpp bitmaps, you should store the image pixels in RGB format.
    This doesn't even make sense. 15/16/24/32BPP do not have a palette. I know what bitmasks are -- ie, 11111.000000.00000 = R16 -- but what does that have to do with creating an image?

    Any help would be appreciated. Thank you.
    Last edited by Salem; 11-05-2006 at 10:56 AM. Reason: you only need code tags for code, nothing else

  2. #2
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > the entries must specify the value of the red, green, and blue (RGB) bitmasks.
    Like it says, a 3 entry table
    red would be 0xF800
    green would be 0x07E0
    blue would be 0x001F
    correponding to the masks it takes to extract an RGB from each 16-bit number in the pixel data.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  3. #3
    Registered User
    Join Date
    Nov 2006
    Posts
    4

    Question

    Hi Salem. Thanks for responding.

    What do they mean by "entries"? I assume they are referring to index 1 of the palette[0]. This would correspond to bytes 0-1 (16BPP) or 0-2 (24BPP), but it was not necessary in the 32BPP example I provided, despite the quote from MSDN: "For a 16 bpp or 32 bpp non-palletized image, the color table must be three entries long".

    All I'm trying to do is create a HBITMAP from a pixel array in 16/24/32BPP, then access the pixels directly. Anyone know how to do this?

    With my DOS 32BIT VESA library, I can easily create/draw/rotate/etc images, but I am not very experienced with Windows API. I use DirectDraw and custom controls/interfaces for all my applications.

  4. #4
    Registered User
    Join Date
    Nov 2006
    Posts
    4
    Ok, here's what I have so far. The DirectDraw version works, but the WinAPI HBITMAP version does not.
    Code:
    /**************************** IMAGE.H ***************************/
    
    #define DD // default
    //#define WIN // does not work
    
    // IMAGE STRUCTURE, 24/32 BYTES
    
    typedef struct {
    byte type[3], system;  // type = 0. system = 0=WIN, 1=DD, 2+=reserved
    dword x, y, w, h;      // location, size
    union {                // pixels
    HBITMAP hbmp;
    IDirectDrawSurface *surface;
    }
    } IMAGE;
    
    // LOAD, DRAW, CREATE, GET/SET PIXEL/S
    
    void loadi(IMAGE *i, char *fn);               // load .bmp/.tga/.i
    void drawi(IMAGE *i);                         // draw to current screen
    int newi(IMAGE *i, int w, int h, int bpp);    // create blank image
    int geti(IMAGE *i, void *data);               // get all pixels
    int seti(IMAGE *i, void *data);               // set all pixels
    dword getpi(IMAGE *i, int x, int y);          // get pixel at
    void setpi(IMAGE *i, int x, int y, dword c);  // set pixel at
    int copyi(IMAGE *i, IMAGE *i2);               // copy i pixels to i2
    int formati(IMAGE *i, int bpp, void *pal);    // convert to 1/2/4/8/15/16/24/32BPP
                                                  // pal/lette only if <= 8
    void killi(IMAGE *i);                         // delete
    
    // MOVE, SIZE, FLIP, ROTATE
    
    void movei(IMAGE *i, int x, int y);         // set location
    void movei(IMAGE *i, double vx, double vy); // move by velocity
    void sizei(IMAGE *i, int w, int h);         // size pixels
    void sizei(IMAGE *i, double percent);       // size by percent
    void sizewi(IMAGE *i, int w);               // size w
    void sizehi(IMAGE *i, int h);               // same with h
    void setsizei(int antialias, int maintain); // set sizex(IMAGE *i, ...)
    // properties: use antialias? 1/0. maintain proportions for sizehi/sizewi? 1/0
    void canvasi(IMAGE *i,                      // set canvas side insets, +/-
    int l, int t, int r, int b);
    void flipi(IMAGE *i, int d);                // flip HORIZONTAL/VERTICAL
    void rotatei(IMAGE *i, int d);              // rotate LEFT/RIGHT/CORNERS
    void rotateai(IMAGE *i, int degree);        // rotate arbitrary, 0-359
    void polyi(IMAGE *i, XY *points,            // create 2D polygon based on
    int x, int y, int accuracy);                // pixel at XY (for masks/fills).
                                                // accuracy=1-100%
    
    // LIGHT, COLOR, EFFECTS
    
    void lighti(IMAGE *i, int n);       // adjust light/darkness, -100 to 100%
    void huei(IMAGE *i, int n);         // adjust hue, 0-359
    void saturatei(IMAGE *i, int n);    // adjust gray/pure, -100 to 100%
    void morei(IMAGE *i, int c, int n); // more RGB. c=RED/GREEN/BLUE. n = 1-100%
    void replacei(IMAGE *i, dword c,    // replace all appearances of c with c2
    dword c2, int accuracy);            // accuracy = 1-100% (for "hue map" feature)
    void alphai(IMAGE *i, int n);       // adjust alpha. n = 0/opaque or 1-100%
    void contrasti(IMAGE *i, int n);    // sharpen/blur, -100 to 100
    Last edited by Ken Fitlike; 11-05-2006 at 10:18 AM. Reason: removed distracting fonts and ugly bold type

  5. #5
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    A bunch of function prototypes isn't going to help us figure out what you've done.

    Post your WinAPI version of the code which deals with bitmaps.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  6. #6
    Registered User
    Join Date
    Nov 2006
    Posts
    4
    Ken - "Please just stick to code tags - the universally applied extra fonts and bold type are overkill" - I use a text preprocessor that automatically formats code to Courier New bold 10, which is standard in 640x480 or 800x600. Sorry if it looks "overkill" *on your PC* or PDA, cell phone, etc.

    Salem - "Post your WinAPI version of the code which deals with bitmaps" - The very first example creates a 8x8x32 HBITMAP then displays it.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. how to create adjacent arrays in memory?
    By sudeepta in forum C++ Programming
    Replies: 3
    Last Post: 07-28-2008, 09:03 AM
  2. create variable size arrays
    By s-men in forum C Programming
    Replies: 6
    Last Post: 08-27-2007, 07:45 PM
  3. Button handler
    By Nephiroth in forum Windows Programming
    Replies: 8
    Last Post: 03-12-2006, 06:23 AM
  4. Create arrays with constructor problem
    By dee.dw in forum C Programming
    Replies: 7
    Last Post: 10-26-2005, 11:36 AM
  5. about arrays create within a struct~
    By Unregistered in forum C Programming
    Replies: 2
    Last Post: 04-26-2002, 04:21 AM