BREW でカメラ (前編) - 2 / 3 -
camera_app の概要
アプリを起動するとプレビュー モードになり、プレビュー画像を表示します。「0」キー、または「電源」キーを押すとアプリは終了します。
次回 " BREW でカメラ (後編) "の処理でファイルアクセスが必要なので、予め MIF エディタや Application Wizard では「ファイルを使用する」設定にします。
関連情報:" 第 11 回 TCP / IP ネットワークプログラミング − MIF ファイルの設定 − "
準備
Application Wizard には、カメラに関する設定はありません。
ICamera インターフェースを使用するためには、camera_app.c に " AEECamera.h " をインクルードして 1 行追加します。
#include <AEECamera.h>
■ アプレット構造体の宣言
アプリ全体で使用する変数として、ICamera インターフェースのインスタンス変数をアプレット構造体に追加します。
typedef struct _camera_app { ... // add your own variables here... ICamera *_camera; // ICamera インターフェースのインスタンス変数 } camera_app;
カメラの初期化
プレビュー画像のサイズは QVGA (横 240 × 縦 320) に設定します。コールバック関数にアプレット構造体へのポインタが渡されるようにします。
int camera_app_InitializeCamera(camera_app *pMe) { int result = SUCCESS; AEESize size; // インスタンスの生成を行う result = ISHELL_CreateInstance(pMe->a.m_pIShell, AEECLSID_CAMERA, (void **)&(pMe->_camera)); if (result == SUCCESS) { // カメラ イベント用コールバック関数を登録 result = ICAMERA_RegisterNotify(pMe->_camera, camera_app_OnCamera, pMe); // プレビュー 画像のサイズを設定 (必須) // 今回は QVGA にする size.cx = 240; size.cy = 320; ICAMERA_SetDisplaySize(pMe->_camera, &size); } else { pMe->_camera = NULL; } return result; }
ISHELL_CreateInstance 関数で pMe->m_pIShell を pMe->a.m_pIShell とします。こうすると、変数の初期化処理などをする関数 camera_app_InitAppData で camera_app_InitializeCamera 関数を記述しても、問題は発生しません。
camera_app_HandleEvent 関数で EVT_APP_START イベントの処理を次のようにして記述して、camera_app_InitializeCamera 関数がアプリ起動後に呼び出されるようにします。
static boolean camera_app_HandleEvent(camera_app* pMe, AEEEvent eCode, uint16 wParam, uint32 dwParam) { ... // App is told it is starting up case EVT_APP_START: // Add your code here... camera_app_InitializeCamera(pMe); return(TRUE); ... }
プレビュー
ICAMERA_Preview 関数を呼び出す camera_app_PreviewCamera という関数を定義します。
int camera_app_PreviewCamera(camera_app *pMe) { return ICAMERA_Preview(pMe->_camera); }
アプリが起動しカメラ初期化が完了すれば、プレビュー モードに移行するようにします。
static boolean camera_app_HandleEvent(camera_app* pMe, AEEEvet eCode, uint16 wParam, uint32 dwParam) { ... // App is told it is starting up case EVT_APP_START: // Add your code here... camera_app_InitializeCamera(pMe); camera_app_PreviewCamera(pMe); // 追加 return(TRUE); ... }
プレビュー処理の実装です。プレビュー処理は camera_app_OnPreview という関数の中に記述します。
void camera_app_OnPreview(camera_app *pMe) { IBitmap *bitmap; int result = SUCCESS; // 画像を取得 // この画像は自分で解放しなければならない result = ICAMERA_GetFrame(pMe->_camera, &bitmap); if (result != SUCCESS) { return; } // 画面に描画する IDISPLAY_BitBlt(pMe->pIDisplay, 0, 0, pMe->DeviceInfo.cxScreen, pMe->DeviceInfo.cyScreen, bitmap, 0, 0, AEE_RO_COPY); IDISPLAY_Update(pMe->pIDisplay); // 画像を解放する IBITMAP_Release(bitmap); }
まず、ICAMERA_GetFrame 関数を使って、プレビュー画像をビットマップとして取得します。
続いて、ビットマップを、IDISPLAY_BitBlt 関数を使って画面に転送します。このとき、IDISPLAY_Update 関数を呼び出してください。( これを忘れると、画面が更新されません )
最後に、ICAMERA_GetFrame 関数で取得したビットマップを、IBITMAP_Release 関数により解放します。
次に、camera_app_OnPreview 関数が カメラ イベント用コールバック関数から呼び出されるようにします。
プレビュー画像が取得できるようになると、AEECameraNotify 構造体の nStatus 変数に CAM_STATUS_FRAME が設定されて、コールバック関数が呼ばれます。
void camera_app_OnCamera(void *pUser, AEECameraNotify *pNotify) { camera_app *pMe = (camera_app *)pUser; switch (pNotify->nStatus) { case CAM_STATUS_FRAME: camera_app_OnPreview(pMe); break; } }
第 1 引数の pUser には、先程 ICAMERA_RegisterNotify 関数の第 3 引数に指定した、アプレット構造体へのポインタが格納されています。ただし pUser は void* 型なので、使用する前に camera_app* 型にキャストします。