热门IT资讯网

android前后摄像头切换

发表于:2024-11-30 作者:热门IT资讯网编辑
编辑最后更新 2024年11月30日,android前后摄像头切换demo,startview后的页面上有切换、拍照两个按钮,拍照后照片未保存,需要保存的请看下方注释,实现了拍照、聚焦功能,以下是CameraPreview.java源码:

android前后摄像头切换demo,startview后的页面上有切换、拍照两个按钮,拍照后照片未保存,需要保存的请看下方注释,实现了拍照、聚焦功能,以下是CameraPreview.java源码:


package com.myselftest;


import java.io.File;

import java.io.FileOutputStream;

import java.io.IOException;

import java.io.OutputStream;

import java.util.ArrayList;

import java.util.List;


import android.content.Context;

import android.hardware.Camera;

import android.hardware.Camera.Size;

import android.os.Bundle;

import android.util.Log;

import android.view.Display;

import android.view.KeyEvent;

import android.view.Surface;

import android.view.SurfaceHolder;

import android.view.View;

import android.view.Window;

import android.view.WindowManager;

import android.widget.TextView;

import android.widget.Toast;

import android.os.Handler;

import android.os.Message;

import android.widget.RelativeLayout;

import android.view.MotionEvent;

import android.app.Activity;

import android.view.View.OnClickListener;

import android.hardware.Camera.CameraInfo;

import android.os.SystemProperties;

import android.view.View.OnTouchListener;

import android.graphics.Rect;

import android.hardware.Camera.PictureCallback;


public class CameraPreview extends Activity implements OnClickListener, SurfaceHolder.Callback {


private static final String TAG = "CameraPreview";

private Camera mCamera;

private Camera.Parameters mCameraParam;

private int mPrvW = 800;

private int mPrvH = 600;


private final AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback();


private long mFocusCallbackTime;

private FocusIndicatorView mFocusIndicatorView;

private static final int WIDTH_DP = 80;

private static final int HEIGTH_DP = 80;

private boolean focusing = false;

private boolean state;

private TextView btn_position = null;

private TextView btn_capture = null;

private SurfaceHolder holder = null;

private VideoPreview mVideoPreview;

private int cameraPosition = 1; //1,camera_back 0,camera_front

private int cameraId;

private RelativeLayout mRelativeLayout;

CameraInfo ci = null;

public static int dip2px(Context context, float dpValue) {

final float scale = context.getResources().getDisplayMetrics().density;

return (int) (dpValue * scale + 0.5f);

}

@Override

protected void onCreate(Bundle savedInstanceState) {

// TODO Auto-generated method stub

super.onCreate(savedInstanceState);


setContentView(R.layout.camera_preview);


Window win = getWindow();

win.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

win.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);


btn_position = (TextView) findViewById(R.id.btn_position);

btn_capture = (TextView) findViewById(R.id.btn_capture);

mPrvW = this.getWindow().getWindowManager().getDefaultDisplay().getWidth();

mPrvH = mPrvW*4/3;

mFocusIndicatorView = new FocusIndicatorView(this);

int width_px = dip2px(this, WIDTH_DP);

int heigth_px = dip2px(this, HEIGTH_DP);

RelativeLayout.LayoutParams mLayoutParams = new RelativeLayout.LayoutParams(width_px, heigth_px);

int[] rules = mLayoutParams.getRules();

rules[RelativeLayout.CENTER_IN_PARENT] = 1;

mRelativeLayout = (RelativeLayout) findViewById(R.id.main_layout);

mRelativeLayout.addView(mFocusIndicatorView, mLayoutParams);

mRelativeLayout.setOnTouchListener(onTouchListener);

mVideoPreview = (VideoPreview) findViewById(R.id.camera_preview);

btn_position.setOnClickListener(this);

btn_capture.setOnClickListener(this);

}


@Override

public void onClick(View v){

if(v.equals(btn_position)){

camera_position();

}else if(v.equals(btn_capture)){

rawCapture();

}

}

@Override

