<menu id="w8yyk"><menu id="w8yyk"></menu></menu>
  • <dd id="w8yyk"><nav id="w8yyk"></nav></dd>
    <menu id="w8yyk"></menu>
    <menu id="w8yyk"><code id="w8yyk"></code></menu>
    <menu id="w8yyk"></menu>
    <xmp id="w8yyk">
    <xmp id="w8yyk"><nav id="w8yyk"></nav>
  • 網站首頁 > 物聯資訊 > 技術分享

    在MFC下實現圖像放大鏡

    2016-09-28 00:00:00 廣州睿豐德信息科技有限公司 閱讀
    睿豐德科技 專注RFID識別技術和條碼識別技術與管理軟件的集成項目。質量追溯系統、MES系統、金蝶與條碼系統對接、用友與條碼系統對接

    當我們想仔細觀察某個細微的東西時,一般都會使用放大鏡。而要看清顯示在計算機屏幕上的圖片或文字時通常也可以借助于Windows操作系統附帶的放大程序來實現。但該程序只能以固定的放大倍數去進行觀看,有時并不能滿足我們的需要。本文就通過MFC基本類庫提供的StretchBlt函數來實現對屏幕圖象的局部放大,并且可以隨意放大、縮小,選取到合適的放大倍數來對圖像的細節進行觀察。

    設計與實現

    本程序主要用來對圖像的局部進行可調倍數的放大,應當具有以下主要功能:

    1. 移動MOUSE放大顯示圖像的不同部位

    2. 左擊增加放大倍率、右擊減少放大倍率。

    從光學角度來看,對物體的放大成像是通過把較小的真實物體顯示成尺寸較大的虛像來實現的。因此我們可以用類似的原理,把圖像中待放大的區間從較小的顯示范圍拉伸到一個比較大的顯示范圍即可達到圖像放大的效果,兩個區間的比值也就是圖像的放大倍率。可以通過縮小源區間的范圍或擴大放大區間的范圍來實現放大倍率的調整。在MFC基本類庫中提供有CDC類的StretchBlt函數可以將一幅位圖從一個源矩形以一定的光柵操作拷貝到另外一個不同大小的目標矩形中去,因此可以用此函數來實現圖象放大的功能,其函數原形聲明如下:

    BOOL StretchBlt( int x, int y, //目標矩形的坐標原點

    int nWidth, int nHeight, //目標矩形的長度和寬度

    CDC* pSrcDC, //源設備環境句柄

    int xSrc, int ySrc, //源矩形的坐標原點

    int nSrcWidth, int nSrcHeight, //源矩形的長度和寬度

    DWORD dwRop ); //光柵操作標志

    當指定的源和目標矩形的寬度或高度不一樣時,StretchBlt函數將創建一個位圖的鏡像。如果是寬度有變化,就沿x軸創建鏡像;如果是高度上有變化就沿y軸創建鏡像。而且該函數可以在內存中對源圖象做拉伸或壓縮處理后再拷貝到目標矩形中去。

    要放大圖像首先要把圖像顯示出來,一般可以從文件動態裝載或者直接從資源中用LoadBitMap讀取位圖資源。下面的代碼放在視類的OnDraw函數中,用以在第一次調用時將位圖裝載并顯示出來,以后再被調用只是負責重畫:

    ……

    static bool load;

    if (!load)

    {

    BITMAP bm;

    load = !load;

    //裝載位圖到 m_pBitmap

    m_pBitmap->LoadBitmap(IDB_BITMAP1);

    //創建相關的設備環境

    m_pdcMem->CreateCompatibleDC(pDC);

    //將位圖從m_ pBitmap中裝載到m_pdcMem中

    m_pdcMem->SelectObject(m_pBitmap);

    m_pBitmap->GetObject(sizeof(bm),&bm);

    m_sizeSource.cx = bm.bmWidth;

    m_sizeSource.cy = bm.bmHeight;

    m_sizeDest = m_sizeSource;

    //把位圖從m_pdcMem中裝載到當前正在使用的設備環境中

    pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,m_pdcMem,0,0,m_sizeSource.cx,m_sizeSource.cy,mana);

    }

    else

    {

    //重畫圖像

    pDC->StretchBlt(0,0,m_sizeSource.cx,m_sizeSource.cy,m_pdcMem,0,0,m_sizeSource.cx,m_sizeSource.cy,mana);

    SetCursor(NULL);//隱藏鼠標

    }

    要實現前面提到的第一個功能:移動MOUSE放大顯示圖像的不同部位,顯然首先要在WM_MOUSEMOVE消息的響應函數里編寫代碼。以整形變量s和d來分別表示所選取的源和目標區域的大小,再通過消息響應函數OnMouseMove的入口參數point來確定當前的鼠標位置就可以計算出我們要選取的源和目標區域在圖像的位置。放大的工作只需通過StretchBlt函數將源區域中所在的圖像拉伸到目標矩形那么大,并拷貝給目標區域即可實現所選區域的放大效果,下面是部分主要代碼:

    ……

    //確定目標區域、源區域的坐標位置

    CRect srect,drect,mrect;

    srect.left = point.x – s;

    srect.top = point.y – s;

    srect.right = point.x + s;

    srect.bottom = point.y + s;

    drect.left = point.x – d;

    drect.top = point.y – d;

    drect.right = point.x + d;

    drect.bottom = point.y + d;

    mrect.left = oldx – d;

    mrect.top = oldy – d;

    mrect.right = oldx + d;

    mrect.bottom = oldy + d;

    dd = 2*d;

    //獲取可用設備環境句柄

    CDC * pDC = GetDC();

    OnPrepareDC(pDC);

    if (recover)

    {

    pDC->BitBlt(mrect.left,mrect.top,dd,dd,m_pdcMem,mrect.left,mrect.top,mana);

    }

    //隱藏鼠標

    SetCursor(NULL);

    //拉伸放大

    pDC->StretchBlt(drect.left,drect.top,drect.Width(),drect.Height(),m_pdcMem,srect.left,srect.top,srect.Width(),srect.Height(),SRCCOPY);

    //保存當前鼠標位置備用

    oldx = point.x; oldy = point.y;

    //釋放設備環境句柄

    ReleaseDC(pDC);

    recover = true;

    ……

    為了實現第二個功能:左擊增加放大倍率、右擊減少放大倍率,可以分別在消息WM_LBUTTONDOWN和消息WM_RBUTTONDOWN中添加改變選取區域大小的代碼來實現。如果選取源矩形不變而改變目標矩形的大小會隨著放大倍數的增大,顯示區域也不斷增大,當放大到一定程度的時候會另人無法忍受,因此選取通過縮放源矩形大小來控制放大倍數的方案:

    void CZoomInView::OnRButtonDown(UINT nFlags, CPoint point)

    {

    if (s < 60)

    {

    SetCursor(NULL);

    s+=3;

    OnMouseMove(nFlags, point);

    }

    CView::OnRButtonDown(nFlags, point);

    }

    ……

    void CZoomInView::OnLButtonDown(UINT nFlags, CPoint point)

    {

    if(s>5)

    {

    s-=3;

    SetCursor(NULL);

    OnMouseMove(nFlags, point);

    }

    CView::OnLButtonDown(nFlags, point);

    }

    RFID管理系統集成商 RFID中間件 條碼系統中間層 物聯網軟件集成
    最近免费观看高清韩国日本大全