安卓端获取摄像头原始数据

package com.example.previewcamera;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import com.example.camera.R;
import android.app.Activity;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;


@SuppressWarnings("deprecation")
public class CameraPreviewActivity extends Activity implements Camera.PreviewCallback{

    private Camera mCamera;
    private SurfaceView surface_cam;
    private SurfaceHolder mSurfaceHolder;
    private boolean is_writed;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_preview);
        is_writed = false;
        surface_cam = (SurfaceView) findViewById(R.id.surface_cam);
        initSurfaceView();
    }
    
    private Camera getCamera() {
        Camera camera = null;
        int cameraId = 0; // or 1  // findCamera(false);
        try {
            if (cameraId == 1) {
                camera = Camera.open(cameraId);
            } else if (cameraId == 0) {
                camera = Camera.open(0);
            }
        } catch (Exception e) {
            camera = null;
        }
        
        Camera.Parameters parameters = camera.getParameters();
        int width = 640; 
        int height = 480;
        parameters.setPreviewSize(width, height);   
        parameters.setPictureSize(width, height);
        // android.graphics.ImageFormat.NV21 默认格式
        // parameters.setPreviewFormat(android.graphics.ImageFormat.NV21);
        camera.setParameters(parameters);
        
        int pre_format;
        parameters = camera.getParameters();
        pre_format = parameters.getPreviewFormat();
        Log.i("Camera", "[getCamera]" + pre_format); // 17
        if(android.graphics.ImageFormat.NV21 == pre_format) {
            Log.i("Camera", "[getCamera]NV21");
        }
        Log.i("Camera", "[getCamera]NV21:" + android.graphics.ImageFormat.NV21);
        Log.i("Camera", "[getCamera]YUY2:" + android.graphics.ImageFormat.YUY2);
        Log.i("Camera", "[getCamera]NV16:" + android.graphics.ImageFormat.NV16);
        Log.i("Camera", "[getCamera]JPEG:" + android.graphics.ImageFormat.JPEG);
        return camera;
    }
    
    private void initSurfaceView() {
        mSurfaceHolder = surface_cam.getHolder();
        mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
            
            @Override
            public void surfaceCreated(SurfaceHolder arg0) {
                // TODO Auto-generated method stub
                mCamera = getCamera();
            }
            
            @Override
            public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
                // TODO Auto-generated method stub
                try {
                    // mCamera, mSurfaceHolder
                    mCamera.setPreviewDisplay(mSurfaceHolder);
                    mCamera.setPreviewCallback(CameraPreviewActivity.this);
                    mCamera.startPreview();
                } catch (IOException e) {
                    
                }
            }
            
            @Override
            public void surfaceDestroyed(SurfaceHolder arg0) {
                // TODO Auto-generated method stub
                if (mCamera != null) {
                    mCamera.setPreviewCallback(null);
                    mCamera.stopPreview();// 停掉摄像头的预览
                    mCamera.release();
                    mCamera = null;
                }
            }
        });
    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {
        // 460800 = 640x480x3/2  出来的是 nv21
        Log.v("JAVA", "yuv : " + data.length);
        if(false == is_writed) {
            is_writed = true;
            try {
                FileOutputStream out;
                out = new FileOutputStream("/storage/sdcard/java_nv21.yuv");
                out.write(data, 0, data.length);
                out.close();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

布局增加显示控件

<SurfaceView 
android:id="@+id/surface_cam"
android:layout_width="640dp"
android:layout_height="480dp"
/>

对应权限

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

 输出 YUV 格式分析

出来的摄像头数据这里保持的系统默认配置 ImageFormat.NV21.

这里保持着 2 个 Y , 1 个 U,1 个 V 的比例。

Y个数 640x480, U个数 640x480/4, V个数 640x480/4.

即 U 和 V 的个数加起来, 刚好为 Y 总数的一半.

格式如下

YYYYYYYY
YYYYYYYY
VUVUVUVU


 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