android前后摄像头切换

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<Size> 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<Size> 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 <cameraCount; 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<Camera.Area> focusAreas = new ArrayList<Camera.Area>();

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

mCameraParam.setFocusAreas(focusAreas);

}

if(mCameraParam.getMaxNumMeteringAreas() > 0){

List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();

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布局文件:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

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">

<com.myselftest.VideoPreview

android:id="@+id/camera_preview"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:layout_centerInParent="true"/>

<Button

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" />

<Button

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" />

</RelativeLayout>

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

时间: 2024-11-16 03:04:47

android前后摄像头切换的相关文章

【Android】自定义相机的实现(支持连续拍照、前后摄像头切换、连续对焦)

~转载请注明http://blog.csdn.net/u013015161/article/details/46921257 介绍 这几天,写了一个自定义照相机的demo,支持连续拍照和摄像头切换.由于自己以前没接触过相关的编程,也算是一个学习的过程,在这里做一下记录,同时也分享出来,并附上源码和工程. 效果如图: 左上角switch切换摄像头,右边snap按钮进行拍照. 一般流程 Android进行拍照,需要调用摄像头类android.hardware.Camera.而要进行预览,则需要用an

Android 实例讲解自定义Camera拍照和预览以及前后置摄像头切换

上一篇博文讲解了怎么去调用本地图片和调用系统拍照图片(http://blog.csdn.net/a123demi/article/details/40003695)的功能. 而本博文将通过实例实现自定义Camera的功效.具体功能如下: 1.实现自定义Camera拍照: 2.实现前后置摄像头的切换: 3.实现Camera拍照后图片缩小显示以及正常预览: 4.实现Camera拍照后图片保存: 在具体实现代码之前,我们先来了解一下Android api对实现自定义Camera的介绍. 根据api的介

Android横竖屏切换及其对应布局加载问题

第一,横竖屏切换连带横竖屏布局问题: 如果要让软件在横竖屏之间切换,由于横竖屏的高宽会发生转换,有可能会要求不同的布局. 可以通过以下两种方法来切换布局: 1)在res目录下建立layout-land和layout-port目录,相应的layout文件名不变,比如:layout-land是横屏的layout,layout-port是竖屏的layout,其他的不用管,横竖屏切换时程序调用Activity的onCreate方法中的setOnContent(xxx),并自动加载相应的布局. 2)假如布

Android中Activity切换时共享视图元素的切换动画(4.x兼容方案)

同时发布在我的博客 点此进入 开始 上一篇讲了使用 Google 的 AppCompat-v7 来实现 Activity 切换时实现共享视图元素的切换动画.这一篇介绍两个可以兼容 4.x 的两个第三方方案. 上一篇:Android中Activity切换时共享视图元素的切换动画(5.0以上) 方案一:PreLollipopTransition 首先在 build.gradle 配置文件添加这个库依赖 dependencies { compile 'com.kogitune:pre-lollipop

如果写一个android桌面滑动切换屏幕的控件(二)

在viewgroup执行: public void snapToScreen(int whichScreen) { whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); boolean changingScreens = whichScreen != mCurrentScreen; mNextScreen = whichScreen; int mScrollX = this.getScrollX(); fin

如果写一个android桌面滑动切换屏幕的控件(三)

下面我们把这个控件内嵌到Layout中做一些动画和展示,效果图: 这个子控件可以上下移动,可以左右滑动,如果上下滑动距离大于左右滑动距离,则必须上下滑动 这样来写onTouch事件: @Override public boolean onTouchEvent(MotionEvent ev) { if (mVelocityTracker == null) { mVelocityTracker = VelocityTracker.obtain(); } mVelocityTracker.addMov

【Android 多语言切换简单实例分享】

一.Android多语言切换 Android应用的开发不可能只针对某一个国家或者区域使用,各国间语言文化各不相同,因此一个优秀的APP必须支持多种语言,为了实现这个特性,Android给出了一个解决方式,在res目录下通过values+语言编码来实现多国语言的支持(中间采用连字符号-连接),例如:values-es代表英文,如果你决定了你的应用要支持多国语言,那么你就必须新建多种values-XXX的多语言支持文件,下面通过一个例子来看看基本的使用方式,先看下效果图: 1.工程结构 注:主要看下

Android -- 获取摄像头帧数据解码

由于Android下摄像头预览数据只能  ImageFormat.NV21 格式的,所以解码时要经过一翻周折. Camera mCamera = Camera.open(); Camera.Parameters p = mCamera.getParameters(); p.setPreviewFormat(ImageFormat.NV21); /*这是唯一值,也可以不设置.有些同学可能设置成 PixelFormat 下面的一个值,其实是不对的,具体的可以看官方文档*/ mCamera.setPa

android基础----&gt;摄像头与相册的调用

很多应用程序都可能会使用到调用摄像头拍照和从相册选取图片的功能,今天我们开始android中摄像头与相册调用的学习. 目录导航 调用摄像头拍照 从相册中选择照片 友情链接 调用摄像头拍照 大致流程:调用相机拍照,然后剪辑,之后再在imageView中显示.项目结构如下: 一. 一些初始化的代码: public static final int TAKE_PHOTO = 1; public static final int CROP_PHOTO = 2; public static final i