protected void onResume() {

super.onResume();

mVideoPreview.setAspectRatio(mPrvW, mPrvH);

holder = mVideoPreview.getHolder();

holder.addCallback(this);

holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);


}


public boolean onTouchEvent(MotionEvent event) {

if(focusing == false) {

focusing = true;

mFocusIndicatorView.showStart();

mCamera.autoFocus(mAutoFocusCallback);

}

return true;

}

public class FocusIndicatorView extends View {

public FocusIndicatorView(Context context) {

super(context);

}

private void setDrawable(int resid) {

setBackgroundDrawable(getResources().getDrawable(resid));

}



public void showStart() {

setDrawable(R.drawable.ic_focus_focusing);

}



public void showSuccess() {

setDrawable(R.drawable.ic_focus_focused);

}



public void showFail() {

setDrawable(R.drawable.ic_focus_failed);

}



public void clear() {

setBackgroundDrawable(null);

}

}

public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

Log.i(TAG, "surfaceChanged width is : " + width+" height is"+height+" ci.orientation="+ci.orientation);

startPreview(ci.orientation);

}


public void surfaceCreated(SurfaceHolder holder) {

// TODO Auto-generated method stub

ci = new CameraInfo();

Camera.getCameraInfo(0, ci);

openCamera(0);

cameraId = 0;

try {

mCamera.setPreviewDisplay(holder);

} catch (IOException exception) {

closeCamera();

Log.i(TAG, "surfaceCreated closeCamera ");

}


}


private void openCamera(int cmaId) {

if (mCamera == null) {

mCamera = Camera.open(cmaId);

cameraId = cmaId;

Log.i(TAG, "Enter openCamera to init the mCamera.");

if (null == mCamera) {

Log.i(TAG, "init the mCamera is null.");

}

}

}


private void closeCamera() {

if (null != mCamera) {

mCamera.release();

mCamera = null;

}

}


public void surfaceDestroyed(SurfaceHolder holder) {

// TODO Auto-generated method stub

stopPreview();

closeCamera();

Log.i(TAG, "surfaceDestroyed closeCamera ");


}


private void stopPreview() {

if (null != mCamera) {

mCamera.stopPreview();

}

}


private Handler mHandler = new Handler() {

@Override

public void handleMessage(Message msg) {

// TODO Auto-generated method stub

super.handleMessage(msg);

if (0 == msg.what) {

mFocusIndicatorView.clear();

}

}

};

private void startPreview(int orientation) {//orientation:当前所选摄像头的偏转角度

if (null != mCamera) {

mCameraParam = mCamera.getParameters();

}else{

return;

}

Size size = mCameraParam.getPictureSize();

List sizes = mCameraParam.getSupportedPreviewSizes();

Size optimalSize = null;

if (size != null && size.height != 0) {

optimalSize = getOptimalPreviewSize(sizes, (double) mPrvH / mPrvW);

}

if (optimalSize != null) {

mCameraParam.setPreviewSize(optimalSize.width, optimalSize.height);

} else {

mCameraParam.setPreviewSize(mPrvW, mPrvH);

}

mCameraParam.set("fps-mode", 0); // Frame rate is normal

mCameraParam.set("cam-mode", 0); // Cam mode is preview

if (cameraPosition == 1) {

mCameraParam.setFocusMode(mCameraParam.FOCUS_MODE_CONTINUOUS_PICTURE);

mCameraParam.setFlashMode(Camera.Parameters.FLASH_MODE_ON);

}

mCamera.setDisplayOrientation(orientation);

mCamera.setParameters(mCameraParam);

mCamera.startPreview();

mCamera.autoFocus(mAutoFocusCallback);

}


private Size getOptimalPreviewSize(List sizes, double targetRatio) {

final double ASPECT_TOLERANCE = 0.05;

if (sizes == null) {

return null;

}


Size optimalSize = null;

double minDiff = Double.MAX_VALUE;


Display display = getWindowManager().getDefaultDisplay();

int targetHeight = Math.min(display.getHeight(), display.getWidth());


if (targetHeight <= 0) {

WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);

targetHeight = windowManager.getDefaultDisplay().getHeight();

}


