保存成图形文件

来源:互联网 发布:centos7 3306端口查看 编辑:程序博客网 时间:2024/04/30 10:34

如何将视图窗口中的自绘图,以图片方式保存最好是.BMP格式!并且保存的图片要刚好是客户区范围之内的,同时因为我的图形会随时放大,所以也要不停的进行删除内存中保存的图片的和重新生成,请问怎么办??/ 
  

   

VC 如何把界面一区域保存为 bmp 图片文件?

----------------------------------------------------------------------

用bitblt从窗体的DC往新建的Dc里面复制
然后再把新建DC里的东西弄到位图里面

--------------------------------------------------------


我这里有一个截取客户区图像并保存成文件的函数,可以修改函数中拷贝区域的大小后直接使用

void CTest5View::OnGrabClient() 
{
// TODO: Add your command handler code here
BITMAPINFO bi;//信息头
void *pBits=NULL;
CRect rect;//客户区窗口
GetClientRect(&rect);//默认拷贝区域为客户区大小,可以自行修改rect大小
int nWidth=rect.right;
int nHeight=rect.bottom;
//填充信息头
ZeroMemory(&bi,sizeof(bi));
bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
bi.bmiHeader.biHeight=nHeight;
bi.bmiHeader.biWidth=nWidth;
bi.bmiHeader.biPlanes=1;
bi.bmiHeader.biBitCount=24;
bi.bmiHeader.biCompression=BI_RGB;
bi.bmiHeader.biSizeImage=3*nWidth*nHeight;

//拷贝客户区至内存DC
HDC hActiveDC=::GetDC(this->m_hWnd);
HDC hActiveWndCompatibleDC=CreateCompatibleDC(hActiveDC);
HBITMAP hActiveWndCompactibleBitmap=CreateCompatibleBitmap(hActiveDC,rect.right,rect.bottom);
SelectObject(hActiveWndCompatibleDC,hActiveWndCompactibleBitmap);

BitBlt(hActiveWndCompatibleDC,0,0,rect.right,rect.bottom,hActiveDC,0,0,SRCCOPY);

//保存内存DC
HDC hBmpFileDC=CreateCompatibleDC(hActiveWndCompatibleDC);
HBITMAP hBmpFileBitmap=CreateDIBSection(hActiveWndCompatibleDC,&bi,DIB_RGB_COLORS,&pBits,NULL,0);
SelectObject(hBmpFileDC,hBmpFileBitmap);
BitBlt(hBmpFileDC,0,0,nWidth,nHeight,hActiveWndCompatibleDC,0,0,SRCCOPY);

CString tempFileName=_T("test.bmp");//目标文件名
HANDLE hFile=CreateFile(tempFileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
if(hFile!=INVALID_HANDLE_VALUE)
{
DWORD dwRet=0;
//填充文件头
BITMAPFILEHEADER bmfHeader;
ZeroMemory(&bmfHeader,sizeof(bmfHeader));
bmfHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bmfHeader.bfSize=bi.bmiHeader.biSizeImage+bmfHeader.bfOffBits;
bmfHeader.bfType='MB';
WriteFile(hFile,&bmfHeader,sizeof(bmfHeader),&dwRet,NULL);
WriteFile(hFile,&bi.bmiHeader,sizeof(bi.bmiHeader),&dwRet,NULL);
WriteFile(hFile,pBits,bi.bmiHeader.biSizeImage,&dwRet,NULL);
CloseHandle(hFile);

}


--------------------------------------------------------

也可以把你要拷贝区域的rect做为一个参数传到那个函数里,可以实现你要的功能

 

一、BitBlt函数:原样复制
整个视频显示器可看作是一幅大位图,其上的像素由存储在视频显示适配卡上内存中的位来描述。所以,我们可以使用BitBlt函数来完成将图像从视频显示的一个区域复制到另一个区域。这就是位块传送(bit-block tranfer)。此函数是像素移动程序,实际上对像素执行了一次位运算操作。
BitBlt函数从称为“源”的设备描述表中将一个矩形区的像素传送到称为“目标”的另一个设备描述表中相同大小的矩形区。源和目标设备描述表可以相同。此函数语法如下:
BitBlt(hdcDst,xDst,yDst,cx,cy,hdcSrc,xSrc,ySrc,dwROP);
xSrc和ySrc参数指明了源图像左上角在源设备描述表中的坐标位置。cx和cy是图像的宽度和高度。xDst和yDst是图像复制到的设备描述表中的坐标位置。dwROP是光栅操作符。
  注意:BitBlt是从实际视频显示内存传送像素,也就是说整个显示屏上的图像都存于显存中,若图像超出了显示屏,那么BitBlt只传送在显示屏上的部分。

 

BitBlt的最大限制是两个设备描述表必须兼容,就是说两者的每个像素都具有相同的位数。所以,不能用它将屏幕上的某些图形复制到打印机。
二、StretchBlt函数:拉伸位图
此函数语法如下:StretchBlt(hdcDst,xDst,yDst,cxDst,cyDst,
hdcSrc,xSrc,ySrc,cxSrc,cySrc,dwROP);
BitBlt和StretchBlt函数中所有的坐标与大小都是基于逻辑单位的。但如果BitBlt函数中有两个不同的设备描述表,而这两个设备描述表引用相同的物理设备却具有不同的映射模式时,BitBlt就不明确了:cx和cy都是逻辑单位,它们同样应用于源设备描述表和目标设备描述表中的矩形区。此时,所有的坐标和尺寸必须在实际的位传送之前转换为设备坐标。cx和cy同时用于源和目标设备描述表,所以必须分别转换为设备描述表自己的单位。(?)
三、PatBlt函数:绘制填充图形
语法如下:PatBlt(hdc,x,y,cx,cy,dwROP);

 

GDI位图对象:也称为设备相关位图或者DDB
一、创建DDB
DDB是Windows图形设备接口的图形对象之一(其中还包括画笔、画刷、字体、元文件和调色板)。这些图形对象保存在GDI模式内部,由应用程序软件的数字句柄引用。用HBITMAP类型的变量存储DDB句柄:HBITMAP hBitmap。然后通过调用某个创建DDB的函数来获得句柄,这有三个函数。这些函数分配并初始化GDI内存中的一些内存来存储关于位图的信息,以及实际位图的位信息。应用程序不能直接访问这段内存。位图与设备描述表无关。程序使用完位图以后,就清除这段内存:DeleteObject(hBitmap);
三个函数:
CreateBitmap(cx,cy,cPlanes,cBitsPixel,bits);
CreateCompatibleBitmap(hdc,cx,cy);创建一个与设备兼容的位图。
CreateBitmapIndirect(&bitmap);bitmap是BITMAP类型的结构。
二、位图位
获得和设置像素位:
GetBitmapBits(hBitmap,cBytes,&bits);
SetBitmapBits(hBitmap,cBytes,&bits);
cBytes指明要复制的字节数,bits是其大小至少为cBytes的缓冲区。
像素实际上并不涉及任何固定的颜色,它只是一个值,与在视频板上的调色板查找表是的索引值有关。
基本的规则:不要用CreateBitmap、CreateBitmapIndirect或SetBitmapBits来设置彩色DDB的位,只能安全地设置单色DDB的位。
三、内存设备描述表
设备描述表指的是某个图形输出设备(如显示器或打印机),及其设备驱动程序。
内存设备描述表只位于内存中,它不是真正的图形输出设备,但可以说与某个实际设备“兼容”。在有某个实际设备的设备描述表之后,就可以创建内存设备描述表:
hdcMem=CreateCompatibleDC(hdc);
如果其参数为NULL,则创建一个与显示器相兼容的内存设备描述表。最后用DeleteDC来清除。
内存设备描述表有一个与实际光栅设备相同的、单色、1像素宽、1像素高的显示表面。然后,通过将一个GDI位图对象选进内存设备描述表来完成扩大显示表面的工作:SelectObject(hdcMem,hBitmap);
内存设备描述表是唯一一种可以选进位图的设备描述表。SelectObject调用以后,DDB就是内存设备描述表的显示表面。可以在其上进行各种处理实际设备描述表的每项操作。
批注:内存设备描述表实际上提供了一种在内存和显示器间进行位图传送的方法。
四、加载位图资源
也可用LoadBitmap函数来获得GDI位图对象句柄。
五、单色位图格式
对于单色位图,可以用一个字节数组来描述位图中的各个像素。
先用BITMAP结构来定义位图的信息,再用BYTE类型的数组来定义各个像素定义的各个位,最后用CreateBitmap、CreateBitmapIndirect来创建位图。

 void  CMyBView::SaveToBmp()
{
  BITMAPINFO bi;//信息头
  void *pBits=NULL;
  CRect rect(startpoint.x, startpoint.y, temppoint.x, temppoint.y);//客户区窗口
 // GetClientRect(&rect);
  int nWidth = maxpoint.x - minpoint.x;
  int nHeight= maxpoint.y - minpoint.y;

  //填充信息头
  ZeroMemory(&bi,sizeof(bi));
  bi.bmiHeader.biSize=sizeof(bi.bmiHeader);
  bi.bmiHeader.biHeight=nHeight;
  bi.bmiHeader.biWidth=nWidth;
  bi.bmiHeader.biPlanes=1;
  bi.bmiHeader.biBitCount=24;
  bi.bmiHeader.biCompression=BI_RGB;
  bi.bmiHeader.biSizeImage=3*nWidth*nHeight;

//拷贝客户区至内存DC
  HDC hActiveDC=::GetDC(this->m_hWnd);
  HDC hActiveWndCompatibleDC=CreateCompatibleDC(hActiveDC);
  HBITMAP hActiveWndCompactibleBitmap=CreateCompatibleBitmap(hActiveDC,nWidth,nHeight);
  SelectObject(hActiveWndCompatibleDC,hActiveWndCompactibleBitmap);
  
  BitBlt(hActiveWndCompatibleDC,0,0,nWidth,nHeight,hActiveDC,minpoint.x,minpoint.y,SRCCOPY);

//保存内存DC
  HDC hBmpFileDC=CreateCompatibleDC(hActiveWndCompatibleDC);
  HBITMAP hBmpFileBitmap=CreateDIBSection(hActiveWndCompatibleDC,&bi,DIB_RGB_COLORS,&pBits,NULL,0);
  SelectObject(hBmpFileDC,hBmpFileBitmap);
  BitBlt(hBmpFileDC,0,0,nWidth,nHeight,hActiveWndCompatibleDC,0,0,SRCCOPY);

  
  CString tempFileName=_T("test.bmp");//目标文件名
  CFileDialog dlg(FALSE, _T("bmp"), _T("Temp.bmp"), OFN_HIDEREADONLY  | OFN_OVERWRITEPROMPT, _T("Bitmap Files (*.bmp) |*.bmp |All Files (*.*) |*.* | |"), this);
  if(dlg.DoModal() == IDOK)
  {
  tempFileName=dlg.GetPathName();
  }
  HANDLE hFile=CreateFile(tempFileName,GENERIC_WRITE,FILE_SHARE_WRITE,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
  if(hFile!=INVALID_HANDLE_VALUE)
  {
  DWORD dwRet=0;

  //填充文件头
  BITMAPFILEHEADER bmfHeader;
  ZeroMemory(&bmfHeader,sizeof(bmfHeader));
  bmfHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
  bmfHeader.bfSize=bi.bmiHeader.biSizeImage+bmfHeader.bfOffBits;
  bmfHeader.bfType= 'MB';
  WriteFile(hFile,&bmfHeader,sizeof(bmfHeader),&dwRet,NULL);
  WriteFile(hFile,&bi.bmiHeader,sizeof(bi.bmiHeader),&dwRet,NULL);
  WriteFile(hFile,pBits,bi.bmiHeader.biSizeImage,&dwRet,NULL);
  CloseHandle(hFile);
  }
}

  BitBlt(hActiveWndCompatibleDC,0,0,nWidth,nHeight,hActiveDC,minpoint.x,minpoint.y,SRCCOPY);

 minpoint.x,minpoint.y, 原起点

原创粉丝点击