做了Android摄像头编程的测试,自己总结一下代码和其中的注意事项。
CameraTestActivity.java:
1 package test.cameratest; 2 3 import java.io.IOException; 4 import java.util.Iterator; 5 import java.util.List; 6 7 import android.hardware.Camera; 8 import android.hardware.Camera.Size; 9 import android.os.Bundle; 10 import android.app.Activity; 11 import android.content.Context; 12 import android.content.res.Configuration; 13 import android.util.Log; 14 import android.view.Display; 15 import android.view.SurfaceHolder; 16 import android.view.SurfaceView; 17 import android.view.Window; 18 import android.view.WindowManager; 19 import android.widget.LinearLayout; 20 21 public class MainActivity extends Activity implements SurfaceHolder.Callback { 22 23 private String Tag = "CameraTest"; 24 private SurfaceView mSurfaceView; 25 private SurfaceHolder mSurfaceHolder; 26 private Camera mCamera; 27 private Size previewSize; 28 private int screenWidth; 29 private int screenHeight; 30 31 @Override 32 protected void onCreate(Bundle savedInstanceState) { 33 super.onCreate(savedInstanceState); 34 //全屏 35 requestWindowFeature(Window.FEATURE_NO_TITLE); 36 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 37 WindowManager.LayoutParams.FLAG_FULLSCREEN); 38 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 39 setContentView(R.layout.activity_main); 40 41 WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE); 42 Display display = wm.getDefaultDisplay(); 43 //获取屏幕的宽和高 44 screenWidth = display.getWidth(); 45 screenHeight = display.getHeight(); 46 47 mSurfaceView = (SurfaceView) findViewById(R.id.surfaceview); 48 mSurfaceHolder = mSurfaceView.getHolder(); 49 mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 50 mSurfaceHolder.addCallback(this); 51 } 52 53 @Override 54 protected void onResume() { 55 super.onResume(); 56 Log.d(Tag, "resume"); 57 } 58 59 @Override 60 protected void onPause() { 61 super.onPause(); 62 Log.d(Tag, "pause"); 63 } 64 65 @Override 66 protected void onStop() { 67 super.onStop(); 68 Log.d(Tag, "stop"); 69 } 70 71 @Override 72 protected void onDestroy() { 73 super.onDestroy(); 74 Log.d(Tag, "destroy"); 75 } 76 77 @Override 78 public void surfaceCreated(SurfaceHolder holder) { 79 Log.d(Tag, "surface created"); 80 mCamera = Camera.open(); 81 if (mCamera == null) { 82 Log.d(Tag, "camera null"); 83 } 84 try { 85 mCamera.setPreviewDisplay(holder); 86 } catch (IOException e) { 87 Log.e(Tag, "IOException caused by setPreviewDisplay"); 88 } 89 mCamera.setPreviewCallback(mPreviewCallback); 90 Camera.Parameters parameters = mCamera.getParameters(); 91 //Log.d(Tag, parameters.flatten()); 92 if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) { 93 parameters.set("orientation", "portrait"); 94 mCamera.setDisplayOrientation(90); 95 } else { 96 parameters.set("orientation", "landscape"); 97 mCamera.setDisplayOrientation(0); 98 } 99 int previewWidth = 0; 100 int previewHeight = 0; 101 List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes(); 102 Iterator<Camera.Size> iter = previewSizes.iterator(); 103 while (iter.hasNext()) { 104 Camera.Size size = iter.next(); 105 Log.d(Tag, "" + size.width + " by " + size.height); 106 if (size.width >= previewWidth && size.width <= screenHeight && 107 size.height >= previewHeight && size.height <= screenWidth) {//640 108 previewWidth = size.width; 109 previewHeight = size.height; 110 } 111 } 112 parameters.setPreviewSize(previewWidth, previewHeight); 113 Log.d(Tag, "preivewWidth: " + previewWidth + " preivewHeight: " + previewHeight); 114 List<String> focusModes = parameters.getSupportedFocusModes(); 115 if (focusModes != null && focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) { 116 parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 117 } 118 mCamera.setParameters(parameters); 119 previewSize = mCamera.getParameters().getPreviewSize(); 120 } 121 122 @Override 123 public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 124 Log.d(Tag, "surface changed"); 125 //Log.d(Tag, "surface size: " + width + " by " + height); 126 //Log.d(Tag, "preview size: " + previewSize.width + " by " + previewSize.height); 127 //使SurfaceView大小和预览大小比例相同 128 mSurfaceView.setLayoutParams(new LinearLayout.LayoutParams(width, (int)(width * previewSize.width / previewSize.height))); 129 //Log.d(Tag, "surface size2: " + width + " by " + (int)(width * previewSize.width / previewSize.height)); 130 mCamera.startPreview(); 131 mCamera.autoFocus(mAutoFocusCallback); 132 } 133 134 @Override 135 public void surfaceDestroyed(SurfaceHolder holder) { 136 Log.d(Tag, "surface destroyed"); 137 if (mCamera != null) { 138 mCamera.autoFocus(null); 139 mCamera.stopPreview(); 140 mCamera.setPreviewCallback(null); 141 mCamera.release(); 142 mCamera = null; 143 } 144 } 145 146 Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() { 147 @Override 148 public void onAutoFocus(boolean success, Camera camera) { 149 Log.d(Tag, "AutoFocus: " + success); 150 if (success) { 151 //自动对焦成功 152 // ... 153 } else { 154 //自动对焦失败,再次对焦 155 mCamera.autoFocus(mAutoFocusCallback); 156 } 157 } 158 }; 159 160 Camera.PreviewCallback mPreviewCallback = new Camera.PreviewCallback() { 161 @Override 162 public void onPreviewFrame(byte[] data, Camera camera) 163 { 164 165 } 166 }; 167 168 }
布局文件activity_camera_test.xml:
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent" 4 android:layout_height="match_parent" 5 android:orientation="vertical" 6 tools:context=".MainActivity" > 7 8 <SurfaceView 9 android:layout_width="fill_parent" 10 android:layout_height="wrap_content" 11 android:id="@+id/surfaceview"/> 12 13 </LinearLayout>
注意事项:(新发现的会再补充上)
1,在surfaceChanged函数里面,mCamera.autoFocus(mAutoFocusCallback),如果写成autoFocus(null)的话,程序安装后第一次打开时预览会很亮很模糊。