1. 程式人生 > >Android Camera原始幀格式轉換 —— 獲取Camera影象(一)

Android Camera原始幀格式轉換 —— 獲取Camera影象(一)

package com.dreamy.cameraframedemo;

import android.app.Activity;
import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.os.Bundle;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

import com.dreamy.cameraframedemo.util.ImageUtils;

import java.io.IOException; public class MainActivity extends Activity implements SurfaceHolder.Callback, Camera.PreviewCallback, View.OnClickListener { // raw frame resolution: 1280x720, image format is: YV12 // you need get all resolution that supported on your devices; // my phone is HUAWEI honor 6Plus, most devices can use 1280x720
private static final int SRC_FRAME_WIDTH = 1280; private static final int SRC_FRAME_HEIGHT = 720; private static final int IMAGE_FORMAT = ImageFormat.YV12; private Camera mCamera; private Camera.Parameters mParams; private SurfaceView mSurfaceView; private SurfaceHolder mSurfaceHolder; @Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); initView(); setListener(); } private void initView() { mSurfaceView = (SurfaceView) findViewById(R.id.sv_recording); mSurfaceHolder = mSurfaceView.getHolder(); mSurfaceHolder.setFixedSize(SRC_FRAME_WIDTH, SRC_FRAME_HEIGHT); mSurfaceHolder.addCallback(this); mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } private void setListener() { // set Listener if you want, eg: onClickListener } @Override public void onClick(View v) { } @Override public void onPreviewFrame(byte[] data, Camera camera) { ImageUtils.saveImageData(data); camera.addCallbackBuffer(data); } private void openCamera(SurfaceHolder holder) { releaseCamera(); // release Camera, if not release camera before call camera, it will be locked mCamera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); mParams = mCamera.getParameters(); setCameraDisplayOrientation(this, Camera.CameraInfo.CAMERA_FACING_BACK, mCamera); mParams.setPreviewSize(SRC_FRAME_WIDTH, SRC_FRAME_HEIGHT); mParams.setPreviewFormat(IMAGE_FORMAT); // setting preview format:YV12 mParams.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO); mCamera.setParameters(mParams); // setting camera parameters try { mCamera.setPreviewDisplay(holder); } catch (IOException ioe) { ioe.printStackTrace(); } mCamera.setPreviewCallback(this); mCamera.startPreview(); } private synchronized void releaseCamera() { if (mCamera != null) { try { mCamera.setPreviewCallback(null); } catch (Exception e) { e.printStackTrace(); } try { mCamera.stopPreview(); } catch (Exception e) { e.printStackTrace(); } try { mCamera.release(); } catch (Exception e) { e.printStackTrace(); } mCamera = null; } } /** * Android API: Display Orientation Setting * Just change screen display orientation, * the rawFrame data never be changed. */ private void setCameraDisplayOrientation(Activity activity, int cameraId, Camera camera) { Camera.CameraInfo info = new Camera.CameraInfo(); Camera.getCameraInfo(cameraId, info); int rotation = activity.getWindowManager().getDefaultDisplay() .getRotation(); int degrees = 0; switch (rotation) { case Surface.ROTATION_0: degrees = 0; break; case Surface.ROTATION_90: degrees = 90; break; case Surface.ROTATION_180: degrees = 180; break; case Surface.ROTATION_270: degrees = 270; break; } int displayDegree; if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) { displayDegree = (info.orientation + degrees) % 360; displayDegree = (360 - displayDegree) % 360; // compensate the mirror } else { displayDegree = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(displayDegree); } @Override public void surfaceCreated(SurfaceHolder holder) { openCamera(holder); // open camera } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { } }