2012年5月30日水曜日

カメラプレビューにちょっとした機能を追加

SurfaceViewを使ってカメラプレビューを実装する
以前にAndroidでのカメラプレビューの実装のやり方を載せましたがこれに機能を追加してみました

  • 撮影機能
  • オートフォーカス機能

内容的にはオートフォーカスは画面をタッチ、撮影はカメラボタン(カメラボタンがない機種もあるのでボリュームボタンも)、撮影時に向きの調整。
オートフォーカスはまぁわりと簡単に実装できました。
(本当はタッチフォーカス機能まで実装したかったんですが、今回は断念。。。)
// オートフォーカス処理
private AutoFocusCallback mAutoFocusListener =
    new AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera camera) { }
    };

// 画面タッチ時にオートフォーカスを実装
public boolean onTouchEvent(MotionEvent event) {
    if (event.getAction() == MotionEvent.ACTION_DOWN) {
        Camera.Parameters params = myCamera.getParameters();
        if (!params.getFocusMode().equals(Camera.Parameters.FOCUS_MODE_FIXED)) {
            myCamera.autoFocus(mAutoFocusListener);
        }
    }
    return true;
}

オートフォーカスの処理自体にはコードを書かなくても動作します。
ですので画面タッチしたときにそれを動くようにしてやるだけでOK。

次に撮影してAndroidのギャラリーに登録します。
// 写真を撮る
private PictureCallback mPictureListener = 
    new PictureCallback() {

        @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            ContentResolver resolver = getContentResolver();

            // 日時からファイル名を生成
            Date token = Calendar.getInstance().getTime();
            String name = photoName.format(token) + ".jpg";

            // データを生成する
            Bitmap tmp_bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

            // 画像データを保存する
            MediaStore.Images.Media.insertImage(resolver, tmp_bitmap, name, null);

            // カメラを再開
            myCamera.startPreview();
        }
    };

// キー操作で撮影
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_CAMERA
                    || keyCode == KeyEvent.KEYCODE_VOLUME_UP
                    || keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) {
            myCamera.takePicture(null, null, mPictureListener);
            return true;
        }

        return super.onKeyDown(keyCode, event);
    }

単純に保存するだけなら難しい処理がなくても動作すると思います。
ただこれだけを書いて実行してみるとわかると思いますが保存した画像は横向きで保存されていることがわかると思います。

いろいろ調べていて
int rotation = getWindowManager().getDefaultDisplay().getRotation();

これで回転がとれると思ったんですが端末の自動画面回転を有効にするのとアプリの画面向きがデフォルトのままでないと動作が確認できませんでした。
アプリの画面向きはともかく端末の自動画面回転を有効にしないと動かないってのはちょっと。。。
ということでセンサを使って判断しました。
なんかもっといいやり方あったら教えてください(>_<)

撮影した画像の向きを変えるのはgraphics.Matrixを使ってできます。
    // データを生成する
    Bitmap tmp_bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
    int width = tmp_bitmap.getWidth();
    int height = tmp_bitmap.getHeight();

    Matrix matrix = new Matrix();
    matrix.setRotate(90);

    // 画像データを保存する
    Bitmap bitmap = Bitmap.createBitmap(tmp_bitmap, 0, 0, width, height, matrix, true);
    MediaStore.Images.Media.insertImage(resolver, bitmap, name, null);


とりあえず作ったものをGitHubに置いています。
https://github.com/hayashida/CameraTest/



0 件のコメント:

コメントを投稿