LoginSignup
16
15

More than 5 years have passed since last update.

今更カメラ制御の基礎(STEP2:オートフォーカスして写真撮る手前まで)

Last updated at Posted at 2014-10-18

はじめに

このサンプルを実行すると、Preview画面が90度ずれたりします。が、それらへの対応処理を入れると可読性が落ちるのでとりあえず無視。

他のステップはこちら

STEP1:基礎
STEP2:オートフォーカスとか
STEP3:保存
STEP4:アスペクト比調整

やりたいこと

・画面をクリック(タッチ)したら、オートフォーカスし、写真を撮る(手前の処理まで)。
・とりあえず、「フォーカスが合いました」的なToastを出しておく。
・実際の撮影・保存はSTEP3で。

STEP1からの追加

・画面のクリックを拾うためにSurfaceViewにリスナを追加(onSurfaceClickListener)。
・クリックされたらAutoFocusを実行し、autoFocusCallbackを呼び出す。
・autoFocusCallback内で写真を撮影しても良いが、ここではさらに、setOneShotPreviewCallbackを呼び出している。理由はプレビュー画像をbyte[]として取得し、画像処理やバーコード認証に利用したいから。
・setOneShotPreviewCallback内で、いろいろ処理を行う。ここではとりあえずToast表示。

ソース

MyActivity.java
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Toast;


public class MyActivity extends Activity {

    private SurfaceView mySurfaceView;
    private Camera myCamera; //hardware


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_my);

        //SurfaceView
        mySurfaceView = (SurfaceView)findViewById(R.id.mySurfaceVIew);
        //リスナ追加 //STEP2で追加
        mySurfaceView.setOnClickListener(onSurfaceClickListener);

        //SurfaceHolder(SVの制御に使うInterface)
        SurfaceHolder holder = mySurfaceView.getHolder();
        //コールバックを設定
        holder.addCallback(callback);

    }

    //コールバック
    private SurfaceHolder.Callback callback = new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {

            //CameraOpen
            myCamera = Camera.open();

            //出力をSurfaceViewに設定
            try{
                myCamera.setPreviewDisplay(surfaceHolder);
            }catch(Exception e){
                e.printStackTrace();
            }

        }

        @Override
        public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i2, int i3) {

            //プレビュースタート(Changedは最初にも1度は呼ばれる)
            myCamera.startPreview();

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

            //片付け
            myCamera.release();
            myCamera = null;
        }
    };

    //以下、STEP2で追加

    //Surfaceをクリックした時
    private View.OnClickListener onSurfaceClickListener = new View.OnClickListener(){
        @Override
        public void onClick(View view){
            if(myCamera != null){
                //AutoFocusを実行
                myCamera.autoFocus(autoFocusCallback);
            }
        }

    };

    //AutoFocusした時
    private Camera.AutoFocusCallback autoFocusCallback = new Camera.AutoFocusCallback(){
        @Override
        public void onAutoFocus(boolean b, Camera camera) {

            //ただ写真を撮るだけならここにtakePicture()を入れても良い
            //しかし、Pixelを弄りたいのでもうワンクッション(画像処理やバーコード処理をしたいので)
            //Previewを1枚切り取る(そしてイベント発生)
            camera.setOneShotPreviewCallback(previewCallback);
        }
    };

    //切り取った時(ここで撮影、各種画像処理を行う)
    private Camera.PreviewCallback previewCallback = new Camera.PreviewCallback(){

        //OnShotPreview時のbyte[]が渡ってくる
        @Override
        public void onPreviewFrame(byte[] bytes, Camera camera) {

            Toast.makeText(getApplicationContext(),"フォーカスが合い画像を切り取りました。",Toast.LENGTH_SHORT).show();

        }
    };
}
16
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
15