1、邏輯坐標(單位長度 窗口) 和 設(shè)備坐標(像素長度 視口)
<1>邏輯坐標。邏輯坐標即是世界坐標系下的坐標。邏輯坐標與設(shè)備無關(guān),客觀世界中的場景可以由世界窗口或視口中進行描述,在窗口中進行描述時使用世界坐標系中的坐標單位也即邏輯坐標,在視口中進行描述使用的是設(shè)備坐標。
<2>設(shè)備坐標。圖形輸出時,Windows將GDI函數(shù)中指定的邏輯坐標映射為設(shè)備坐標。在屏幕顯示的設(shè)備坐標系統(tǒng)中,單位以像素點為準,水平值從左到右增大(正方向向右),垂直值從上到下增大(正方向向下)。注意設(shè)備坐標系的原點永遠不會移動,它們僅僅與物理設(shè)備有關(guān)。
另有鏈接講了一些映射模式中設(shè)備坐標與邏輯坐標轉(zhuǎn)換 http://blog.csdn.net/pcliuguangtao/article/details/5961458
2、幾點細節(jié)區(qū)分
<1>設(shè)備坐標用對象距離窗口左上角的水平距離和垂直距離來指定對象的位置,是以像素為單位來表示的
<2>邏輯坐標和設(shè)備坐標即使在缺省模式(MM_TEXT)下其數(shù)值也未必一致,除了在以下兩種情況下: 1. 窗口為非滾動窗口 2. 窗口為滾動窗口,但垂直滾動條位于滾動邊框的最上端,水平滾動條位于最左端,但如果移動了滾動條這兩種坐標就不一致了。
<3>在VC中鼠標坐標的坐標位置用設(shè)備坐標表示,但所有GDI繪圖都用邏輯坐標表示,所以用鼠標繪圖時,那么必須將設(shè)備坐標轉(zhuǎn)換為邏輯坐標,可以使用CDC 函數(shù)DptoLP()將設(shè)備坐標轉(zhuǎn)化為邏輯坐標,同樣可以用LptoDP()將邏輯坐標轉(zhuǎn)化為設(shè)備坐標。
3、Bitblt用法
在VC中顯示位圖常用取BitBlt()方法,它是將一幅位圖從一個設(shè)備場景復(fù)制到另一個。源和目標DC相互間必須兼容。假設(shè)我已經(jīng)將要用的位圖導(dǎo)入到工程資源中,所以我可以用: CBitmap cbmp; cbmp.LoadBitmap(IDB_BMP1);這樣得到一個CBitmap對象。然后: BITMAP bitmap; cbmp.GetBitmap(&bitmap);這樣得到一個BITMAP對象,之所以要得到此對象是因為從其中可以得到位圖的大小數(shù)據(jù)。然后計算得到要在什么位置顯示此位圖(可以放在一個CRect rect;對象中)。然后顯示此位圖,這是最重要的一步: CDC dcMemory; dcMemory.CreateCompatibleDC(pDC); hOldBitmap = dcMemory.SelectObject(&cbmp); pDC->BitBlt(rect.left, rect.top, bitmap.bmWidth, bitmap.bmHeight, &dcMemory, 0,0, SRCCOPY);其中pDC是一個CDC*,是將要在其中顯示位圖的設(shè)備環(huán)境。這樣位圖就已經(jīng)顯示出來了,但是還要釋放資源: cbmp.DeleteObject(); dcMemory.SelectObject(hOldBitmap); dcMemory.DeleteDC();其中,要將臨時設(shè)備環(huán)境選擇入初始時位圖,否則將不能正確釋放!!
Bitblt作用將某一內(nèi)存塊的數(shù)據(jù)傳送到另一內(nèi)存塊,前一內(nèi)存塊被稱為"源",后一內(nèi)存塊被稱為"目標"圖象程序開發(fā)者使用Blit的函數(shù)在內(nèi)存中將某頁面上的一幅位圖經(jīng)過一定的變換轉(zhuǎn)移到另一個頁面上BitBlt光柵操作符dwRop參數(shù)是光柵操作代碼(Rop),它是指源位圖與目標位圖以及圖案刷的顏色值進行布爾運算的方式,以下列出了常用的光柵操作碼及含義BLACKNESS 用黑色填充目標矩形區(qū)域.DSTINVERT 將目標矩形圖象進行反相. MERGECOPY 將源矩形圖象與指定的圖案刷(Pattern)進行布爾"與"運算. MERGEPAINT 將源矩形圖形經(jīng)過反相后,與目標矩形圖象進行布爾"或"運算.NOTSRCCOPY 將源矩形圖象經(jīng)過反相后,復(fù)制到目標矩形上.NOTSRCERASE 先將源矩形圖象與目標矩形圖象進行布爾"或"運算,然后再將得圖象進行反相.PATCOPY 將指定的圖案刷復(fù)制到目標矩形上.PATINVERT 將指定的圖案刷與目標矩形圖象進行布爾"異或"運算.PATPAINT 先將源矩形圖象進行反相,與指定的圖案刷進行布爾"或"運算,再與目標矩形圖象進行布爾"或"運算SRCAND 將源矩形圖象與目標矩形圖象進行布爾"與"運算.SRCCOPY 將源矩形圖象直接復(fù)制到目標矩形上.SRCERASE 將目標矩形圖象進行反相,再與源矩形圖象進行布爾"與"運算.SRCINVERT 將源矩形圖象與目標矩形圖象進行布爾"異或"運算.SRCPAINT 將源矩形圖象與目標矩形圖象進行布爾"或"運算.WHITENESS 用白色填充目標矩形區(qū)域.
4、可同理 StrenchBlt SetDIBitsToDevice StretchDIBits但注意三點點<1>使用StrenchXXX時,需要先設(shè)置CDC::SetStretchBltMode(MODE),其中MODE可取COLORONCOLOR或HALFTONE
<2>設(shè)備無關(guān)圖xxxDIBitsxxx 函數(shù)參數(shù)包含BITMAPINFO,因為需要傳入自定義調(diào)色板, 而設(shè)備相關(guān)圖可直接使用BitBlt 或 StrenchBlt
<3>在StrenchXXX中,通過改變源與目標 寬、高正負號可使圖片完成上下,左右等翻轉(zhuǎn)
// 我傳入的圖片指針,指向內(nèi)容從圖片正確顯示方向,由左至右,由上至下的順序(見5<1>) void LiveView_CWJ(CWnd* pWnd, unsigned char * pImageBuffer, S_Show_Position* p, BITMAPINFO* bmpInfo, int nStretchMode) { CDC * pDC = pWnd->GetDC(); CDC MemDC; if(!MemDC.CreateCompatibleDC(pDC)) { pWnd->ReleaseDC(pDC); return; } CBitmap bmp; bmp.CreateCompatibleBitmap(pDC,bmpInfo->bmiHeader.biWidth,bmpInfo->bmiHeader.biHeight); CBitmap* pOldBmp = MemDC.SelectObject(&bmp); ::SetDIBitsToDevice(MemDC.GetSafeHdc(), 0,0,bmpInfo->bmiHeader.biWidth,bmpInfo->bmiHeader.biHeight, 0,0, //掃描方向由圖像底部向上開始顯示,我的理解是,設(shè)備無關(guān)圖操作從數(shù)據(jù)"最后一行"往前開始顯示,而設(shè)備相關(guān)圖則從頭到尾顯示 //沒做過測試哈^_^, 另外需要找時間再試試 改變映射模式時這幾個API的顯示效果 0,(bmpInfo->bmiHeader.biHeight),pImageBuffer,bmpInfo,DIB_RGB_COLORS);pDC->SetStretchBltMode(COLORONCOLOR);//COLORONCOLOR HALFTONEpDC->StretchBlt(p->x,p->y,p->S_Width,p->S_Height,&MemDC,0,bmpInfo->bmiHeader.biHeight,/*first*/bmpInfo->bmiHeader.biWidth,-bmpInfo->bmiHeader.biHeight,/*second */ //兩者都為0時和此時對比,圖像上下翻轉(zhuǎn)SRCCOPY);MemDC.SelectObject(pOldBmp);MemDC.DeleteDC();bmp.DeleteObject();pWnd->ReleaseDC(pDC);}5、這張圖像說明兩個問題<1> 上面的解釋中,我傳入的圖像指針,內(nèi)存數(shù)據(jù) 按照 下圖中小窗口中從左至右,自上而下的順序排列
<2>Matlab讀入二進制數(shù)據(jù),展示時,按照先排“列”再排“行”,也就是說正確的顯示方向應(yīng)該講Matlab讀入的數(shù)據(jù)轉(zhuǎn)置后顯示,才是正確的方向

新聞熱點
疑難解答