BREW でカメラ (後編) - 2 / 3 -
追加するマクロと変数
カメラの状態を表すマクロ定数を定義します。スナップショットは 2 つのマクロ定数を定義しています。カメラが停止したときと、スナップショット モードでの撮影が完了したときを区別するのに必要となるからです。
// ICAMERA インターフェース未初期化 #define CAMERA_STATUS_NULL 0 // ICAMERA インターフェース取得済み #define CAMERA_STATUS_READY 1 // プレビュー モード #define CAMERA_STATUS_PREVIEW 2 // スナップショット モードへ移行開始 #define CAMERA_STATUS_BEGIN_SNAPSHOT 3 // スナップショット モード (完了) #define CAMERA_STATUS_SNAPSHOT 4 // カメラ終了処理開始 #define CAMERA_STATUS_BEGIN_STOP 5 // カメラ解放開始 #define CAMERA_STATUS_BEGIN_FREE 6
マクロ定数とメディア データを格納する変数をアプレット構造体に追加します。
typedef struc _camera_app {
...
// add your own variables here...
...
int _cameraStatus; // カメラの状態
AEEMediaData _mediaData; // メディア データ
} camera_app;
カメラの状態は、アプリ起動時に実行される camera_app_InitAppData 関数で初期化します。
boolean camera_app_InitAppData(camera_app* pMe)
{
...
// Insert your code here
for initializing or allocating resources...
// カメラ関係の変数の初期化
pMe->_camera = NULL;
pMe->_cameraStatus = CAMERA_STATUS_NULL;
...
}
カメラ インターフェースの初期化
カメラ インターフェースの初期化関数 camera_app_InitializeCamera 関数で、メディア データ、画像サイズ、遅延エンコードモードを設定します。
int camera_app_InitializeCamera(camera_app *pMe)
{
...
if (result == SUCCESS) {
...
ICAMERA_SetDisplaySize(pMe->_camera, &size);
// ここから追加
// メディア データの設定
// スナップショット モードを利用する前には
// ファイルに保存しない場合でも必ず設定しなければならない
// 今回は使用しないので、適当な値を設定
pMe->_mediaData.clsData = MMD_FILE_NAME;
pMe->_mediaData.pData = "dummy.jpg";
ICAMERA_SetMediaData(pMe->_camera,
&(pMe->_mediaData), "image/jpeg");
// 画像サイズの設定 (必須)
// 今回は QVGA にする
size.cx = 240;
size.cy = 320;
ICAMERA_SetSize(pMe->_camera, &size);
// 遅延エンコードを使用するためには必須
ICAMERA_DeferEncode(pMe->_camera, TRUE);
}
else {
pMe->_camera = NULL;
// 次を追加
pMe->_cameraStatus = CAMERA_STATUS_NULL;
}
return result;
}
カメラの停止
カメラの停止を行う camera_app_StopCamera 関数です。
// カメラを停止する
int camera_app_StopCamera(camera_app *pMe)
{
// 次を追加
pMe->_cameraStatus = CAMERA_STATUS_BEGIN_STOP;
return ICAMERA_Stop(pMe->_camera);
}
_cameraStatus 変数に CAMERA_STATUS_BEGIN_STOP を代入することで、コールバック関数内で camera_app_StopCamera 関数によってカメラの停止が判断できます。
インターフェースの解放
カメラ インターフェースを解放を行う camera_app_FreeCamera 関数を定義します。カメラが動作にかかわらずに camera_app_FreeCamera 関数を呼び出せようにします。
void camera_app_FreeCamera(camera_app *pMe)
{
if (!pMe->_camera) {
// 解放済み
return;
}
if (pMe->_cameraStatus == CAMERA_STATUS_BEGIN_FREE) {
// 現在解放処理に移行中なら何もしない
return;
}
if (pMe->_cameraStatus == CAMERA_STATUS_READY) {
// カメラが待機状態なので、そのまま解放できる
ICAMERA_Release(pMe->_camera);
pMe->_camera = NULL;
pMe->_cameraStatus = CAMERA_STATUS_NULL;
}
else {
// カメラが動作中なので、一旦終了させる必要がある
if (pMe->_cameraStatus == CAMERA_STATUS_BEGIN_STOP) {
// 二重に ICAMERA_Stop() を呼ぶのを防ぐ
pMe->_cameraStatus = CAMERA_STATUS_BEGIN_FREE;
}
else {
pMe->_cameraStatus = CAMERA_STATUS_BEGIN_FREE;
ICAMERA_Stop(pMe->_camera);
}
}
}
camera_app_FreeAppData() 中の
camera_app_StopCamera(pMe);
を
camera_app_FreeCamera(pMe);
に変更します。
プレビューの開始
プレビューを開始する camera_app_PreviewCamera 関数です。
int camera_app_PreviewCamera(camera_app *pMe)
{
int result = SUCCESS;
if (pMe->_cameraStatus == CAMERA_STATUS_PREVIEW) {
// 現在プレビュー中なら何もしない
return result;
}
if (pMe->_cameraStatus == CAMERA_STATUS_READY) {
// カメラが待機状態なので、そのままプレビュー モードに移行できる
pMe->_cameraStatus = CAMERA_STATUS_PREVIEW;
result = ICAMERA_Preview(pMe->_camera);
}
else {
// カメラが動作中なので、一旦終了させる必要がある
pMe->_cameraStatus = CAMERA_STATUS_PREVIEW;
result = ICAMERA_Stop(pMe->_camera);
}
return result;
}
カメラの状態を保持する変数が増えたので、カメラが起動・停止に関係なく問題は起きません。
スナップショットの撮影
スナップショット モードに移行するための関数 camera_app_SnapshotCamera 関数を定義します。
int camera_app_SnapshotCamera(camera_app *pMe)
{
int result = SUCCESS;
if (pMe->_cameraStatus == CAMERA_STATUS_BEGIN_SNAPSHOT) {
// 現在スナップショット モードに移行中なら何もしない
return result;
}
if (pMe->_cameraStatus == CAMERA_STATUS_READY) {
// カメラが待機状態なので、そのままスナップショット モードに移行できる
pMe->_cameraStatus = CAMERA_STATUS_SNAPSHOT;
result = ICAMERA_RecordSnapshot(pMe->_camera);
}
else {
// カメラが動作中なので、一旦終了させる必要がある
pMe->_cameraStatus = CAMERA_STATUS_BEGIN_SNAPSHOT;
result = ICAMERA_Stop(pMe->_camera);
}
return result;
}
スナップショット モードに移行するときには、カメラを停止しておくことがポイントです。
camera_app_OnSnapshot 関数には、スナップショット撮影が完了したときの全ての処理を記述します。それから、スナップショット モードで撮影した画像を画面に表示します。
void camera_app_OnSnapshot(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);
}
処理内容は camera_app_OnPreview 関数と同じです。
camera_app_OnSnapshot 関数の呼び出しは、コールバック関数 camera_app_OnCamera 関数で行います。
void camera_app_OnCamera(void *pUser, AEECameraNotify *pNotify)
{
camera_app *pMe = (camera_app *)pUser;
switch (pNotify->nStatus) {
case CAM_STATUS_FRAME: // 新たなフレームを取得した
if (pMe->_cameraStatus == CAMERA_STATUS_PREVIEW) {
// プレビュー用画像が取得できた
camera_app_OnPreview(pMe);
}
break;
case CAM_STATUS_DONE: // 何らかの処理が完了した
switch (pMe->_cameraStatus) {
case CAMERA_STATUS_PREVIEW:
pMe->_cameraStatus = CAMERA_STATUS_READY;
// プレビュー モードへの移行途中である
// もう一度 camera_app_PreviewCamera() を呼ばなければならない
camera_app_PreviewCamera(pMe);
break;
case CAMERA_STATUS_BEGIN_SNAPSHOT:
pMe->_cameraStatus = CAMERA_STATUS_READY;
// スナップショット モードへの移行途中である
// もう一度 camera_app_SnapshotCamera() を呼ばなければならない
camera_app_SnapshotCamera(pMe);
break;
case CAMERA_STATUS_SNAPSHOT:
pMe->_cameraStatus = CAMERA_STATUS_READY;
// スナップショット モードでの撮影が完了した
camera_app_OnSnapshot(pMe);
break;
case CAMERA_STATUS_BEGIN_STOP:
// カメラの終了処理が完了した
pMe->_cameraStatus = CAMERA_STATUS_READY;
break;
case CAMERA_STATUS_BEGIN_FREE:
pMe->_cameraStatus = CAMERA_STATUS_READY;
// ICamera インターフェースの解放作業の途中である
// もう一度 camera_app_FreeCamera() を呼ばなければならない
camera_app_FreeCamera(pMe);
break;
}
break;
}
}
サスペンドとレジュームへの対応
サスペンドとレジュームに対応させます。
camera_app_HandleEvent 関数を次のようにします。
static boolean camera_app_HandleEvent(camera_app* pMe, AEEEvent eCode,
uint16 wParam, uint32 dwParam)
{
switch (eCode)
{
...
// App is being suspended
case EVT_APP_SUSPEND:
// Add your code here...
// サスペンドへ移行するときは、
// ICamera インターフェースを解放する必要がある
camera_app_FreeCamera(pMe);
return(TRUE);
// App is being resumed
case EVT_APP_RESUME:
// Add your code here...
camera_app_InitializeCamera(pMe);
return(TRUE);
...
}
return FALSE;
}
セレクト キーを押すことでプレビュー モードとスナップショット モードとでモード切替できるようにすれば完成です。

















