保存成圖形文件

如何將視圖窗口中的自繪圖,以圖片方式保存最好是.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, 原起點

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章