###はじめに
このサンプルを実行すると、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();
}
};
}