• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • 圖形擦除技術及編程應用

    發表于:2007-07-14來源:作者:點擊數: 標簽:
    圖形擦除是圖形特技處理中最為常見的一種,在各種 游戲 中圖形擦除技術有著廣泛的應用。圖形擦除在本質上是圖形的消隱,即在兩幅圖片之間進行圖片的平滑過渡顯示。過渡的方式決定了圖形擦除的不同視覺效果,其中最為常見的一種就是圖片淡入淡出的更新:兩幅
    圖形擦除是圖形特技處理中最為常見的一種,在各種游戲中圖形擦除技術有著廣泛的應用。圖形擦除在本質上是圖形的消隱,即在兩幅圖片之間進行圖片的平滑過渡顯示。過渡的方式決定了圖形擦除的不同視覺效果,其中最為常見的一種就是圖片淡入淡出的更新:兩幅圖片由明到暗、由暗到明的循環交替顯示。這種特技效果在編程中的實現,往往是通過DirectX技術實現的:DirectX Transform為我們提供了一個“Microsoft DirectAnimation Control”的類(在注冊表中可以找到該類的注冊信息HKEY_CLASS_ROOT\CLSID\{B6FFC24C-7E13-11D0- 9B47-00C04FC2F51D})供調用,以此實現高質量的圖片擦除。不過,對于DirectX編程,大部分的編程愛好者對其程序框架難以適應,可以說,花在理解DirectX編程上的工夫要遠遠大于對圖形擦除技術本身的理解。有沒有一種更簡單的方法,使用常規的編程方式來實現圖形擦除呢?

    解決方案
    不同于Windows 95中的GUI(圖形用戶接口),在Windows 98以后的版本中,GUI增加了對Alpha Blending(通道混合)的支持,Alpha Blending在概念上最為明顯的就是對“通道”的應用。熟悉圖形處理的朋友對“通道”這個概念并不會感到陌生, Alpha通道是用來表示數字圖像的透明度,改變各種通道的特性,就相當于改變各種基本顏色的濃度。通常情況下,Alpha通道使用8位(Byte)二進制數,可以表示256級灰度,即256級的透明度。假設我們想要在目標區(Dst)里顯示一個像素(Src:Alpha通道值為Src.Alpha),并且要求系統進行“通道合成”運算,那么,進行合成運算的具體公式為:

      Dst.Red   = Src.Red+ (1 - Src.Alpha) ? Dst.Red
      Dst.Green = Src.Green+ (1 - Src.Alpha) ? Dst.Green

      Dst.Blue = Src.Blue + (1 - Src.Alpha) ? Dst.Blue


    從上面的公式可以看出,在進行合成運算之后,更新顯示后的目標區域顏色值(RGB)并不完全是源位圖的RGB值的拷貝,而是源位圖和目標區域進行了“合成”之后的RGB值。和BitBlt函數的像素運算不同,Alpha Blending強調的是源位圖的透明度,正是利用這樣一種合成運算,我們能夠達到圖像“透明”的效果。

    在VC中,系統提供了AlphaBlend函數來實現位圖的通道合成運算,AlphaBlend 函數主要用來顯示透明或半透明的位圖,其調用格式如下:

    BOOL AlphaBlend(
    HDC hdcDest,
    // 目標設備環境句柄
    int nXOriginDest,
    // 目標坐標x
    int nYOriginDest,
    // 目標坐標y
    int nWidthDest,
    // 目標寬度
    int nHeightDest,
    //目標高度
    HDC hdcSrc,
    //源設備環境句柄
    int nXOriginSrc,
    // 源坐標x
    int nYOriginSrc,
    // 源坐標y
    int nWidthSrc,
    //源寬度
    int nHeightSrc,
    //源高度
    BLENDFUNCTION blendFunction
    // 合成方式具體數據結構
    );


    BLENDFUNCTION定義了在源位圖和目標位圖之間進行合成的具體方式,其具體數據成員及含義如下:

    typedef struct _BLENDFUNCTION {
    BYTE BlendOp;
    BYTE BlendFlags;//必須為零
    BYTE SourceConstantAlpha;//位圖使用的透明度,0為完全透明、255為正常方式顯示
    BYTE AlphaFormat;//通常為零,如果源位圖為32位真彩色,此值可取為AC_SRC_ALPHA
    }BLENDFUNCTION, ?PBLENDFUNCTION, ?LPBLENDFUNCTION;


    由上面的函數說明我們知道,AlphaBlend能夠以特定的透明度來顯示一幅位圖,那么,如果讓AlphaBlend以不同的通道值(從0到255)不斷地交替顯示兩幅圖片,這樣就實現了“擦除”效果。

    編程實現
    了解了上述原理,編程中的具體運用就不會再是難事了,下面以在VC中為例,說明這種圖形處理技術在編程中的具體實現。

    首先在VC中新建一基于對話框的項目WipeImage。準備好兩幅等大的圖片(IDB_CROSS、IDB_LANTERN),并將圖片引入資源管理器。在CWipeImageDlg類中加入以下的全局成員變量聲明:

    class CWipeImageDlg : public CDialog
    {
    // Construction
    public:
    BLENDFUNCTION m_bf;
    CBitmap cross,lantern;
    BITMAP bmp;
    int bmpWidth,bmpHeight;
    CDC dcForCross,dcForLantern;
    CDC? dc;
    BOOL bShowLantern;
    ………(系統自動生成部分)
    };


    接著在類向導中加入對WM_INITDIALOG和WM_TIMER消息的響應,其響應代碼分別如下:

    BOOL CWipeImageDlg::OnInitDialog()
    {
    ………(系統自動生成部分)
    // TODO: Add extra initialization here
    //初始化全局成員變量
    this->bShowLantern=TRUE;
    m_bf.BlendOp = AC_SRC_OVER;
    m_bf.BlendFlags = 0;
    m_bf.SourceConstantAlpha =10;
    m_bf.AlphaFormat = 0;
    //為節約篇幅,以下代碼中略去對操作不成功的處理代碼
    if(!cross.LoadBitmap(IDB_CROSS))
    {
    AfxMessageBox("裝載位圖出錯!");
    return FALSE;
    }
    cross.GetBitmap(&&bmp);
    lantern.LoadBitmap(IDB_LANTERN);
    cross.GetBitmap(&&bmp);
    //獲得位圖的大小信息
    bmpWidth=bmp.bmWidth;
    bmpHeight=bmp.bmHeight;
    dc=this->GetDC();
    dcForCross.CreateCompatibleDC(dc);
    dcForLantern.CreateCompatibleDC(dc);
    //將位圖裝入設備環境句柄
    dcForCross.SelectObject(&&cross);
    dcForLantern.SelectObject(&&lantern);
    //打開計時器
    SetTimer(1000,50,NULL);
    return TRUE;
    }
    void CWipeImageDlg::OnTimer(UINT nIDEvent)
    {
    //圖片透明度每次遞增5點
    m_bf.SourceConstantAlpha+=5;
    //當第一幅圖片完全可見之后,顯示另一張圖片
    if(m_bf.SourceConstantAlpha>=200)
    {
    m_bf.SourceConstantAlpha=10;
    //將bShowLantern做為顯示標志,確認應該顯示哪一張圖片 
    bShowLantern=!bShowLantern;
    }
    if(bShowLantern)
    {
    //按透明度遞增的方式顯示“吊燈”圖片 AlphaBlend(?dc,0,0,bmpWidth,bmpHeight,dcForLantern,0,0,bmpWidth,bmpHeight,m_bf);
    }
    else
    {
    //按透明度遞增的方式顯示“背景”圖片
    AlphaBlend(?dc,0,0,bmpWidth,bmpHeight,dcForCross,0,0,bmpWidth,bmpHeight,m_bf);
    }
    CDialog::OnTimer(nIDEvent);
    }


    編譯說明
    由于AlphaBlend函數是在“Msimg32.dll”(對應于Msimg32.lib庫文件)中定義的。所以,為了避免LNK2001錯誤,在編譯前應該將“Msimg32.lib”文件加入FadeImage項目,然后運行上面的程序,你會發現,在或明或暗之間,你的兩幅位圖已經出現在屏幕之上了。

    原文轉自:http://www.kjueaiud.com

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>