Log.d(TAG, "getOptimalPreviewSize() sizes.size = " + sizes.size());

int i = 1;

for (Size size : sizes) {

double ratio = (double) size.width / size.height;

i++;

if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) {

continue;

}

if (Math.abs(size.height - targetHeight) < minDiff) {

optimalSize = size;

minDiff = Math.abs(size.height - targetHeight);

}

}


if (optimalSize == null) {

Log.d(TAG, "No preview size match the aspect ratio");

minDiff = Double.MAX_VALUE;

for (Size size : sizes) {

if (Math.abs(size.height - targetHeight) < minDiff) {

optimalSize = size;

minDiff = Math.abs(size.height - targetHeight);

}

}

} else {

Log.d(TAG, String.format("Optimal preview size is %sx%s", optimalSize.width, optimalSize.height));

}

return optimalSize;

}


@Override

public boolean onKeyDown(int keyCode, KeyEvent event) {

switch (keyCode) {

case KeyEvent.KEYCODE_DPAD_CENTER:

return true;

case KeyEvent.KEYCODE_SEARCH:

return true;

case KeyEvent.KEYCODE_FOCUS:

return true;

case KeyEvent.KEYCODE_BACK:

break;

}

return super.onKeyDown(keyCode, event);

}

private void camera_position(){

CameraInfo cameraInfo = new CameraInfo();

int cameraCount = Camera.getNumberOfCameras();

for(int i = 0; i

Camera.getCameraInfo(i, cameraInfo);

Log.d(TAG, "cameraOrientation-"+i+":"+cameraInfo.orientation);

if(cameraPosition == 0){

if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK){

stopPreview();

closeCamera();

openCamera(i);

cameraPosition = 1;

if (null != mCamera) {

try {

mCamera.setPreviewDisplay(holder);

} catch (IOException ex) {

closeCamera();

Log.i(TAG, "camera_position closeCamera "+i);

ex.printStackTrace();

}

startPreview(cameraInfo.orientation);

}

break;

}

}else{

if(cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){

stopPreview();

closeCamera();

openCamera(i);

cameraPosition = 0;

if (null != mCamera) {

try {

mCamera.setPreviewDisplay(holder);

} catch (IOException ex) {

closeCamera();

Log.i(TAG, "camera_position closeCamera "+i);

ex.printStackTrace();

}

startPreview(90);

}

break;

}

}

}

}


private void rawCapture() {

if(mCamera != null){

try {

mCamera.startPreview();

mCamera.autoFocus(mAutoFocusCallback);

mCamera.takePicture(null, null, new JpegPictureCallback());

Toast.makeText(this, getString(R.string.cma_capture_success), Toast.LENGTH_LONG).show();

mCamera.stopPreview();

mCamera.setPreviewDisplay(holder);

mCamera.startPreview();

}catch(Exception ex){

closeCamera();

ex.printStackTrace();

}

Log.i(TAG, "rawCapture function end");

}

}


private final class AutoFocusCallback implements android.hardware.Camera.AutoFocusCallback {

public void onAutoFocus(boolean focused, android.hardware.Camera camera) {

mFocusCallbackTime = System.currentTimeMillis();

Log.i(TAG, "mFocusCallbackTime is " + mFocusCallbackTime);

if(focused && !state) {

mFocusIndicatorView.showSuccess();

mHandler.sendEmptyMessageDelayed(0, 1500);

} else if(!focused){

mHandler.removeMessages(0);

mFocusIndicatorView.showFail();

}

focusing = false;

state = focused;

}

}


private final class JpegPictureCallback implements PictureCallback {

public void onPictureTaken(byte[] jpegData, android.hardware.Camera camera) {

Log.d(TAG, "mJpegPictureCallbackTime = " + System.currentTimeMillis());

if (jpegData != null) {

storeImage(jpegData);

}

}

}

