首先Focus思維是當照片擷取完後恢復到預覽畫面還在對焦時透過onAutoFocus的參數success成立時再度呼叫takePicture
而另一種則是透過takePicture進行第一次拍照,完成後且開啟預覽畫面時再度呼叫takePicture本身
兩者直到temp_count條件成立才不持續拍攝,但是用Focus對焦本身比較容易失敗啊!!!
另外並不是每隻手機都支援對焦功能,所以開發者也要去確認手機是否支援對焦功能
可能是小弟我手機爛到不行,有沒有好心人要贊助啊XD
Manifest:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.cyfang.test" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="15" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:largeHeap="true" android:theme="@style/AppTheme" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
透過Foucs:
package com.cyfang.test; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import java.util.List; import android.app.Activity; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.hardware.Camera; import android.hardware.Camera.AutoFocusCallback; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.Size; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.Toast; public class MainActivity extends Activity implements SurfaceHolder.Callback, PictureCallback { /** SurfaceView */ private SurfaceView surfaceView; /** Holder */ private SurfaceHolder holder; /** 相機 */ private Camera camera; /** 拍照按鈕 */ private Button buttonTake; /** 照片寬度 */ private int picWidth; /** 照片寬度 */ private int picHeight; /** 預覽寬度 */ private int pvWidth; /** 預覽高度 */ private int pvHeight; /** 連拍次數 */ private int take_count = 3; /** 連拍次數 */ private int temp_count = take_count; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonTake = (Button) findViewById(R.id.button1); // 按鈕點擊事件 buttonTake.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { camera.takePicture(null, null, MainActivity.this); } }); surfaceView = (SurfaceView) findViewById(R.id.surfaceView); surfaceView.setZOrderOnTop(false); holder = surfaceView.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override protected void onStop() { if (camera != null) { camera.stopPreview(); camera.release(); camera = null; } super.onStop(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { try { if (camera == null) { camera = Camera.open(CameraInfo.CAMERA_FACING_BACK); // 取得相機參數 Parameters parameters = camera.getParameters(); // 判斷能不能對焦 if (parameters.getSupportedFocusModes().contains(Parameters.FOCUS_MODE_AUTO)) { parameters.setFocusMode(Parameters.FOCUS_MODE_AUTO); if (parameters.getSupportedFocusModes().contains(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE)) parameters.setFocusMode(Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); else Toast.makeText(MainActivity.this, "抱歉您的手機不支援對焦連拍", 1).show(); } // 關閉閃光燈 parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); // 預覽尺寸清單 List<Size> previewList = parameters.getSupportedPreviewSizes(); // 照片尺寸清單 List<Size> pictureList = parameters.getSupportedPictureSizes(); picWidth = pictureList.get(0).width; picHeight = pictureList.get(0).height; // 設定最佳照片尺寸 parameters.setPictureSize(picWidth, picHeight); pvWidth = previewList.get(0).width; pvHeight = previewList.get(0).height; // 設定最佳預覽尺寸 parameters.setPreviewSize(pvWidth, pvHeight); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { camera.setDisplayOrientation(90); parameters.setRotation(90); } // 設定相機參數 camera.setParameters(parameters); // 設定顯示的Holder camera.setPreviewDisplay(holder); // 開始顯示 camera.startPreview(); } } catch (IOException e) { } catch (RuntimeException e) { } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } @Override public void onPictureTaken(byte[] data, Camera camera) { try { Log.i("Count", temp_count + ""); ByteArrayInputStream stream = new ByteArrayInputStream(data); Bitmap bitmap = BitmapFactory.decodeStream(stream); stream.close(); stream = null; FileOutputStream fileOutputStream = new FileOutputStream( new File("/sdcard/" + new Date().getTime() + ".jpg")); bitmap.compress(CompressFormat.JPEG, 90, fileOutputStream); bitmap = null; // 寫入檔案 fileOutputStream.flush(); fileOutputStream.close(); fileOutputStream = null; camera.startPreview(); if (temp_count-- != 1) { camera.cancelAutoFocus(); camera.autoFocus(autoFocusCallback); } else { camera.cancelAutoFocus(); temp_count = take_count; } } catch (IOException e) { Log.i("Tack_IOException", e.getMessage()); } } private final AutoFocusCallback autoFocusCallback = new AutoFocusCallback() { @Override public void onAutoFocus(boolean success, Camera camera) { if (success) camera.takePicture(null, null, MainActivity.this); } }; }
不透過Focus:
package com.cyfang.test; import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.util.Date; import java.util.List; import android.app.Activity; import android.content.res.Configuration; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.BitmapFactory; import android.hardware.Camera; import android.hardware.Camera.CameraInfo; import android.hardware.Camera.Parameters; import android.hardware.Camera.PictureCallback; import android.hardware.Camera.Size; import android.os.Bundle; import android.util.Log; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class MainActivity extends Activity implements SurfaceHolder.Callback, PictureCallback { /** SurfaceView */ private SurfaceView surfaceView; /** Holder */ private SurfaceHolder holder; /** 相機 */ private Camera camera; /** 拍照按鈕 */ private Button buttonTake; /** 照片寬度 */ private int picWidth; /** 照片寬度 */ private int picHeight; /** 預覽寬度 */ private int pvWidth; /** 預覽高度 */ private int pvHeight; /** 連拍次數 */ private int take_count = 3; /** 連拍次數 */ private int temp_count = take_count; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); buttonTake = (Button) findViewById(R.id.button1); // 按鈕點擊事件 buttonTake.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { camera.takePicture(null, null, MainActivity.this); } }); surfaceView = (SurfaceView) findViewById(R.id.surfaceView); surfaceView.setZOrderOnTop(false); holder = surfaceView.getHolder(); holder.addCallback(this); holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } @Override protected void onStop() { if (camera != null) { camera.stopPreview(); camera.release(); camera = null; } super.onStop(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { // TODO Auto-generated method stub } @Override public void surfaceCreated(SurfaceHolder holder) { try { if (camera == null) { camera = Camera.open(CameraInfo.CAMERA_FACING_BACK); // 取得相機參數 Parameters parameters = camera.getParameters(); // 關閉閃光燈 parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF); // 預覽尺寸清單 List<size> previewList = parameters.getSupportedPreviewSizes(); // 照片尺寸清單 List<size> pictureList = parameters.getSupportedPictureSizes(); picWidth = pictureList.get(0).width; picHeight = pictureList.get(0).height; // 設定最佳照片尺寸 parameters.setPictureSize(picWidth, picHeight); pvWidth = previewList.get(0).width; pvHeight = previewList.get(0).height; // 設定最佳預覽尺寸 parameters.setPreviewSize(pvWidth, pvHeight); if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { camera.setDisplayOrientation(90); parameters.setRotation(90); } // 設定相機參數 camera.setParameters(parameters); // 設定顯示的Holder camera.setPreviewDisplay(holder); // 開始顯示 camera.startPreview(); } } catch (IOException e) { } catch (RuntimeException e) { } } @Override public void surfaceDestroyed(SurfaceHolder holder) { // TODO Auto-generated method stub } @Override public void onPictureTaken(byte[] data, Camera camera) { try { Log.i("Count", temp_count + ""); ByteArrayInputStream stream = new ByteArrayInputStream(data); Bitmap bitmap = BitmapFactory.decodeStream(stream); stream.close(); stream = null; FileOutputStream fileOutputStream = new FileOutputStream( new File("/sdcard/" + new Date().getTime() + ".jpg")); bitmap.compress(CompressFormat.JPEG, 90, fileOutputStream); bitmap = null; // 寫入檔案 fileOutputStream.flush(); fileOutputStream.close(); fileOutputStream = null; camera.startPreview(); if (temp_count-- != 1) camera.takePicture(null, null, this); else temp_count = take_count; } catch (IOException e) { Log.i("Tack_IOException", e.getMessage()); } } }
執行結果: