画像処理まとめ

コンストラクタでビットマップをリソースからロード

CMFCDlg::CMFCDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMFCDlg::IDD, pParent)
, m_dwState(0)
{
    m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);

    m_Back.LoadBitmapA(IDB_BACK);//ビットマップをリソースからロード
    m_Picture.LoadBitmapA(IDB_PICTURE);

    m_font.CreateFont(
        12,                        // nHeight
        0,                         // nWidth
        0,                         // nEscapement
        0,                         // nOrientation
        FW_NORMAL,                 // nWeight
        FALSE,                     // bItalic
        FALSE,                     // bUnderline
        0,                         // cStrikeOut
        SHIFTJIS_CHARSET,          // nCharSet
        OUT_DEFAULT_PRECIS,        // nOutPrecision
        CLIP_DEFAULT_PRECIS,       // nClipPrecision
        DEFAULT_QUALITY,           // nQuality
        DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
        "MS ゴシック");          / lpszFacename
}

デストラクタでビットマップを解放

CMFCDlg::~CMFCDlg()
{
    m_Back.DeleteObject();
    m_Picture.DeleteObject();
    m_font.DeleteObject();
}

システムのクライアント領域を取得

    RECT rc;
    SystemParametersInfo(SPI_GETWORKAREA,0,&rc,0);
    SetWindowPos(&wndNoTopMost,0,0,rc.right,rc.bottom,SWP_SHOWWINDOW|SWP_DRAWFRAME);

ダイアログにビットマップを貼る

void CMFCDlg::PaintPictureToDlg(
                                CBitmap& bitmap,
                                int x,//ダイアログのX座標
                                int y,//ダイアログのY座標
                                DWORD dwRop)//実行するラスタ オペレーション
{
    BITMAP bm;
    bitmap.GetBitmap(&bm);
    int Height = bm.bmHeight;
    int Width = bm.bmWidth;

    CClientDC Current(this);
    CDC dc;
    dc.CreateCompatibleDC(&Current);
    dc.SelectObject(&bitmap);

    RECT rc;
    GetClientRect(&rc);

    Current.BitBlt(x,y,Width,Height,&dc,0,0,dwRop);

    /* 以下はデストラクタで実施するため不要とのこと msdnより
    dc.SelectObject(old);
    dc.DeleteDC();
    */
}

ダイアログにビットマップを貼る(全部貼る場合)
void CMFCDlg::PaintPictureToDlgAll(
                       CBitmap& bitmap,
                       int x,//ダイアログのX座標
                       int y,//ダイアログのY座標
                       DWORD dwRop)//実行するラスタ オペレーション
{
    PaintPictureToDlg(bitmap,x,y,dwRop);
}

ダイアログにテキストを貼る

void CMFCDlg::DrawTextToDlg(
                            const CString& str,
                            CFont& font,
                            LPRECT lpRect,
                            UINT nFormat, 
                            COLORREF textColor,
                            COLORREF backcrColor,
                            int nBkMode)
{
    CClientDC Current(this);
    Current.SelectObject(&font);
    Current.SetTextColor(textColor);
    Current.SetBkColor(backcrColor);
    Current.SetBkMode(nBkMode);

    Current.DrawText(str,lpRect,nFormat);
}

ダイアログの特定部分を背景で書き直す(点滅に使用)

void CMFCDlg::ReDrawPartOfToDlg(
                            const CBitmap& Back,//ダイアログの背景
                            const RECT& rt)//背景で再描画する範囲
{
    CClientDC Current(this);
    CDC dc;
    dc.CreateCompatibleDC(&Current);
    dc.SelectObject(const_cast<CBitmap*>(&Back));
    Current.TransparentBlt(
        rt.left,
        rt.top,
        rt.right - rt.left,
        rt.bottom - rt.top,
        &dc,
        rt.left,
        rt.top,
        rt.right - rt.left,
        rt.bottom - rt.top,
        RGB(0,0,0));
}

画像の点滅

  • ポイントはOnTimer内で画面の特定領域だけを入れ替えること.OnTimer内でInvalidateRect()等を呼んで,毎回OnPaint()していた参考書もあったが,これだと,いくらか工夫は出来ても,ちらつきを完全に抑えることは出来ない。

ビットマップの場合

void CMFCDlg::OnTimer(UINT_PTR nIDEvent)
{
    const int X = 100;
    const int Y = 200;
    if (nIDEvent == 0xCAFE)
    {
        static bool f = true;

        SetTimer(0xCAFE,500,NULL);
        if (f)
        {
            //絵を貼る
            PaintPictureToDlgAll(m_Picture,X,Y,SRCCOPY);
            f = false;
        }
        else
        {
            BITMAP bm;
            m_Picture.GetBitmap(&bm);

            //絵と同じ範囲の背景を貼る
            RedrawPartOfToDlg(m_Back,rt);
            f = true;
        }
    }
    CDialog::OnTimer(nIDEvent);
}

テキストの場合

  • こっちも同じ要領
void CMFCDlg::OnTimer(UINT_PTR nIDEvent)
{
    RECT rt = {100,200,300,220};
    if (nIDEvent == 0xCAFE)
    {
        SetTimer(0xCAFE,500,NULL);
        static bool f = true;
        if (f)
        {
            DrawTextToDlg("こんにちは",m_font,&rt,DT_CENTER|DT_VCENTER,RGB(0,0,0),RGB(255,255,255),TRANSPARENT);
            f = false;
        }
        else
        {
            RedrawPartOfToDlg(m_Back,rt);
            f = true;
        }

    }
    CDialog::OnTimer(nIDEvent);
}

コメントをかく


「http://」を含む投稿は禁止されています。

利用規約をご確認のうえご記入下さい

管理人/副管理人のみ編集できます