本人现在在做位图保存,矢量图形保存成bmp!以前大虾们给我提供了一些代码,我回去运行后发现了很多错误,望各位大虾指点!错误在下一篇! HBITMAP CopyScreenToBitmap(LPRECT lpRect)
//lpRect 代表选定区域
{
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap;
// 位图句柄
int nX, nY, nX2, nY2;
// 选定区域坐标
int nWidth, nHeight;
// 位图宽度和高度
int xScrn, yScrn;
// 屏幕分辨率 // 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect- >left;
nY = lpRect- >top;
nX2 = lpRect- >right;
nY2 = lpRect- >bottom;
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//确保选定区域是可见的
if (nX 〈0)
nX = 0;
if (nY 〈 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap
(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
hBitmap = SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 返回位图句柄
return hBitmap;
}
得到屏幕位图句柄以后,我们
可以把屏幕内容粘贴到剪贴板上.
if (OpenClipboard(hWnd))
//hWnd为程序窗口句柄
{
//清空剪贴板
EmptyClipboard();
//把屏幕内容粘贴到剪贴板上,
hBitmap 为刚才的屏幕位图句柄
SetClipboardData(CF_BITMAP, hBitmap);
//关闭剪贴板
CloseClipboard();
}
我们也可以把屏幕内容以位图格式存到磁盘文件上.
int SaveBitmapToFile(HBITMAP hBitmap ,
LPSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄
{ //lpFileName 为位图文件名
HDC hDC;
//设备描述表
int iBits;
//当前显示分辨率下每个像素所占字节数
WORD wBitCount;
//位图中每个像素所占字节数
//定义调色板大小, 位图中像素字节大小 ,
位图文件大小 , 写入文件字节数
DWORD dwPaletteSize=0,
dwBmBitsSize,
dwDIBSize, dwWritten;
BITMAP Bitmap;
//位图属性结构
BITMAPFILEHEADER bmfHdr;
//位图文件头结构
BITMAPINFOHEADER bi;
//位图信息头结构
LPBITMAPINFOHEADER lpbi;
//指向位图信息头结构
HANDLE fh, hDib, hPal,hOldPal=NULL;
//定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) *
GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits 〈 = 1)
wBitCount = 1;
else if (iBits 〈 = 4)
wBitCount = 4;
else if (iBits 〈 = 8)
wBitCount = 8;
else if (iBits 〈 = 24)
wBitCount = 24;
//计算调色板大小
if (wBitCount 〈 = 8)
dwPaletteSize = (1 〈 〈 wBitCount) *
sizeof(RGBQUAD);
//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0; dwBmBitsSize = ((Bitmap.bmWidth *
wBitCount+31)/32)* 4
*Bitmap.bmHeight ;
//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize+
dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
// 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = GetDC(NULL);
hOldPal = SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize,
(BITMAPINFOHEADER *)
lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC, hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
}
//创建位图文件
fh = CreateFile(lpFileName, GENERIC_WRITE,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_
FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER)
+ dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof
(BITMAPFILEHEADER)
+ (DWORD)sizeof(BITMAPINFOHEADER)
+ dwPaletteSize;
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof
(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize,
&dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
}
//lpRect 代表选定区域
{
HDC hScrDC, hMemDC;
// 屏幕和内存设备描述表
HBITMAP hBitmap, hOldBitmap;
// 位图句柄
int nX, nY, nX2, nY2;
// 选定区域坐标
int nWidth, nHeight;
// 位图宽度和高度
int xScrn, yScrn;
// 屏幕分辨率 // 确保选定区域不为空矩形
if (IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC = CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC = CreateCompatibleDC(hScrDC);
// 获得选定区域坐标
nX = lpRect- >left;
nY = lpRect- >top;
nX2 = lpRect- >right;
nY2 = lpRect- >bottom;
// 获得屏幕分辨率
xScrn = GetDeviceCaps(hScrDC, HORZRES);
yScrn = GetDeviceCaps(hScrDC, VERTRES);
//确保选定区域是可见的
if (nX 〈0)
nX = 0;
if (nY 〈 0)
nY = 0;
if (nX2 > xScrn)
nX2 = xScrn;
if (nY2 > yScrn)
nY2 = yScrn;
nWidth = nX2 - nX;
nHeight = nY2 - nY;
// 创建一个与屏幕设备描述表兼容的位图
hBitmap = CreateCompatibleBitmap
(hScrDC, nWidth, nHeight);
// 把新位图选到内存设备描述表中
hOldBitmap = SelectObject(hMemDC, hBitmap);
// 把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC, 0, 0, nWidth, nHeight,
hScrDC, nX, nY, SRCCOPY);
//得到屏幕位图的句柄
hBitmap = SelectObject(hMemDC, hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
// 返回位图句柄
return hBitmap;
}
得到屏幕位图句柄以后,我们
可以把屏幕内容粘贴到剪贴板上.
if (OpenClipboard(hWnd))
//hWnd为程序窗口句柄
{
//清空剪贴板
EmptyClipboard();
//把屏幕内容粘贴到剪贴板上,
hBitmap 为刚才的屏幕位图句柄
SetClipboardData(CF_BITMAP, hBitmap);
//关闭剪贴板
CloseClipboard();
}
我们也可以把屏幕内容以位图格式存到磁盘文件上.
int SaveBitmapToFile(HBITMAP hBitmap ,
LPSTR lpFileName) //hBitmap 为刚才的屏幕位图句柄
{ //lpFileName 为位图文件名
HDC hDC;
//设备描述表
int iBits;
//当前显示分辨率下每个像素所占字节数
WORD wBitCount;
//位图中每个像素所占字节数
//定义调色板大小, 位图中像素字节大小 ,
位图文件大小 , 写入文件字节数
DWORD dwPaletteSize=0,
dwBmBitsSize,
dwDIBSize, dwWritten;
BITMAP Bitmap;
//位图属性结构
BITMAPFILEHEADER bmfHdr;
//位图文件头结构
BITMAPINFOHEADER bi;
//位图信息头结构
LPBITMAPINFOHEADER lpbi;
//指向位图信息头结构
HANDLE fh, hDib, hPal,hOldPal=NULL;
//定义文件,分配内存句柄,调色板句柄
//计算位图文件每个像素所占字节数
hDC = CreateDC("DISPLAY",NULL,NULL,NULL);
iBits = GetDeviceCaps(hDC, BITSPIXEL) *
GetDeviceCaps(hDC, PLANES);
DeleteDC(hDC);
if (iBits 〈 = 1)
wBitCount = 1;
else if (iBits 〈 = 4)
wBitCount = 4;
else if (iBits 〈 = 8)
wBitCount = 8;
else if (iBits 〈 = 24)
wBitCount = 24;
//计算调色板大小
if (wBitCount 〈 = 8)
dwPaletteSize = (1 〈 〈 wBitCount) *
sizeof(RGBQUAD);
//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0; dwBmBitsSize = ((Bitmap.bmWidth *
wBitCount+31)/32)* 4
*Bitmap.bmHeight ;
//为位图内容分配内存
hDib = GlobalAlloc(GHND,dwBmBitsSize+
dwPaletteSize+sizeof(BITMAPINFOHEADER));
lpbi = (LPBITMAPINFOHEADER)GlobalLock(hDib);
*lpbi = bi;
// 处理调色板
hPal = GetStockObject(DEFAULT_PALETTE);
if (hPal)
{
hDC = GetDC(NULL);
hOldPal = SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
}
// 获取该调色板下新的像素值
GetDIBits(hDC, hBitmap, 0, (UINT) Bitmap.bmHeight,
(LPSTR)lpbi + sizeof(BITMAPINFOHEADER)
+dwPaletteSize,
(BITMAPINFOHEADER *)
lpbi, DIB_RGB_COLORS);
//恢复调色板
if (hOldPal)
{
SelectPalette(hDC, hOldPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
}
//创建位图文件
fh = CreateFile(lpFileName, GENERIC_WRITE,
0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_
FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
// 设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER)
+ sizeof(BITMAPINFOHEADER)
+ dwPaletteSize + dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof
(BITMAPFILEHEADER)
+ (DWORD)sizeof(BITMAPINFOHEADER)
+ dwPaletteSize;
// 写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof
(BITMAPFILEHEADER), &dwWritten, NULL);
// 写入位图文件其余内容
WriteFile(fh, (LPSTR)lpbi, dwDIBSize,
&dwWritten, NULL);
//清除
GlobalUnlock(hDib);
GlobalFree(hDib);
CloseHandle(fh);
}
E:\Test\TestView.cpp(188) : error C2440: '=' : cannot convert from 'void *' to 'struct HBITMAP__ *'
Conversion from 'void*' to pointer to non-'void' requires an explicit cast
E:\Test\TestView.cpp(190) : error C2440: '=' : cannot convert from 'void *' to 'struct HBITMAP__ *'
Conversion from 'void*' to pointer to non-'void' requires an explicit cast
E:\Test\TestView.cpp(246) : error C2660: 'GetDC' : function does not take 1 parameters
E:\Test\TestView.cpp(247) : error C2664: 'SelectPalette' : cannot convert parameter 2 from 'void *' to 'struct HPALETTE__ *'
Conversion from 'void*' to pointer to non-'void' requires an explicit cast
E:\Test\TestView.cpp(254) : error C2664: 'GetDIBits' : cannot convert parameter 6 from 'struct tagBITMAPINFOHEADER *' to 'struct tagBITMAPINFO *'
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
E:\Test\TestView.cpp(257) : error C2664: 'SelectPalette' : cannot convert parameter 2 from 'void *' to 'struct HPALETTE__ *'
Conversion from 'void*' to pointer to non-'void' requires an explicit cast
E:\Test\TestView.cpp(259) : error C2660: 'ReleaseDC' : function does not take 2 parameters
Error executing cl.exe.Test.exe - 7 error(s), 0 warning(s)
HBITMAP CScrSnapView::CopyScreenToBitmap(LPRECT lpRect)
{
HDC hScrDC,hMemDC; //屏幕和内存设备描述表
HBITMAP hBitmap,hOldBitmap;//位图句柄
int nX,nY,nX2,nY2; //选定区域坐标
int nWidth,nHeight; //位图宽度和高度
int xScrn,yScrn; //屏幕宽度和高度 //确保选定区域不为空矩形
if(IsRectEmpty(lpRect))
return NULL;
//为屏幕创建设备描述表
hScrDC=CreateDC("DISPLAY", NULL, NULL, NULL);
//为屏幕设备描述表创建兼容的内存设备描述表
hMemDC=CreateCompatibleDC(hScrDC); //或者::CreateCompatibleDC(NULL) //获得选定区域坐标
nX=lpRect->left;
nY=lpRect->top;
nX2=lpRect->right;
nY2=lpRect->bottom; //获得屏幕宽度和高度
xScrn=GetDeviceCaps(hScrDC,HORZRES);
yScrn=GetDeviceCaps(hScrDC,VERTRES); //确保选定区域是可见的
if (nX<0)
nX=0;
if (nY<0)
nY=0;
if (nX2>xScrn)
nX2=xScrn;
if (nY2>yScrn)
nY2=yScrn; nWidth=nX2-nX;
nHeight=nY2-nY; //创建一个与屏幕设备描述表兼容的位图
hBitmap=CreateCompatibleBitmap(hScrDC,nWidth,nHeight); //把新位图选到内存设备描述表中
hOldBitmap=(HBITMAP)SelectObject(hMemDC,hBitmap); //把屏幕设备描述表拷贝到内存设备描述表中
BitBlt(hMemDC,0,0,nWidth,nHeight,hScrDC,nX,nY,SRCCOPY);
//得到屏幕位图的句柄
hBitmap=(HBITMAP)SelectObject(hMemDC,hOldBitmap);
//清除
DeleteDC(hScrDC);
DeleteDC(hMemDC);
return hBitmap; //返回位图句柄
}BOOL CScrSnapView::SaveBitmapToFile(HBITMAP hBitmap, LPSTR lpFileName)
{
WORD wBitCount; //位图中每个像素所占字节数 //定义调色板大小,位图中像素字节大小,位图文件大小,写入文件字节数
DWORD dwPaletteSize=0,dwBmBitsSize,dwDIBSize, dwWritten;
BITMAP Bitmap; //位图属性结构
BITMAPFILEHEADER bmfHdr; //位图文件头结构
BITMAPINFOHEADER bi; //位图信息头结构
HANDLE fh; //定义文件,分配内存句柄,调色板句柄
LPSTR lpbk,lpmem; wBitCount = 32;
//设置位图信息头结构
GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = Bitmap.bmWidth;
bi.biHeight = Bitmap.bmHeight; //为负,正向的位图;为正,倒向的位图
bi.biPlanes = 1;
bi.biBitCount = wBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage=0;
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
bi.biClrUsed=0;
bi.biClrImportant=0;
dwBmBitsSize=((Bitmap.bmWidth*wBitCount+31)/32)*4*Bitmap.bmHeight; //创建位图文件
fh = CreateFile(lpFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
if (fh == INVALID_HANDLE_VALUE)
return FALSE;
//设置位图文件头
bmfHdr.bfType = 0x4D42; // "BM"
dwDIBSize = sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+dwBmBitsSize;
bmfHdr.bfSize = dwDIBSize;
bmfHdr.bfReserved1 = 0;
bmfHdr.bfReserved2 = 0;
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER)+(DWORD)sizeof(BITMAPINFOHEADER);
//写入位图文件头
WriteFile(fh, (LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER),&dwWritten, NULL);
//写入位图信息头
WriteFile(fh, (LPSTR)&bi,sizeof(BITMAPINFOHEADER),&dwWritten, NULL); //获取位图阵列
lpmem=new char[dwBmBitsSize];
lpbk=(LPSTR) new char[dwBmBitsSize];
GetBitmapBits(hBitmap,dwBmBitsSize,lpmem);//正向的内存图象数据
//转化为倒向数据(仅在bmHeight为正时需要)
for(int i=0;i<Bitmap.bmHeight;i++)
{
memcpy(lpbk+Bitmap.bmWidth*i*4,lpmem+Bitmap.bmWidth*(Bitmap.bmHeight-i-1)*4,Bitmap.bmWidth*4);
}
//写位图数据
WriteFile(fh, lpbk,dwBmBitsSize,&dwWritten, NULL); //清除
delete []lpbk;
delete []lpmem; CloseHandle(fh);
return TRUE;
}不过保存的位图在windows下可以查看,而在linux下却有问题,我也没有改了。
BOOL CDib::Save( const char *pszFilename )
{ // If we have no data, we can't save.
if( m_pDib == NULL )
return( FALSE ); CFile cf; // Attempt to create the file.
if( !cf.Open( pszFilename,
CFile::modeCreate | CFile::modeWrite ) )
return( FALSE );
// Write the data.
try{ // First, create a BITMAPFILEHEADER
// with the correct data.
BITMAPFILEHEADER BFH;
memset( &BFH, 0, sizeof( BITMAPFILEHEADER ) );
BFH.bfType = 'MB';
BFH.bfSize = sizeof( BITMAPFILEHEADER ) + m_dwDibSize;
BFH.bfOffBits = sizeof( BITMAPFILEHEADER ) +
sizeof( BITMAPINFOHEADER ) +
m_nPaletteEntries * sizeof( RGBQUAD ); // Write the BITMAPFILEHEADER and the
// Dib data.
cf.Write( &BFH, sizeof( BITMAPFILEHEADER ) );
cf.Write( m_pDib, m_dwDibSize );
} // If we get an exception, delete the exception and
// return FALSE.
catch( CFileException *e ){
e->Delete();
return( FALSE );
} return( TRUE );
}
如果本身不存在的会出现内存不足的警告!
[email protected] 谢谢!
我得图形是通过CDC画出来的,怎样保存呢?
SelectObject(HBITMAP);
BitBlt();//把hDC画入hMemDC。
GetBitmapBits();然后去Save();
Conversion from 'void*' to pointer to non-'void' requires an explicit cast
E:\Test\TestView.cpp(190) : error C2440: '=' : cannot convert from 'void *' to 'struct HBITMAP__ *'
这两个错误是你没有自已进行强制转换,
(HBITMAP*)在那个前面加上这个应该就可以了。 Conversion from 'void*' to pointer to non-'void' requires an explicit cast
E:\Test\TestView.cpp(246) : error C2660: 'GetDC' : function does not take 1 parameters
这个我就不太清楚了。我也这样用过的。E:\Test\TestView.cpp(247) : error C2664: 'SelectPalette' : cannot convert parameter 2 from 'void *' to 'struct HPALETTE__ *'
Conversion from 'void*' to pointer to non-'void' requires an explicit cast
E:\Test\TestView.cpp(254) : error C2664: 'GetDIBits' : cannot convert parameter 6 from 'struct tagBITMAPINFOHEADER *' to 'struct tagBITMAPINFO *'
跟前面一个错误一样没有进行类型转换,
(BITMAPINFO *)XXX
Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
E:\Test\TestView.cpp(257) : error C2664: 'SelectPalette' : cannot convert parameter 2 from 'void *' to 'struct HPALETTE__ *'
同上面的原因一样的。
Conversion from 'void*' to pointer to non-'void' requires an explicit cast
E:\Test\TestView.cpp(259) : error C2660: 'ReleaseDC' : function does not take 2 parameters
好像只要releasedc(hdc)就可以了。