Prev: Memory leak after closing thread. (Windows CE)
Next: How to AdjustTokenPrivileges() after ImpersonateLoggedOnUser() ?
From: Friedel Jantzen on 7 Dec 2009 03:19 Hi! > What commands can I look up to add a palette to a bitmap. I created a > 16 color palette because I didn't want to add in 256 colors. What I > want to do is create a bitmap that is not just monochrome. > > I am looking for how to create the bitmap then attach the pixel data > and the palette. The bmp palette is an array of RGBQUAD, following the BITMAPINFOHEADER. With biBitCount = 4 you provide an array RGBQUAD palette[16]; ZeroMemory(palette, sizeof(palette)); BYTE blue = 0, green = 0, red = 0; for(int i = 0; i < 16; i++) { palette[i].rgbBlue = blue; palette[i].rgbGreen = green; palette[i].rgbRed = red; //palette[i].rgbReserved = 0; blue += 16; // what you want red += 4; // " // green ... } Of course you can write this array into an alloced memory block after the header. For the 4bit format image data 1 byte includes 2 pixel indices into the palette. E.g. a width of 16px results in an 8 byte scanline, no padding required in this case. The data for a height of 16 is sized 8*16 bytes then. > This what I have for my current bitmap. > > BYTE cdata[] = {0xff, 0xff, 0xff, > 0,0,0, > 0xff,0,0, ... > //RGB Color data > > int num = 16; > BYTE * pdata = &cdata[0]; > > int datasz = 3*num; > int count = 0; > > while(count < datasz/num ){ > > bfo.bmColor[count].rgbRed = *pdata++; > bfo.bmColor[count].rgbBlue = *pdata++; > bfo.bmColor[count].rgbGreen = *pdata++; > bfo.bmColor[count].rgbReserved = PC_NOCOLLAPSE;; > count++; > } > > (I create a palette very similar to this in DX. But I can't figure > out how to add the palette to the bitmap.) > > BITMAP bitmap = {0,16,16,2,1,1}; This means a bmp width of 16, so you must write (see above): BITMAP bitmap = {0,16,16,8,1,4}; > bitmap.bmBits = data; //Pixel data > > hbitmap = CreateBitmapIndirect(&bitmap); Here you are creating a HBITMAP object (not a DIB!) > hdc = GetDC(hwnd); > HDC hdcmem = CreateCompatibleDC(hdc); > > SelectObject(hdcmem, hbitmap); Here you select a 4bits/px hbmp into a hdcmem compatible to your window, which could have different bits/px. I am not sure that this works, and prefer to create the bitmap object with CreateCompatibleBitmap. But then you cannot choose the bits/px, it is set automatically to the correct value. > BitBlt(hdc, 100, 150, 16, 16 , hdcmem, 0, 0, > SRCCOPY); > > DeleteDC(hdcmem); > ReleaseDC(hwnd, hdc); Note: Your HBITMAP object is not yet deleted. Have a look at CreateDIBSection, perhaps this fits better for your needs. hth, Friedel
From: JoeC on 7 Dec 2009 22:55 On Dec 7, 2:19 am, Friedel Jantzen <nospam_...(a)freenet.de> wrote: > Hi! > > > What commands can I look up to add a palette to a bitmap. I created a > > 16 color palette because I didn't want to add in 256 colors. What I > > want to do is create a bitmap that is not just monochrome. > > > I am looking for how to create the bitmap then attach the pixel data > > and the palette. > > The bmp palette is an array of RGBQUAD, following the BITMAPINFOHEADER. > With biBitCount = 4 you provide an array > RGBQUAD palette[16]; > ZeroMemory(palette, sizeof(palette)); > BYTE blue = 0, green = 0, red = 0; > for(int i = 0; i < 16; i++) { > palette[i].rgbBlue = blue; > palette[i].rgbGreen = green; > palette[i].rgbRed = red; > //palette[i].rgbReserved = 0; > blue += 16; // what you want > red += 4; // " > // green ... > > } > > Of course you can write this array into an alloced memory block after the > header. > For the 4bit format image data 1 byte includes 2 pixel indices into the > palette. E.g. a width of 16px results in an 8 byte scanline, no padding > required in this case. The data for a height of 16 is sized 8*16 bytes > then. > > > > > This what I have for my current bitmap. > > > BYTE cdata[] = {0xff, 0xff, 0xff, > > 0,0,0, > > 0xff,0,0, ... > > //RGB Color data > > > int num = 16; > > BYTE * pdata = &cdata[0]; > > > int datasz = 3*num; > > int count = 0; > > > while(count < datasz/num ){ > > > bfo.bmColor[count].rgbRed = *pdata++; > > bfo.bmColor[count].rgbBlue = *pdata++; > > bfo.bmColor[count].rgbGreen = *pdata++; > > bfo.bmColor[count].rgbReserved = PC_NOCOLLAPSE;; > > count++; > > } > > > (I create a palette very similar to this in DX. But I can't figure > > out how to add the palette to the bitmap.) > > > BITMAP bitmap = {0,16,16,2,1,1}; > > This means a bmp width of 16, so you must write (see above): > BITMAP bitmap = {0,16,16,8,1,4}; > > > bitmap.bmBits = data; //Pixel data > > > hbitmap = CreateBitmapIndirect(&bitmap); > > Here you are creating a HBITMAP object (not a DIB!) > > > hdc = GetDC(hwnd); > > HDC hdcmem = CreateCompatibleDC(hdc); > > > SelectObject(hdcmem, hbitmap); > > Here you select a 4bits/px hbmp into a hdcmem compatible to your window, > which could have different bits/px. I am not sure that this works, and > prefer to create the bitmap object with CreateCompatibleBitmap. But then > you cannot choose the bits/px, it is set automatically to the correct > value. > > > BitBlt(hdc, 100, 150, 16, 16 , hdcmem, 0, 0, > > SRCCOPY); > > > DeleteDC(hdcmem); > > ReleaseDC(hwnd, hdc); > > Note: Your HBITMAP object is not yet deleted. > > Have a look at CreateDIBSection, perhaps this fits better for your needs. > > hth, > Friedel Thanks for the help and pointing me in the right direction. I will do some more work and see how close I can get. I think I did try that header from an example program I have in Petzold's book. I ran into some trouble when I was trying to attach a palette but the header allowed only one element in the array. I will continue to work on the project.
From: JoeC on 7 Dec 2009 23:59 On Dec 7, 2:19 am, Friedel Jantzen <nospam_...(a)freenet.de> wrote: > Hi! > > > What commands can I look up to add a palette to a bitmap. I created a > > 16 color palette because I didn't want to add in 256 colors. What I > > want to do is create a bitmap that is not just monochrome. > > > I am looking for how to create the bitmap then attach the pixel data > > and the palette. > > The bmp palette is an array of RGBQUAD, following the BITMAPINFOHEADER. > With biBitCount = 4 you provide an array > RGBQUAD palette[16]; > ZeroMemory(palette, sizeof(palette)); > BYTE blue = 0, green = 0, red = 0; > for(int i = 0; i < 16; i++) { > palette[i].rgbBlue = blue; > palette[i].rgbGreen = green; > palette[i].rgbRed = red; > //palette[i].rgbReserved = 0; > blue += 16; // what you want > red += 4; // " > // green ... > > } > > Of course you can write this array into an alloced memory block after the > header. > For the 4bit format image data 1 byte includes 2 pixel indices into the > palette. E.g. a width of 16px results in an 8 byte scanline, no padding > required in this case. The data for a height of 16 is sized 8*16 bytes > then. > > > > > This what I have for my current bitmap. > > > BYTE cdata[] = {0xff, 0xff, 0xff, > > 0,0,0, > > 0xff,0,0, ... > > //RGB Color data > > > int num = 16; > > BYTE * pdata = &cdata[0]; > > > int datasz = 3*num; > > int count = 0; > > > while(count < datasz/num ){ > > > bfo.bmColor[count].rgbRed = *pdata++; > > bfo.bmColor[count].rgbBlue = *pdata++; > > bfo.bmColor[count].rgbGreen = *pdata++; > > bfo.bmColor[count].rgbReserved = PC_NOCOLLAPSE;; > > count++; > > } > > > (I create a palette very similar to this in DX. But I can't figure > > out how to add the palette to the bitmap.) > > > BITMAP bitmap = {0,16,16,2,1,1}; > > This means a bmp width of 16, so you must write (see above): > BITMAP bitmap = {0,16,16,8,1,4}; > > > bitmap.bmBits = data; //Pixel data > > > hbitmap = CreateBitmapIndirect(&bitmap); > > Here you are creating a HBITMAP object (not a DIB!) > > > hdc = GetDC(hwnd); > > HDC hdcmem = CreateCompatibleDC(hdc); > > > SelectObject(hdcmem, hbitmap); > > Here you select a 4bits/px hbmp into a hdcmem compatible to your window, > which could have different bits/px. I am not sure that this works, and > prefer to create the bitmap object with CreateCompatibleBitmap. But then > you cannot choose the bits/px, it is set automatically to the correct > value. > > > BitBlt(hdc, 100, 150, 16, 16 , hdcmem, 0, 0, > > SRCCOPY); > > > DeleteDC(hdcmem); > > ReleaseDC(hwnd, hdc); > > Note: Your HBITMAP object is not yet deleted. > > Have a look at CreateDIBSection, perhaps this fits better for your needs. > > hth, > Friedel Thanks again. I got the program to run but I don't get any output yet. I did this: struct BITMAP_INFO{ BITMAPFILEHEADER bmHead; RGBQUAD bmColor[16]; }; BYTE data[] = {0xff,0xff,0x80,0x01,... BITMAPINFO* BitmapInfo = (BITMAPINFO*)(new BITMAP_INFO); PBYTE BitmapBits = data; //reads bitmap data from an array. hbitmap = CreateDIBSection(hdc, BitmapInfo, DIB_RGB_COLORS, (PVOID*)&BitmapBits, NULL, 0); HDC hMem = CreateCompatibleDC(hdc); HDC hdcmem = CreateCompatibleDC(hdc); HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMem, hbitmap); BitBlt(hdc,10, 10, 16, 16, hMem, 0, 0, SRCCOPY); StretchBlt(hdc, 250,250,16*5,16*5,hdcmem,0,0,16,16,MERGECOPY); SelectObject(hMem, hOldBitmap); DeleteDC(hMem); Now I am trying to get some output some dots on the screen. Later I will see how to edit this data with an editor. I already have a monochrome bitmap object and editor.
From: Friedel Jantzen on 8 Dec 2009 01:47
Hi! > I did this: > > struct BITMAP_INFO{ > BITMAPFILEHEADER bmHead; > RGBQUAD bmColor[16]; > }; You picked the wrong struct (see my first reply). Try this: struct BITMAP_INFO{ BITMAPINFOHEADER bmiHead; // ! required RGBQUAD bmColor[16]; }; Then initialize this struct, see the link I posted for BITMAPINFOHEADER. > BYTE data[] = {0xff,0xff,0x80,0x01,... > > BITMAPINFO* BitmapInfo = (BITMAPINFO*)(new BITMAP_INFO); > > PBYTE BitmapBits = data; //reads bitmap data from an array. This parameter of CreateDIBSection is an _out_ parameter and points to the pixel data in the new DIB, not to your data. PBYTE BitmapBits = NULL; > > hbitmap = CreateDIBSection(hdc, BitmapInfo, DIB_RGB_COLORS, > (PVOID*)&BitmapBits, NULL, 0); Now you can copy your data to BitmapBits: GdiFlush(); CopyMemory(BitmapBits, data, dataSize); > HDC hMem = CreateCompatibleDC(hdc); > HDC hdcmem = CreateCompatibleDC(hdc); > > HBITMAP hOldBitmap = (HBITMAP)SelectObject(hMem, hbitmap); > > BitBlt(hdc,10, 10, 16, 16, hMem, 0, 0, SRCCOPY); > StretchBlt(hdc, 250,250,16*5,16*5,hdcmem,0,0,16,16,MERGECOPY); > > SelectObject(hMem, hOldBitmap); > DeleteDC(hMem); There is an easy way to display DIBs: SetDIBitsToDevice http://msdn.microsoft.com/en-us/library/dd162974(VS.85).aspx You can find an interesting sample for manipulating the color table here: http://blogs.msdn.com/oldnewthing/archive/2006/11/15/1081320.aspx To get the complete thing working, download the "scratch" program from the link on this page; if you are a newbie with Win32, this is a good starting point. hth, Friedel |