32ビットDIBクラスを使ってフォトレタッチソフトを創ってみます。高度な機能はなくても、手軽で直感的に扱えるソフトを目指し、本格的な作業用と言うよりはビットマップで遊んでみる、という感じのソフトになるでしょう。ちょうど「DIBとグラフィック処理で遊ぶ」の方向性と同じですね。実際、機能としてはあそこでやって来た処理をまとめて一つのソフトに入れたような感じになると思います。
プログラムの基本的な構造としては、Win32のメインプログラムからDIBクラスのインスタンスを生成しそのインスタンスを操作して各種処理を行うようにします。その処理に関しても、フィルタやRGBの変換など基本的な処理はDIBクラスの方にメンバ関数として定義し、メインプログラムから適当なパラメータを渡してその関数を呼び出すようにしましょう。ビットマップの実体や処理機構はDIBクラスが保持し、メインプログラムはDIBクラスのインターフェース的な性格にするわけですね。これによって、DIBの処理はDIBクラス、ユーザーインターフェースはメインプログラムに分けて書く事が出来るのでわかりやすいプログラムになる....と思います。うまく書けば(^^;。
今回のプログラムでは、DIBクラス型のグローバル変数cfdibを定義し、この変数(DIBクラスC32DIBのデフォルトコンストラクタで生成されたC32DIBインスタンス)の機能を利用してBMPファイルの読み書きや白黒化、といった操作を行ってみました。
今回のメインプログラムでは、ウインドウにメニューをつけてみました。ウインドウのメニューはリソースで定義する事が多いのですが、フォトレタッチではメニューを動的に作成・変更する事もあるでしょうからコードで生成する事にします。メニューは、トップレベルに「ファイル」と「変換」を、ファイル内のポップアップに「開く」「保存」「終了」、変換内のポップアップに「白黒化」メニューを入れます。これは、単にCreateMenu()してからAppendMenu()していけば良いですね。
// メニュー作成 hMenu=CreateMenu(); // トップレベルメニュー hMenuFile=CreateMenu(); // 「ファイル」メニュー hMenuConv=CreateMenu(); // 「変換」メニュー // ファイルメニュー項目作成 AppendMenu(hMenuFile,MF_STRING,1,"開く(&O)"); AppendMenu(hMenuFile,MF_STRING,2,"保存(&S)"); AppendMenu(hMenuFile,MF_SEPARATOR,0,NULL); AppendMenu(hMenuFile,MF_STRING,3,"終了(&X)"); // 変換メニュー項目作成 AppendMenu(hMenuConv,MF_STRING,10,"白黒化(&G)"); // トップレベルメニューに追加 AppendMenu(hMenu,MF_POPUP,(UINT)hMenuFile,"ファイル(&F)"); AppendMenu(hMenu,MF_POPUP,(UINT)hMenuConv,"変換(&C)");
こうして作成したメニューをSetMenu()でウインドウのメニューに設定します。
// ウインドウにメニューを設定 SetMenu(hwMain,hMenu);
メニューがクリックされるとWM_COMMANDメッセージがAppendMenu()で指定したパラメータとともに送られてくるので、メニューに応じた処理を行います。
case WM_COMMAND: switch (LOWORD(wParam)) { case 1: // 開くメニュー // ダイアログ設定 ofn.lpstrTitle=lpszOpen; ofn.Flags=OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; if (!GetOpenFileName(&ofn)) // ファイルを選択 return 0; cdib.LoadBMP(lpszFn); // BMP読み込み InvalidateRgn(hwnd,NULL,TRUE); UpdateWindow (hwnd); break; case 2: // 保存メニュー // ダイアログ設定 ofn.lpstrTitle=lpszSave; ofn.Flags=OFN_OVERWRITEPROMPT | OFN_HIDEREADONLY; if (!GetSaveFileName(&ofn)) // ファイルを選択 return 0; cdib.SaveBMP(lpszFn); // BMPに保存 break; case 3: // 終了メニュー DestroyWindow(hwMain); break; case 10: // 白黒化 cdib.GrayScale(); // 白黒化処理 InvalidateRgn(hwnd,NULL,FALSE); UpdateWindow (hwnd); break; } return 0;
読み込みや保存、白黒化などビットマップの処理はDIBクラスの関数を呼び出して行っています。また、ファイル選択のダイアログはWM_CREATE時に初期化して、一部の属性を調整しながら使いまわすようにしました。
メニューから、あるいはドラッグ&ドラッグでファイルを読み込んで「白黒化」「保存」などを試してみてください。
アーカイブには実行ファイルとソース・ヘッダ、VC++5のプロジェクトが収録されています。