MFCでのpictureコントロールによる画像表示

7399 ワード

参考博文
    http://blog.sina.com.cn/s/blog_4d8730df0100mpzj.html
   http://blog.csdn.net/chenyusiyuan/article/details/4744097
本稿ではopencv 246とVS 2012がMFCで画像表示を行う際に発生する問題点について説明する
一、MFC 1を作成するにはまずMFCダイアログアプリケーション(Dialog-based Application)を作成する.2 OKをクリック--Nextをクリックして次のステップに進み、ここではDialog-based Applicationを作成する.ほとんどのオプションはデフォルト設定でいいが、一番下の「UseUnicode libraries」は削除したほうがいい.
のオプションで、プログラムコードは16 bitのUnicode文字セットで符号化されますが、多くの関数ではchar*(ASCII stings)タイプの文字を使用しますが、UnicodeからASCIIに文字列を変換するのは面倒です.Unicodeを使用すると、コンパイル時に次のエラーが発生する可能性があります.cannot convert parameter 1 from'CString'to'const char*'cannot convert from'const char[11]'to'LPCWSTR'これは、UnicodeとMulti-byte文字列の変換で問題が発生したことを意味します.そこで、ここでは「UseUnicode libraries」オプションを外します.
二、コードを書く
1プロジェクトファイルを開き、リソースビューに入ります:LoadPicture(プロジェクト名)->LoadPicture.rc->Dialog IDD_LoadPicture_DIALOGをダブルクリックすると、初期のGUIインタフェースが表示され、ButtonとPictureコントロールが2つ追加されます
個々のコントロールを選択し、右クリックして属性を選択すると、コントロールのID番号が表示されます.この番号は自分で編集できます.例えば、PictureコントロールのID番号はIDC_ShowImgに設定します.このID番号は後の画像表示関数で使用します.
2 OpencvライブラリをVSに追加します.構成が間違っていないと、Opencv 246+VS 2012の構成課はこのブログを参考にします.VS 2012のOPENCV 246の構成
3それからLoadPicture.hの#include“resource.h”コード行の下に以下のコードを加える.
#include 
#include 
#define IMAGE_WIDTH 256
#define IMAGE_HEIGHT 256
#define IMAGE_CHANNELS 3
4クラスビューパネルでCloadPictureDlgを右クリックし、Add->Add Variableを選択し、IplImage*タイプの変数TheImageを追加します.
 
利用MFC中的picture control 控件显示图像_第1张图片
利用MFC中的picture control 控件显示图像_第2张图片
CLoadPictureDlgをクリックし、下のウィンドウのリストでOnInitDialogをダブルクリックし、//TODO:追加の初期化コードを追加し、TheImageの初期化コードを追加します.
 
