一.主要使用的方法
Camera
1.Camera.open(int cameraId)
创建新的摄影机对象,使用完需要释放release(),否则其它应用无法使用。
2.setPreviewFormat(int pixel_format)
设置onPreviewFrame方法中数据回调的类型( nv21,YV12)
Camera.getParameters().
3.setPreviewCallbackWithBuffer
与addCallbackBuffer(byte[] callbackBuffer) 搭配使用实现内存复用
1.startPreview()
开始预览
SurfaceView
1.surfaceCreated:SurfaceView创建完成回调
2.onPreviewFrame(byte[] data, Camera camera)
data:摄像头数据回调
3.surfaceDestroyed:SurfaceView销毁回调
TextureView
setPreviewCallback(PreviewCallback cb)
设置预览回调
setPreviewTexture(SurfaceTexture surfaceTexture)
预览图像设置到surfaceTexture纹理
在startPreview之前调用
开始预览
二.实现过程
1.申请相机权限
2.SurfaceView实现
1)继承SurfaceView,实现surfaceCreated,surfaceDestroyed,onPreviewFrame等方法
public class RYSurfaceView extends SurfaceView implements SurfaceHolder.Callback, Camera.PreviewCallback{
private String TAG="RYSurfaceView";
private Camera.Size size;
private Camera mCamera;
byte[] buffer;
public RYSurfaceView(Context context, AttributeSet attrs) {
super(context, attrs);
getHolder().addCallback(this);
}
@Override
public void surfaceCreated(@NonNull SurfaceHolder holder) {
startPreview();
}
private void startPreview() {
mCamera=Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
Camera.Parameters parameters = mCamera.getParameters();
size=parameters.getPreviewSize();
try {
mCamera.setPreviewDisplay(getHolder());
mCamera.setDisplayOrientation(90);
//设置回调格式为nv21
parameters.setPreviewFormat(ImageFormat.NV21);
mCamera.setParameters(parameters);
buffer=new byte[size.width*size.height*3/2];
mCamera.addCallbackBuffer(buffer);
mCamera.setPreviewCallbackWithBuffer(this);
mCamera.startPreview();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
if(mCamera != null){
mCamera.stopPreview();
mCamera.release();
mCamera= null;
}
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
if(mCamera!=null)
mCamera.addCallbackBuffer(data);//复用内存提供效率
//注意,先addCallbackBuffer,然后再处理帧数据,否则会降低帧率。
// parameters.setPreviewFormat(ImageFormat.NV21);设置后 data为nv21
Log.i(TAG,data.toString());
}
}
2)在布局文件中使用自定义SurfaceView
<com.ry.question3.RYSurfaceView
android:id="@+id/ryview"
android:layout_width="match_parent"
android:layout_height="500dp" />
2.TextureView实现
1)代码实现
public class TextureViewActivity extends AppCompatActivity implements TextureView.SurfaceTextureListener, Camera.PreviewCallback {
TextureView textureView;
Camera mCamera;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_texture_view);
TextureView textureView= findViewById(R.id.textureView);
textureView.setSurfaceTextureListener(this);
// 打开摄像头
mCamera = Camera.open();
mCamera.setDisplayOrientation(90);
Camera.Parameters parameters = mCamera.getParameters();
//设置回调格式为nv21
parameters.setPreviewFormat(ImageFormat.NV21);
mCamera.setParameters(parameters);
mCamera.setPreviewCallback(this);
}
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
try {
mCamera.setPreviewTexture(surface);
mCamera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) { }
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
mCamera.release();
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
//数据回调
}
}
2)布局文件
<TextureView
android:id="@+id/textureView"
android:layout_width="match_parent"
android:layout_height="500dp"/>
三.结果