谁会不通过显示图象来修改图象内容,比如加上一些汉字之类的? 谁会不通过显示图象就修改图象内容,比如加上一些汉字之类的?返回值要求存成另一个图象文件!!高分相谢! 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 可以在memory dc中进行,然后保存。 1,首先你要有一个dib类(网上多的是,我也有)2,其次在内存中新建一个dc,然后把图像显示在内存的dc上3,在内存的dc上绘图,如添加直线,文字等等。4,通过dib类把内存dc上的图像保存到文件中。 这样的东西我做过。 HDC hScrDC, hMemDC; HBITMAP hBitmap, hOldBitmap; hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL); hMemDC = CreateCompatibleDC(hScrDC); hBitmap = (HBITMAP)LoadImage(NULL, szSrcFileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); BITMAP hBMP; ::GetObject(hBitmap, sizeof(hBMP), &hBMP); int nWidth = hBMP.bmWidth; int nHeight = hBMP.bmHeight; hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); BitBlt(hMemDC, 0, 0, nWidth, nHeight, hMemDC, 0, 0, SRCCOPY); // Add Draw Text function here AddTextToImage(hMemDC); hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); DeleteDC(hScrDC); DeleteDC(hMemDC); SaveBitmapToFile(hBitmap, szDstFileName);保存文件的函数省略。 test("d:\\a.bmp","不好意思,代码长了点,并且没有通过测试。");BOOL SaveToBmp(HBITMAP hBitmap,const char *szBmpFile);void test(const char* szBitmapFile,const char* szStr){ HDC hDC = GetDC(NULL); CDC dc; dc.Attach(hDC); CDC tempDC; tempDC.CreateCompatibleDC(&dc);//创建一内存DC。 CBitmap* pOldBitmap; CBitmap bitmap; HBITMAP hBitmap=(HBITMAP)LoadImage(NULL, "c:\\7_1405_4.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION); bitmap.Attach(hBitmap); pOldBitmap = tempDC.SelectObject(bitmap);// tempDC.TextOut(0,0,szStr); tempDC.TextOut(0,0,"这只是一个例子。"); tempDC.SelectObject(pOldBitmap); dc.Detach(); ReleaseDC(NULL,hDC); SaveToBmp(bitmap,szBitmapFile); bitmap.Detach(); DeleteObject(hBitmap);}#include "math.h"BOOL SaveToBmp(HBITMAP hBitmap,const char *szBmpFile){ BITMAP bm; PBITMAPINFO bmpInf; BOOL bRet=FALSE; int nPaletteSize=0; if(GetObject(hBitmap,sizeof(bm),&bm)==0) return FALSE; if(bm.bmBitsPixel<16) nPaletteSize=pow(2,bm.bmBitsPixel); bmpInf=(PBITMAPINFO)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+ sizeof(RGBQUAD)*nPaletteSize); if(bmpInf==NULL) { return FALSE; } //----------------------------------------------- bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); bmpInf->bmiHeader.biWidth = bm.bmWidth; bmpInf->bmiHeader.biHeight = bm.bmHeight; bmpInf->bmiHeader.biPlanes = bm.bmPlanes; bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel; bmpInf->bmiHeader.biCompression = BI_RGB; bmpInf->bmiHeader.biSizeImage = (bm.bmWidth+7)/8*bm.bmHeight*bm.bmBitsPixel; bmpInf->bmiHeader.biXPelsPerMeter = 0; bmpInf->bmiHeader.biYPelsPerMeter = 0; bmpInf->bmiHeader.biClrUsed = 0; bmpInf->bmiHeader.biClrImportant = 0; //----------------------------------------------- void* buf=(void*) new char[bmpInf->bmiHeader.biSizeImage]; if(buf==NULL) { LocalFree(bmpInf); return FALSE; } if(!::GetDIBits(GetWindowDC(NULL),hBitmap,0,(WORD)bm.bmHeight,buf,bmpInf,DIB_RGB_COLORS)) { delete []buf; LocalFree(bmpInf); return FALSE; } BITMAPFILEHEADER bmFHeader; bmFHeader.bfType=0x4d42;//"BM" bmFHeader.bfReserved1=0; bmFHeader.bfReserved2=0; bmFHeader.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+bmpInf->bmiHeader.biSize+ nPaletteSize*sizeof(RGBQUAD)); bmFHeader.bfSize=(DWORD)(bmFHeader.bfOffBits+bmpInf->bmiHeader.biSizeImage); DWORD dwTemp; HANDLE hFile; hFile=CreateFile(szBmpFile,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); while(hFile!=INVALID_HANDLE_VALUE) { //写BITMAPFILEHEADER if(WriteFile(hFile,&bmFHeader,sizeof(BITMAPFILEHEADER),&dwTemp,NULL)==0) break; //写BITMAPINFOHEADER if(WriteFile(hFile,&bmpInf->bmiHeader,bmpInf->bmiHeader.biSize,&dwTemp,NULL)==0) break; //写调色板数据(可能有) if(nPaletteSize != 0) { if(WriteFile(hFile,&bmpInf->bmiColors,nPaletteSize*sizeof(RGBQUAD),&dwTemp,NULL)==0) break; } //写图像数据 DWORD dwLen=bmpInf->bmiHeader.biSizeImage; BYTE *pTemp=(BYTE*)buf; while(dwLen>=65535) { if(WriteFile(hFile,pTemp,65535,&dwTemp,NULL)==0) { dwLen=0xffffffff; break; } dwLen-=65535; pTemp+=65535; } if(dwLen==0xffffffff) break; if((dwLen>0)&&(WriteFile(hFile,pTemp,dwLen,&dwTemp,NULL)==0)) break; bRet=TRUE; break;//必须的 } if(hFile!=INVALID_HANDLE_VALUE) { CloseHandle(hFile); } delete []buf; LocalFree(bmpInf); return bRet;} 这太简单了。获得显示Bitmap的dc,在dc上画,再存为Bitmap.HBITMAP save( HBITMAP hBitmap){ CDC sourceDC, destDC; sourceDC.CreateCompatibleDC( NULL ); destDC.CreateCompatibleDC( NULL ); BITMAP bm; ::GetObject( hBitmap, sizeof( bm ), &bm ); HBITMAP hbmResult = ::CreateCompatibleBitmap(CClientDC(NULL), w, h); HBITMAP hbmOldSource = (HBITMAP)::SelectObject( sourceDC.m_hDC, hBitmap ); HBITMAP hbmOldDest = (HBITMAP)::SelectObject( destDC.m_hDC, hbmResult ); destDC.TextOut(10,10,"加一行文字!"); destDC.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &sourceDC, 0, 0, SRCCOPY ); // Restore DCs ::SelectObject( sourceDC.m_hDC, hbmOldSource ); ::SelectObject( destDC.m_hDC, hbmOldDest ); return hbmResult;} 临时现编的函数,未经测试,可能有错误,但大意如此。 假设:lpszBmpFile和lpszNewBmpFile,代码如下: HDC hDC = GetDC(NULL); HDC hMemDC = CreateCompatibleDC(hDC); HBITMAP hBitmap = NULL; hBmp = (HBITMAP)LoadImage(NULL, lpszBmpFile, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hBmp); // then you can draw something here, for example: TextOut(hMemDC, ......); ...... // Create logical palette if device support a palette CPalette pal; if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE ) { UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256); LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize]; pLP->palVersion = 0x300; pLP->palNumEntries = GetSystemPaletteEntries( hDC, 0, 255, pLP->palPalEntry ); // Create the palette pal.CreatePalette( pLP ); delete[] pLP; } CBitmap bitmap; bitmap.Attach(hBmp); HANDLE hDIB = DDBToDIB(bitmap, BI_RGB, &pal ); WriteDIB(lpszNewBmpFile, hDIB); SelectObject(hMemDC, hOldBmp); DeleteObject(hBmp); ReleaseDC(NULL, hDC);上面代码用到的两个函数:HANDLE DDBToDIB(CBitmap& bitmap, DWORD dwCompression, CPalette* pPal );BOOL WriteDIB( LPTSTR szFile, HANDLE hDIB);HANDLE DDBToDIB(CBitmap& bitmap, DWORD dwCompression, CPalette *pPal){ BITMAP bm; BITMAPINFOHEADER bi; LPBITMAPINFOHEADER lpbi; DWORD dwLen; HANDLE hDIB; HANDLE handle; HDC hDC; HPALETTE hPal; ASSERT( bitmap.GetSafeHandle() ); // The function has no arg for bitfields if( dwCompression == BI_BITFIELDS ) return NULL; // If a palette has not been supplied use defaul palette hPal = (HPALETTE) pPal->GetSafeHandle(); if (hPal==NULL) hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); // Get bitmap information bitmap.GetObject(sizeof(bm),(LPSTR)&bm); // Initialize the bitmapinfoheader bi.biSize = sizeof(BITMAPINFOHEADER); bi.biWidth = bm.bmWidth; bi.biHeight = bm.bmHeight; bi.biPlanes = 1; bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel; bi.biCompression = dwCompression; bi.biSizeImage = 0; bi.biXPelsPerMeter = 0; bi.biYPelsPerMeter = 0; bi.biClrUsed = 0; bi.biClrImportant = 0; // Compute the size of the infoheader and the color table int nColors = (1 << bi.biBitCount); if( nColors > 256 ) nColors = 0; dwLen = bi.biSize + nColors * sizeof(RGBQUAD); // We need a device context to get the DIB from hDC = ::GetDC(NULL); hPal = SelectPalette(hDC,hPal,FALSE); RealizePalette(hDC); // Allocate enough memory to hold bitmapinfoheader and color table hDIB = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDIB){ SelectPalette(hDC,hPal,FALSE); ::ReleaseDC(NULL,hDC); return NULL; } lpbi = (LPBITMAPINFOHEADER)hDIB; *lpbi = bi; // Call GetDIBits with a NULL lpBits param, so the device driver // will calculate the biSizeImage field GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight, (LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS); bi = *lpbi; // If the driver did not fill in the biSizeImage field, then compute it // Each scan line of the image is aligned on a DWORD (32bit) boundary if (bi.biSizeImage == 0){ bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8) * bi.biHeight; // If a compression scheme is used the result may infact be larger // Increase the size to account for this. if (dwCompression != BI_RGB) bi.biSizeImage = (bi.biSizeImage * 3) / 2; } // Realloc the buffer so that it can hold all the bits dwLen += bi.biSizeImage; if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE)) hDIB = handle; else{ GlobalFree(hDIB); // Reselect the original palette SelectPalette(hDC,hPal,FALSE); ::ReleaseDC(NULL,hDC); return NULL; } // Get the bitmap bits lpbi = (LPBITMAPINFOHEADER)hDIB; // FINALLY get the DIB BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, // Start scan line (DWORD)bi.biHeight, // # of scan lines (LPBYTE)lpbi // address for bitmap bits + (bi.biSize + nColors * sizeof(RGBQUAD)), (LPBITMAPINFO)lpbi, // address of bitmapinfo (DWORD)DIB_RGB_COLORS); // Use RGB for color table if( !bGotBits ) { GlobalFree(hDIB); SelectPalette(hDC,hPal,FALSE); ::ReleaseDC(NULL,hDC); return NULL; } SelectPalette(hDC,hPal,FALSE); ::ReleaseDC(NULL,hDC); return hDIB;}BOOL WriteDIB(LPTSTR szFile, HANDLE hDIB){ BITMAPFILEHEADER hdr; LPBITMAPINFOHEADER lpbi; if (!hDIB) return FALSE; CFile file; if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) ) return FALSE; lpbi = (LPBITMAPINFOHEADER)hDIB; int nColors = 1 << lpbi->biBitCount; // Fill in the fields of the file header hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM" hdr.bfSize = GlobalSize (hDIB) + sizeof( hdr ); hdr.bfReserved1 = 0; hdr.bfReserved2 = 0; hdr.bfOffBits = (DWORD) (sizeof( hdr ) + lpbi->biSize + nColors * sizeof(RGBQUAD)); // Write the file header file.Write( &hdr, sizeof(hdr) ); // Write the DIB header and the bits file.Write( lpbi, GlobalSize(hDIB) ); return TRUE;} 如何采用多线程实现图片的预加载?? 串口调试读数很慢?怎么解决? atol怎么将12位及其以上的字符串转换成long型 双鼠标问题 谁能给个在RichEdit里面插入Ole的例子? 如何实现两个连接公用一个端口进行通讯? combobox如何设定默认值? MFC关于对话框的按钮调用CXXview中的函数的问题,头文件相互包含问题 怎么在VC的CHtmlView类的子类里面去掉右键菜单,或者替换掉 在wince 下怎样用opengl es 做出电子书动态翻页效果? 继承类时,如何作构造函数? 请问关于调制解调器(TAPI)编程的经典书籍有那些?
2,其次在内存中新建一个dc,然后把图像显示在内存的dc上
3,在内存的dc上绘图,如添加直线,文字等等。
4,通过dib类把内存dc上的图像保存到文件中。
HBITMAP hBitmap, hOldBitmap; hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
hMemDC = CreateCompatibleDC(hScrDC); hBitmap = (HBITMAP)LoadImage(NULL, szSrcFileName, IMAGE_BITMAP,
0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); BITMAP hBMP;
::GetObject(hBitmap, sizeof(hBMP), &hBMP);
int nWidth = hBMP.bmWidth;
int nHeight = hBMP.bmHeight; hOldBitmap = (HBITMAP)SelectObject(hMemDC, hBitmap); BitBlt(hMemDC, 0, 0, nWidth, nHeight, hMemDC, 0, 0, SRCCOPY); // Add Draw Text function here
AddTextToImage(hMemDC); hBitmap = (HBITMAP)SelectObject(hMemDC, hOldBitmap); DeleteDC(hScrDC);
DeleteDC(hMemDC); SaveBitmapToFile(hBitmap, szDstFileName);
保存文件的函数省略。
void test(const char* szBitmapFile,const char* szStr)
{
HDC hDC = GetDC(NULL);
CDC dc;
dc.Attach(hDC);
CDC tempDC;
tempDC.CreateCompatibleDC(&dc);//创建一内存DC。
CBitmap* pOldBitmap;
CBitmap bitmap; HBITMAP hBitmap=(HBITMAP)LoadImage(NULL, "c:\\7_1405_4.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE|LR_CREATEDIBSECTION);
bitmap.Attach(hBitmap);
pOldBitmap = tempDC.SelectObject(bitmap);// tempDC.TextOut(0,0,szStr);
tempDC.TextOut(0,0,"这只是一个例子。");
tempDC.SelectObject(pOldBitmap);
dc.Detach();
ReleaseDC(NULL,hDC);
SaveToBmp(bitmap,szBitmapFile); bitmap.Detach();
DeleteObject(hBitmap);
}#include "math.h"
BOOL SaveToBmp(HBITMAP hBitmap,const char *szBmpFile)
{
BITMAP bm;
PBITMAPINFO bmpInf;
BOOL bRet=FALSE;
int nPaletteSize=0; if(GetObject(hBitmap,sizeof(bm),&bm)==0)
return FALSE; if(bm.bmBitsPixel<16)
nPaletteSize=pow(2,bm.bmBitsPixel); bmpInf=(PBITMAPINFO)LocalAlloc(LPTR,sizeof(BITMAPINFOHEADER)+
sizeof(RGBQUAD)*nPaletteSize);
if(bmpInf==NULL)
{
return FALSE;
}
//-----------------------------------------------
bmpInf->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmpInf->bmiHeader.biWidth = bm.bmWidth;
bmpInf->bmiHeader.biHeight = bm.bmHeight;
bmpInf->bmiHeader.biPlanes = bm.bmPlanes;
bmpInf->bmiHeader.biBitCount = bm.bmBitsPixel;
bmpInf->bmiHeader.biCompression = BI_RGB;
bmpInf->bmiHeader.biSizeImage = (bm.bmWidth+7)/8*bm.bmHeight*bm.bmBitsPixel;
bmpInf->bmiHeader.biXPelsPerMeter = 0;
bmpInf->bmiHeader.biYPelsPerMeter = 0;
bmpInf->bmiHeader.biClrUsed = 0;
bmpInf->bmiHeader.biClrImportant = 0;
//-----------------------------------------------
void* buf=(void*) new char[bmpInf->bmiHeader.biSizeImage];
if(buf==NULL)
{
LocalFree(bmpInf);
return FALSE;
}
if(!::GetDIBits(GetWindowDC(NULL),hBitmap,0,(WORD)bm.bmHeight,buf,bmpInf,DIB_RGB_COLORS))
{
delete []buf;
LocalFree(bmpInf);
return FALSE;
}
BITMAPFILEHEADER bmFHeader;
bmFHeader.bfType=0x4d42;//"BM"
bmFHeader.bfReserved1=0;
bmFHeader.bfReserved2=0;
bmFHeader.bfOffBits=(DWORD)(sizeof(BITMAPFILEHEADER)+bmpInf->bmiHeader.biSize+
nPaletteSize*sizeof(RGBQUAD));
bmFHeader.bfSize=(DWORD)(bmFHeader.bfOffBits+bmpInf->bmiHeader.biSizeImage); DWORD dwTemp;
HANDLE hFile;
hFile=CreateFile(szBmpFile,GENERIC_READ|GENERIC_WRITE,0,NULL,CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,NULL);
while(hFile!=INVALID_HANDLE_VALUE)
{
//写BITMAPFILEHEADER
if(WriteFile(hFile,&bmFHeader,sizeof(BITMAPFILEHEADER),&dwTemp,NULL)==0)
break;
//写BITMAPINFOHEADER
if(WriteFile(hFile,&bmpInf->bmiHeader,bmpInf->bmiHeader.biSize,&dwTemp,NULL)==0)
break;
//写调色板数据(可能有)
if(nPaletteSize != 0)
{
if(WriteFile(hFile,&bmpInf->bmiColors,nPaletteSize*sizeof(RGBQUAD),&dwTemp,NULL)==0)
break;
} //写图像数据
DWORD dwLen=bmpInf->bmiHeader.biSizeImage;
BYTE *pTemp=(BYTE*)buf;
while(dwLen>=65535)
{
if(WriteFile(hFile,pTemp,65535,&dwTemp,NULL)==0)
{
dwLen=0xffffffff;
break;
}
dwLen-=65535;
pTemp+=65535;
}
if(dwLen==0xffffffff)
break;
if((dwLen>0)&&(WriteFile(hFile,pTemp,dwLen,&dwTemp,NULL)==0))
break;
bRet=TRUE;
break;//必须的
}
if(hFile!=INVALID_HANDLE_VALUE)
{
CloseHandle(hFile);
}
delete []buf;
LocalFree(bmpInf);
return bRet;
}
{
CDC sourceDC, destDC;
sourceDC.CreateCompatibleDC( NULL );
destDC.CreateCompatibleDC( NULL ); BITMAP bm;
::GetObject( hBitmap, sizeof( bm ), &bm ); HBITMAP hbmResult = ::CreateCompatibleBitmap(CClientDC(NULL), w, h); HBITMAP hbmOldSource = (HBITMAP)::SelectObject( sourceDC.m_hDC, hBitmap );
HBITMAP hbmOldDest = (HBITMAP)::SelectObject( destDC.m_hDC, hbmResult ); destDC.TextOut(10,10,"加一行文字!");
destDC.BitBlt(0,0,bm.bmWidth, bm.bmHeight, &sourceDC, 0, 0, SRCCOPY ); // Restore DCs
::SelectObject( sourceDC.m_hDC, hbmOldSource );
::SelectObject( destDC.m_hDC, hbmOldDest ); return hbmResult;
}
临时现编的函数,未经测试,可能有错误,但大意如此。
假设:lpszBmpFile和lpszNewBmpFile,代码如下: HDC hDC = GetDC(NULL);
HDC hMemDC = CreateCompatibleDC(hDC); HBITMAP hBitmap = NULL;
hBmp = (HBITMAP)LoadImage(NULL, lpszBmpFile, IMAGE_BITMAP, 0, 0,
LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE); HBITMAP hOldBmp = (HBITMAP)SelectObject(hMemDC, hBmp);
// then you can draw something here, for example:
TextOut(hMemDC, ......);
...... // Create logical palette if device support a palette
CPalette pal;
if( dc.GetDeviceCaps(RASTERCAPS) & RC_PALETTE )
{
UINT nSize = sizeof(LOGPALETTE) + (sizeof(PALETTEENTRY) * 256);
LOGPALETTE *pLP = (LOGPALETTE *) new BYTE[nSize];
pLP->palVersion = 0x300; pLP->palNumEntries =
GetSystemPaletteEntries( hDC, 0, 255, pLP->palPalEntry ); // Create the palette
pal.CreatePalette( pLP ); delete[] pLP;
} CBitmap bitmap;
bitmap.Attach(hBmp); HANDLE hDIB = DDBToDIB(bitmap, BI_RGB, &pal );
WriteDIB(lpszNewBmpFile, hDIB); SelectObject(hMemDC, hOldBmp);
DeleteObject(hBmp);
ReleaseDC(NULL, hDC);
上面代码用到的两个函数:
HANDLE DDBToDIB(CBitmap& bitmap, DWORD dwCompression, CPalette* pPal );
BOOL WriteDIB( LPTSTR szFile, HANDLE hDIB);
HANDLE DDBToDIB(CBitmap& bitmap, DWORD dwCompression, CPalette *pPal)
{
BITMAP bm;
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HANDLE hDIB;
HANDLE handle;
HDC hDC;
HPALETTE hPal;
ASSERT( bitmap.GetSafeHandle() ); // The function has no arg for bitfields
if( dwCompression == BI_BITFIELDS )
return NULL; // If a palette has not been supplied use defaul palette
hPal = (HPALETTE) pPal->GetSafeHandle();
if (hPal==NULL)
hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE); // Get bitmap information
bitmap.GetObject(sizeof(bm),(LPSTR)&bm); // Initialize the bitmapinfoheader
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = bm.bmPlanes * bm.bmBitsPixel;
bi.biCompression = dwCompression;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0; // Compute the size of the infoheader and the color table
int nColors = (1 << bi.biBitCount);
if( nColors > 256 )
nColors = 0;
dwLen = bi.biSize + nColors * sizeof(RGBQUAD); // We need a device context to get the DIB from
hDC = ::GetDC(NULL);
hPal = SelectPalette(hDC,hPal,FALSE);
RealizePalette(hDC); // Allocate enough memory to hold bitmapinfoheader and color table
hDIB = GlobalAlloc(GMEM_FIXED,dwLen); if (!hDIB){
SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return NULL;
} lpbi = (LPBITMAPINFOHEADER)hDIB; *lpbi = bi; // Call GetDIBits with a NULL lpBits param, so the device driver
// will calculate the biSizeImage field
GetDIBits(hDC, (HBITMAP)bitmap.GetSafeHandle(), 0L, (DWORD)bi.biHeight,
(LPBYTE)NULL, (LPBITMAPINFO)lpbi, (DWORD)DIB_RGB_COLORS); bi = *lpbi; // If the driver did not fill in the biSizeImage field, then compute it
// Each scan line of the image is aligned on a DWORD (32bit) boundary
if (bi.biSizeImage == 0){
bi.biSizeImage = ((((bi.biWidth * bi.biBitCount) + 31) & ~31) / 8)
* bi.biHeight; // If a compression scheme is used the result may infact be larger
// Increase the size to account for this.
if (dwCompression != BI_RGB)
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
} // Realloc the buffer so that it can hold all the bits
dwLen += bi.biSizeImage;
if (handle = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
hDIB = handle;
else{
GlobalFree(hDIB); // Reselect the original palette
SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return NULL;
} // Get the bitmap bits
lpbi = (LPBITMAPINFOHEADER)hDIB; // FINALLY get the DIB
BOOL bGotBits = GetDIBits( hDC, (HBITMAP)bitmap.GetSafeHandle(),
0L, // Start scan line
(DWORD)bi.biHeight, // # of scan lines
(LPBYTE)lpbi // address for bitmap bits
+ (bi.biSize + nColors * sizeof(RGBQUAD)),
(LPBITMAPINFO)lpbi, // address of bitmapinfo
(DWORD)DIB_RGB_COLORS); // Use RGB for color table if( !bGotBits )
{
GlobalFree(hDIB);
SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return NULL;
} SelectPalette(hDC,hPal,FALSE);
::ReleaseDC(NULL,hDC);
return hDIB;}BOOL WriteDIB(LPTSTR szFile, HANDLE hDIB)
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER lpbi; if (!hDIB)
return FALSE; CFile file;
if( !file.Open( szFile, CFile::modeWrite|CFile::modeCreate) )
return FALSE; lpbi = (LPBITMAPINFOHEADER)hDIB; int nColors = 1 << lpbi->biBitCount; // Fill in the fields of the file header
hdr.bfType = ((WORD) ('M' << 8) | 'B'); // is always "BM"
hdr.bfSize = GlobalSize (hDIB) + sizeof( hdr );
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD) (sizeof( hdr ) + lpbi->biSize +
nColors * sizeof(RGBQUAD)); // Write the file header
file.Write( &hdr, sizeof(hdr) ); // Write the DIB header and the bits
file.Write( lpbi, GlobalSize(hDIB) ); return TRUE;
}