温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

android前后摄像头切换

发布时间:2020-05-21 00:15:40 来源:网络 阅读:3061 作者:qiang_guozky 栏目:移动开发

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上测试通过。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI