Save an image (of 24 bits depth or less)
-
Dear All; I am trying to save an image to my harddrive, the image should be of depth 24 or less ie.16, 8, 4. regardless of of the monitor's resolution I have the tried the following code and its works fine but the saved images are of 32 bit depth. I have tried to fiddle with the code but i cant get an image of 24 bit depth or less :((, can anyone please advise and i will be grateful.
void Example:: SaveBitmap(char *name,HBITMAP hBitMap) { CBitmap bmp; bmp.Attach(hBitMap); BITMAP bitmap; bmp.GetBitmap(&bitmap); int size = bitmap.bmWidth*bitmap.bmHeight*bitmap.bmBitsPixel/8; BYTE *lpBits = new BYTE[size]; ::GetBitmapBits(hBitMap,size,lpBits); WriteBmp(name,&bitmap,(int*)lpBits); delete []lpBits; } // this method write a bitmap to the hard disk void Example::WriteBmp(char* name,BITMAP *bmp,int* data) { BITMAPINFO Bmi; memset(&Bmi,0,sizeof(BITMAPINFO)); Bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); Bmi.bmiHeader.biWidth = bmp->bmWidth; Bmi.bmiHeader.biHeight = bmp->bmHeight; Bmi.bmiHeader.biPlanes = 1; Bmi.bmiHeader.biBitCount = bmp->bmBitsPixel; Bmi.bmiHeader.biCompression = BI_RGB; Bmi.bmiHeader.biSizeImage = bmp->bmHeight*bmp->bmWidth*bmp->bmBitsPixel/8; FILE* image = fopen (name,"wb"); if(image==0) return; int h = abs(Bmi.bmiHeader.biHeight); int w = abs(Bmi.bmiHeader.biWidth); Bmi.bmiHeader.biHeight=-h; Bmi.bmiHeader.biWidth=w; int sz = Bmi.bmiHeader.biSizeImage; BITMAPFILEHEADER bfh; bfh.bfType=('M'<<8)+'B'; bfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); bfh.bfSize=sz+bfh.bfOffBits; bfh.bfReserved1=0; bfh.bfReserved2=0; fwrite(&bfh,sizeof(bfh),1,image); fwrite(&Bmi.bmiHeader,sizeof(BITMAPINFOHEADER),1,image); fwrite(data,sz,1,image); fclose(image); } <\code> Thank you llp00na
-
Dear All; I am trying to save an image to my harddrive, the image should be of depth 24 or less ie.16, 8, 4. regardless of of the monitor's resolution I have the tried the following code and its works fine but the saved images are of 32 bit depth. I have tried to fiddle with the code but i cant get an image of 24 bit depth or less :((, can anyone please advise and i will be grateful.
void Example:: SaveBitmap(char *name,HBITMAP hBitMap) { CBitmap bmp; bmp.Attach(hBitMap); BITMAP bitmap; bmp.GetBitmap(&bitmap); int size = bitmap.bmWidth*bitmap.bmHeight*bitmap.bmBitsPixel/8; BYTE *lpBits = new BYTE[size]; ::GetBitmapBits(hBitMap,size,lpBits); WriteBmp(name,&bitmap,(int*)lpBits); delete []lpBits; } // this method write a bitmap to the hard disk void Example::WriteBmp(char* name,BITMAP *bmp,int* data) { BITMAPINFO Bmi; memset(&Bmi,0,sizeof(BITMAPINFO)); Bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); Bmi.bmiHeader.biWidth = bmp->bmWidth; Bmi.bmiHeader.biHeight = bmp->bmHeight; Bmi.bmiHeader.biPlanes = 1; Bmi.bmiHeader.biBitCount = bmp->bmBitsPixel; Bmi.bmiHeader.biCompression = BI_RGB; Bmi.bmiHeader.biSizeImage = bmp->bmHeight*bmp->bmWidth*bmp->bmBitsPixel/8; FILE* image = fopen (name,"wb"); if(image==0) return; int h = abs(Bmi.bmiHeader.biHeight); int w = abs(Bmi.bmiHeader.biWidth); Bmi.bmiHeader.biHeight=-h; Bmi.bmiHeader.biWidth=w; int sz = Bmi.bmiHeader.biSizeImage; BITMAPFILEHEADER bfh; bfh.bfType=('M'<<8)+'B'; bfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER); bfh.bfSize=sz+bfh.bfOffBits; bfh.bfReserved1=0; bfh.bfReserved2=0; fwrite(&bfh,sizeof(bfh),1,image); fwrite(&Bmi.bmiHeader,sizeof(BITMAPINFOHEADER),1,image); fwrite(data,sz,1,image); fclose(image); } <\code> Thank you llp00na
You are converting a device-dependent bitmap (DDB) to a device independent bitmap (DIB) to save. Since you don't do any conversion of the bitmap format, if the source DDB is 32-bit, then the saved DIB is 32-bit. If you want to convert the format, you can use GetDIBits() to get the DIB bits in the format you want. See How To Convert Between Device-Dependent Bitmaps and DIBs[^] Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
-
You are converting a device-dependent bitmap (DDB) to a device independent bitmap (DIB) to save. Since you don't do any conversion of the bitmap format, if the source DDB is 32-bit, then the saved DIB is 32-bit. If you want to convert the format, you can use GetDIBits() to get the DIB bits in the format you want. See How To Convert Between Device-Dependent Bitmaps and DIBs[^] Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
Mark Salsbery wrote:
Since you don't do any conversion of the bitmap format, if the source DDB is 32-bit, then the saved DIB is 32-bit.
Its because i don't know how to convert from a 32 bit bitmap to a less depth bitmap.
Mark Salsbery wrote:
See How To Convert Between Device-Dependent Bitmaps and DIBs[^]
Thank you for the article, i will go through it and give it a go. I am gratefull for your valuable assistance :).
llp00na
-
Mark Salsbery wrote:
Since you don't do any conversion of the bitmap format, if the source DDB is 32-bit, then the saved DIB is 32-bit.
Its because i don't know how to convert from a 32 bit bitmap to a less depth bitmap.
Mark Salsbery wrote:
See How To Convert Between Device-Dependent Bitmaps and DIBs[^]
Thank you for the article, i will go through it and give it a go. I am gratefull for your valuable assistance :).
llp00na
Here's another link: Converting DDB to DIB[^] In that code, the BITMAPINFOHEADER biPlanes, biBitCount, and biCompression members are initialized to match the source DDB. To change the type, set those members to the actual format you want before making the first call to GetDIBits. Remember, for 1, 4, and 8 bit formats you'll need to deal with a color table in the DIB. For 24-bit, there's no color table. See the documentation for BITMAPINFOHEADER for details. Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
-
Here's another link: Converting DDB to DIB[^] In that code, the BITMAPINFOHEADER biPlanes, biBitCount, and biCompression members are initialized to match the source DDB. To change the type, set those members to the actual format you want before making the first call to GetDIBits. Remember, for 1, 4, and 8 bit formats you'll need to deal with a color table in the DIB. For 24-bit, there's no color table. See the documentation for BITMAPINFOHEADER for details. Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder
Mark Salsbery wrote:
Remember, for 1, 4, and 8 bit formats you'll need to deal with a color table in the DIB. For 24-bit, there's no color table. See the documentation for BITMAPINFOHEADER for details.
Alright then, i will convert it to a 16 or 24 bit bitmap then. I dont want to run into complications.
Mark Salsbery wrote:
Here's another link: Converting DDB to DIB[^]
Many thanx, I am once again very grateful :)
llp00na
-
Here's another link: Converting DDB to DIB[^] In that code, the BITMAPINFOHEADER biPlanes, biBitCount, and biCompression members are initialized to match the source DDB. To change the type, set those members to the actual format you want before making the first call to GetDIBits. Remember, for 1, 4, and 8 bit formats you'll need to deal with a color table in the DIB. For 24-bit, there's no color table. See the documentation for BITMAPINFOHEADER for details. Mark
"Posting a VB.NET question in the C++ forum will end in tears." Chris Maunder