private void storeImage(byte[] jpegData) {//本例未保存所拍照片,如需要保存,请取消下方的注释

String name = "factorymode_test.jpg";


// File fHandle = new File(name);

// try {

// OutputStream bos = new FileOutputStream(fHandle);

// bos.write(jpegData);

// bos.close();

// long storeImageTime = System.currentTimeMillis();

// Log.d(TAG, "storeImageTime = " + storeImageTime);

// } catch (Exception ex) {

// fHandle.delete();

// }

}

OnTouchListener onTouchListener = new OnTouchListener(){

@Override

public boolean onTouch(View v, MotionEvent event){

mFocusIndicatorView.setX(event.getX());

mFocusIndicatorView.setY(event.getY());

if(event.getAction() == MotionEvent.ACTION_DOWN){

mFocusIndicatorView.showSuccess();

}else if(event.getAction() == MotionEvent.ACTION_UP){

mFocusIndicatorView.showFail();

if(cameraPosition == 1){

focusOnTouch(event);

}

}

return true;

}

};

private void focusOnTouch(MotionEvent event){

int [] location = new int[2];

mRelativeLayout.getLocationOnScreen(location);

Rect focusRect = calculateTapArea(mVideoPreview.getWidth(), mVideoPreview.getHeight(), 1f, event.getRawX(),

event.getRawY(), location[0], location[0] + mRelativeLayout.getWidth(), location[1], location[1] + mRelativeLayout.getHeight());

Rect meteringRect = calculateTapArea(mVideoPreview.getWidth(), mVideoPreview.getHeight(), 1.5f, event.getRawX(),

event.getRawY(), location[0], location[0] + mRelativeLayout.getWidth(), location[1], location[1] + mRelativeLayout.getHeight());

mCameraParam.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);

if(mCameraParam.getMaxNumFocusAreas() > 0){

List focusAreas = new ArrayList();

focusAreas.add(new Camera.Area(focusRect, 1000));

mCameraParam.setFocusAreas(focusAreas);

}

if(mCameraParam.getMaxNumMeteringAreas() > 0){

List meteringAreas = new ArrayList();

meteringAreas.add(new Camera.Area(meteringRect, 1000));

mCameraParam.setMeteringAreas(meteringAreas);

}

if(mCamera != null){

mCamera.setParameters(mCameraParam);

}

mCamera.autoFocus(mAutoFocusCallback);

}

private Rect calculateTapArea(int focusWidth, int focusHeight, float areaMultiple, float x, float y, int previewLeft, int previewRight, int preViewTop, int preViewBottom){

int areaWidth = (int)(focusWidth * areaMultiple);

int areaHeight = (int)(focusHeight * areaMultiple);

int centerX = (previewLeft + previewRight) / 2;

int centerY = (preViewTop + preViewBottom) / 2;

double unitx = (((double)previewRight - (double)previewLeft)) /2000;

double unity = (((double)preViewBottom - (double)preViewTop)) /2000;

int left = clamp((int)(((x - areaWidth / 2) - centerX) / unitx), -1000, 1000);

int top = clamp((int)(((y - areaHeight / 2) - centerY) / unity), -1000, 1000);

int right = clamp((int)(left + areaWidth / unitx), -1000, 1000);

int bottom = clamp((int)(top + areaHeight / unity), -1000, 1000);

return new Rect(left, top, right, bottom);

}

private int clamp(int x, int min, int max){

if(x > max){

return max;

}

if(x < min){

return min;

}

return x;

}

}


camera_preview.xml布局文件:


xmlns:android="http://schemas.android.com/apk/res/android"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:id="@+id/main_layout"

android:orientation="vertical">

android:id="@+id/camera_preview"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_centerInParent="true"/>

android:id="@+id/btn_capture"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:layout_alignParentRight="true"

android:layout_marginRight="33dp"

android:gravity="center"

android:text="@string/cma_capture" />


android:id="@+id/btn_position"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_alignParentBottom="true"

android:layout_alignParentLeft="true"

android:layout_marginLeft="48dp"

android:gravity="center"

android:text="@string/cma_position" />


以上代码在android6.0上测试通过。

0