Camera1实时预览并采集YUV图像

来源:互联网 发布:java工程师人才缺口 编辑:程序博客网 时间:2024/05/17 12:50

1.动态声明权限

<uses-feature android:name="android.hardware.camera"/><uses-permission android:name="android.permission.RECORD_AUDIO"/><uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/><uses-permission android:name="android.permission.CAMERA"/>

2.声明SurfaceView来实时显示预览



<SurfaceView    android:id="@+id/record_surface"    android:layout_width="match_parent"    android:layout_height="match_parent" />

3.初始化相机,实时预览,并通过YUVImage保存预览的图像到本地图片


package com.example.administrator.avlearning.activity;import android.annotation.TargetApi;import android.app.Activity;import android.graphics.ImageFormat;import android.graphics.Rect;import android.graphics.YuvImage;import android.hardware.Camera;import android.os.Bundle;import android.util.Log;import android.view.SurfaceHolder;import android.view.SurfaceView;import com.example.administrator.avlearning.R;import java.io.ByteArrayOutputStream;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import java.util.List;/****************************************** * 类描述:Camera采集视频数据 * 类名称:VideoRecordTest ******************************************/public class VideoRecordTest extends Activity implements SurfaceHolder.Callback, Camera.PreviewCallback {    Camera camera = null;    Camera.Parameters parameters;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.video_record_test);        initview();    }    private void initview() {        SurfaceView surfaceView = (SurfaceView) findViewById(R.id.record_surface);        SurfaceHolder surfaceHolder = surfaceView.getHolder();        surfaceHolder.addCallback(this);        surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);    }    @Override    public void surfaceCreated(SurfaceHolder holder) {        openCamera(holder); // 开启相机    }    @Override    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {    }    @Override    public void surfaceDestroyed(SurfaceHolder holder) {        releaseCamera(); // 在surfaceDestroyed的时候记得releaseCamera    }    private void openCamera(SurfaceHolder holder) {        releaseCamera();        try {            camera = getCamera(Camera.CameraInfo.CAMERA_FACING_BACK); // 根据需求选择前/后置摄像头        } catch (Exception e) {            camera = null;            e.printStackTrace();        }        if(camera != null){            try {                camera.setPreviewCallback(this);                camera.setDisplayOrientation(90); // 此方法为官方提供的旋转显示部分的方法,并不会影响onPreviewFrame方法中的原始数据;                if(parameters == null){                    parameters = camera.getParameters();                }                parameters.setPreviewFormat(ImageFormat.NV21); // 常用格式:NV21 / YV12                List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();                for (int i = 0; i < previewSizes.size(); i++) {                    Log.e("yzy","SupportedPreviewSizes : " + previewSizes.get(i).width + "x" + previewSizes.get(i).height);                }                // 还可以设置很多相机的参数,但是建议先遍历当前相机是否支持该配置,不然可能会导致出错;                parameters.setPreviewSize(1920, 1080);               // parameters.setPictureFormat(PixelFormat.JPEG); // Sets the image                // format for                // picture                // 设定相片格式为JPEG,默认为NV21                //parameters.setPreviewFormat(PixelFormat.YCbCr_420_SP); // Sets                camera.setParameters(parameters);                camera.setPreviewDisplay(holder);                camera.startPreview();            } catch (IOException e) {                e.printStackTrace();            }        }    }    @TargetApi(9)    private Camera getCamera(int cameraType) {        Camera camera = null;        try {            camera = Camera.open(cameraType);        } catch (Exception e) {            e.printStackTrace();        }        return camera; // returns null if camera is unavailable    }    private synchronized void releaseCamera() {        if (camera != null) {            try {                camera.setPreviewCallback(null);            } catch (Exception e) {                e.printStackTrace();            }            try {                camera.stopPreview();            } catch (Exception e) {                e.printStackTrace();            }            try {                camera.release();            } catch (Exception e) {                e.printStackTrace();            }            camera = null;        }    }    /* * 编码器获取数据,编码,编码后的数据的处理等大致流程如下: *//* 1.获取原始帧 */    @Override    public void onPreviewFrame(byte[] onPreviewData, Camera camera) {    /* 在此可以对onPreviewData进行Rotate或者Scale     * 也可以转换yuv的格式,例如yuv420P(YV12)或者yuv420SP(NV21/NV12)     * 相关开源类库可以使用libyuv/ffmpeg等     */    /* 取得编码后的数据便可进行相应的操作,可以保存为本地文件,也可进行推流 */    /* 然后将onPreviewData加入Camera回调*/       camera.addCallbackBuffer(onPreviewData);      //  saveImage(onPreviewData,camera);    }    private void saveImage(byte[] data, Camera arg1) {        FileOutputStream outStream = null;        try {            YuvImage yuvimage = new YuvImage(data,ImageFormat.NV21,arg1.getParameters().getPreviewSize().width,arg1.getParameters().getPreviewSize().height,null);            ByteArrayOutputStream baos = new ByteArrayOutputStream();            yuvimage.compressToJpeg(new Rect(0,0,arg1.getParameters().getPreviewSize().width,arg1.getParameters().getPreviewSize().height), 80, baos);            outStream = new FileOutputStream(String.format("/sdcard/%d.jpg", System.currentTimeMillis()));            outStream.write(baos.toByteArray());            outStream.close();        } catch (FileNotFoundException e) {            e.printStackTrace();        } catch (IOException e) {            e.printStackTrace();        } finally {        }    }}

原创粉丝点击