CvSize ImgSize;    
ImgSize.height = IMAGE_HEIGHT;    
ImgSize.width = IMAGE_WIDTH;    
TheImage=cvCreateImage( ImgSize, IPL_DEPTH_8U, IMAGE_CHANNELS );
5次にOnPaintをダブルクリックし、if(ISIconic()のelseに次のコードを追加してウィンドウを再描画します.
CDialog::OnPaint();//再描画ダイアログ
CDialog::UpdateWindow();//Windowsウィンドウを更新します.この呼び出しがなければ、画像表示に問題が発生します.
ShowImage( TheImage, IDC_ShowImg );//ピクチャ関数の再描画
次にCtestPicControlAppの下のメンバーリストでInitInstanceをダブルクリックし、「//TODO:Place code here to handle when the dialog is...」の2つの下にcvReleaseImage(&dlg.TheImage)を追加します.
すなわち、「OK」または「Cancel」を押すと、TheImageが使用するメモリが解放されます.
 
6画像の読み取りと処理の機能関数を書きます.
リソースビューに戻り、ボタンReadImageをダブルクリックし、ボタンクリックのメッセージ応答プログラムを確立する:OnBnClickedReadimage、主な応答操作はポップアップダイアログボックスで画像ファイルを選択し、画像ファイルを読み込み、画像を256*256の大きさに統一的にスケールし、画像を表示することを含む.コードは以下の通りである.
// TODO:               
        CFileDialog dlg(
                TRUE, _T("*.bmp"), NULL,
                OFN_FILEMUSTEXIST | OFN_PATHMUSTEXIST | OFN_HIDEREADONLY,
                _T("image files (*.bmp; *.jpg) |*.bmp; *.jpg | All Files (*.*) |*.*||"), NULL
                );                                                                              //        
        dlg.m_ofn.lpstrTitle = _T("Open Image");         //            
        if(dlg.DoModal()!=IDOK )      //         
                return;

        CString mPath = dlg.GetPathName();   //       

        IplImage* ipl = cvLoadImage( mPath, 1 );   //     、          ipl  
        if(!ipl)                                                                       //           
                return;
        if(TheImage)                                                           //              
                cvZero( TheImage );
        ResizeImage( ipl );      //           ,              256,     TheImage  
        ShowImage( TheImage, IDC_ShowImg);                     //              
        cvReleaseImage(&ipl);                                          //    ipl      

7上記のコードには2つの新しいメンバー関数ResizeImageとShowImageが含まれており、前者は読み込まれた異なるサイズの画像をスケーリングし、ROIを設定することで256*256のTheImageに画像を格納する役割を果たす.後者は、画像表示コントロールIDC_に画像TheImageを表示するShouImgウィンドウの真ん中.この2つの機能を実現するには、まずクラスビューパネルでCtestPicControl Dlgを右クリックし、Add->Add Functionを選択し、void ShowImage(IplImage*img、UINT ID)とvoid ResizeImage(IplImage*img)の2つの関数を作成します.次の2つの関数の実装コードを示します.
関数の追加
利用MFC中的picture control 控件显示图像_第3张图片
void CLoadPicControlDlg::ShowImage(IplImage* img, UINT ID)// ID  Picture Control   ID 
{
        CDC* pDC=GetDlgItem(ID)->GetDC();//         DC
        HDC hDC=pDC->GetSafeHdc();//    HDC(    )        

        CRect rect;
        GetDlgItem(ID)->GetClientRect(&rect);
        int rw=rect.right-rect.left;    //   picture control    
        int rh=rect.bottom-rect.top;
        int iw=img->width;             //         
        int ih=img->height;
        int tx = (int)(rw - iw)/2;                                       //                 
        int ty = (int)(rh - ih)/2;
        SetRect( rect, tx, ty, tx+iw, ty+ih );

        CvvImage cimg;
        cimg.CopyOf(img);    //     
        cimg.DrawToHDC(hDC,&rect);

        ReleaseDC(pDC);
}
void CtestPicControlDlg::ResizeImage(IplImage* img)
{
        //         
        int w = img->width;
        int h = img->height;

        //            
        int max = (w > h)? w: h;

        //         TheImage         
        float scale = (float) ( (float) max / 256.0f );

        //          
        int nw = (int)( w/scale );
        int nh = (int)( h/scale );

        //             TheImage      ,       TheImage          
        int tlx = (nw > nh)? 0: (int)(256-nw)/2;
        int tly = (nw > nh)? (int)(256-nh)/2: 0;

        //    TheImage   ROI   ,       img
        cvSetImageROI( TheImage, cvRect( tlx, tly, nw, nh) );

        //     img     ,     TheImage  
        cvResize( img, TheImage );

        //    TheImage   ROI          
        cvResetImageROI( TheImage );
}

利用MFC中的picture control 控件显示图像_第4张图片
 
に注意
1:もしあなたのCvvImageに赤いベースラインのヒントが現れて定義されていないならば、それはあなたのopencvバージョンが比較的新しい中のCvvImage関数がすでに取り除かれたことを説明して、私のopencv 246はこの関数がありません.工程にCvImageを入れる限り.hとCvImage.cppでいいです.この2つのファイルについては、このブログを参照してください.http://blog.csdn.net/lxy201700/article/details/16921715
2:コンパイル後error C 4996:'fopen':This function or variable may be unsafe.のエラーメッセージの説明のvsバージョンは比較的に新しくて、VS 2008の中でただwarningで、私のはVS 2012のエラーファイルの生成に失敗しました.この問題の解決についてはブログを参照してください.http://blog.csdn.net/lxy201700/article/details/16921629