Android 自定义Camera全屏拍照,支持前后摄像头

来源:互联网 发布:java导入自己的package 编辑:程序博客网 时间:2024/06/05 13:31

最近项目中一直在调用系统相机拍照,而产品总是要求拍照页面向iOS看齐,真是很头疼啊。但问题还是存在,有必要搞一个自定义的啦。在网上搜索了一段时间后,发现还真不是那么好实现的,实践之后,总结一些要点如下:

1.camera的parameters设置总是会提示出setParamters failed的异常

2.预览和图片的尺寸设置

3.预览图片变形

4.自动聚焦

5.保存的图片旋转角度

以上是我遇到的难点,并将之一一解决后的总结。


第1个问题,setPreviewFrameRate和setPreviewSize不能放在一起使用,否则set的时候必然报错,这个也是在查看了源代码后发现的。

第2个问题,每个手机都有自己支持的尺寸集合,并不是设置一个固定的宽高就可以的,所以要想设置尺寸,一定是先获取手机支持的尺寸,而且排序也不一样,有的从大到小,有的从小到大。没办法,开源嘛。

第3个问题就是surfaceview的尺寸大小,设置的不对的话,会导致预览变形,这个要和预览尺寸配合着设置

第4个问题比较容易解决一点,网上有很多种设置方式,但是最好用的就是使用重力加速度类型的传感器来实现,这个效果是最好的,在配合上触屏操作时也加上自动聚焦功能,就能保证自动聚焦这个功能完美的实现了。

第5个问题就是拍照会转动手机在各种角度拍照,那么获取的图片显示的时候有要求的需要根据角度重新生成bitmap,然后再显示啦。这个使用Matrix类就能实现,但是难点在于如何获取到正确的旋转角度。通常都会使用getWindowManager().getDefaultDisplay().getRotation();这个方法,但是当我将这个相机Activity设置成portrait时,这个方法是无效的,因此必须使用OrientationEventListener这个监听器,其实这个也是利用传感器实现的方向监听。


好了,以上总是我遇到的一些问题,以及一些总结,下面直接贴出代码,就不上传工程啦。所有的代码都写在一个activity里面了,还没有做架构抽象,感兴趣的小伙伴可以抽象一下,反馈给我,呵呵。


CameraManager.java

import android.content.Context;import android.graphics.PixelFormat;import android.graphics.Point;import android.graphics.Rect;import android.hardware.Camera;import android.media.AudioManager;import android.media.MediaPlayer;import android.net.Uri;import android.view.SurfaceHolder;import android.widget.Toast;import java.io.IOException;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.List;/** * Created by zouguibao on 2017/11/23. */public class CameraManger {    private static CameraManger instance;    private Camera camera;    private MediaPlayer mShootSound;    public static final int TYPE_PREVIEW = 0;    public static final int TYPE_PICTURE = 1;    public static final int ALLOW_PIC_LEN = 2000;       //最大允许的照片尺寸的长度   宽或者高    private int cameraPosition;    private CameraManger() {    }    public static CameraManger getInstance() {        if (instance == null) {            instance = new CameraManger();        }        return instance;    }    /**     * 打开摄像头     *     * @param holder     * @param autoFocusCallback     * @param degree     */    public void openCamera(SurfaceHolder holder, Camera.AutoFocusCallback autoFocusCallback, int degree) {        try {            //初始化摄像头            cameraPosition = Camera.CameraInfo.CAMERA_FACING_BACK;            // 打开摄像头            camera = Camera.open(cameraPosition);            // 设置用于显示拍照影像的SurfaceHolder对象            camera.setPreviewDisplay(holder);            camera.setDisplayOrientation(degree);            camera.autoFocus(autoFocusCallback);        } catch (Exception e) {//                e.printStackTrace();            camera.release();            camera = null;        }    }    /**     * 设置参数     */    public void setCameraParameters(int screenWidth, int screenHeight) {        try {            if (camera != null) {                Camera.Parameters parameters = camera.getParameters();//获取各项参数                Camera.Size previewSize = findFitPreResolution(parameters);                parameters.setPreviewSize(previewSize.width, previewSize.height);// 设置预览大小                parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);                parameters.setPictureFormat(PixelFormat.JPEG);//设置图片格式                //不能与setPreviewSize一起使用,否则setParamters会报错//                    parameters.setPreviewFrameRate(5);//设置每秒显示4帧                parameters.setJpegQuality(80);// 设置照片质量                Camera.Size pictureSize = null;                if (equalRate(screenWidth, screenHeight, 1.33f)) {                    pictureSize = findFitPicResolution(parameters, (float) 4 / 3);                } else {                    pictureSize = findFitPicResolution(parameters, (float) 16 / 9);                }                parameters.setPictureSize(pictureSize.width, pictureSize.height);// 设置保存的图片尺寸                camera.setParameters(parameters);                camera.startPreview();            }        } catch (Exception e) {            e.printStackTrace();        }    }    private boolean equalRate(int width, int height, float rate) {        float r = (float) width / (float) height;        if (Math.abs(r - rate) <= 0.2) {            return true;        } else {            return false;        }    }    /**     * 摄像头切换     *     * @param holder     * @param autoFocusCallback     * @param degree     */    public void turnCamera(SurfaceHolder holder, Camera.AutoFocusCallback autoFocusCallback, int degree, int screenWidth, int screenHeight) {        //切换前后摄像头        //现在是后置,变更为前置        if (camera != null && cameraPosition == Camera.CameraInfo.CAMERA_FACING_BACK) {            camera.stopPreview();//停掉原来摄像头的预览            camera.release();//释放资源            camera = null;//取消原来摄像头            camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT);//打开当前选中的摄像头            try {                camera.setPreviewDisplay(holder);//通过surfaceview显示取景画面                camera.setDisplayOrientation(degree);                camera.autoFocus(autoFocusCallback);                setCameraParameters(screenWidth, screenHeight);            } catch (IOException e) {                e.printStackTrace();            }            camera.startPreview();//开始预览            cameraPosition = Camera.CameraInfo.CAMERA_FACING_FRONT;            DataUtils.isBackCamera = false;        } else if (cameraPosition == Camera.CameraInfo.CAMERA_FACING_FRONT) {            //代表摄像头的方位,CAMERA_FACING_FRONT前置            // CAMERA_FACING_BACK后置            //现在是前置, 变更为后置            camera.stopPreview();//停掉原来摄像头的预览            camera.release();//释放资源            camera = null;//取消原来摄像头            camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK);//打开当前选中的摄像头            try {                camera.setPreviewDisplay(holder);//通过surfaceview显示取景画面                camera.setDisplayOrientation(degree);                camera.autoFocus(autoFocusCallback);                setCameraParameters(screenWidth, screenHeight);            } catch (IOException e) {                e.printStackTrace();            }            camera.startPreview();//开始预览            cameraPosition = Camera.CameraInfo.CAMERA_FACING_BACK;            DataUtils.isBackCamera = true;        }    }    public void setCameraZoom(int scale) {        Camera.Parameters parameters = camera.getParameters();        int zoom = parameters.getZoom() + scale;        if (zoom < 0) zoom = 0;        if (zoom > parameters.getMaxZoom())            zoom = parameters.getMaxZoom();        parameters.setZoom(zoom);        camera.setParameters(parameters);    }    public boolean setCameraFocusAreas(Point point) {        if (camera == null) {            return false;        }        Camera.Parameters parameters = null;        try {            parameters = camera.getParameters();        } catch (Exception e) {            e.printStackTrace();            return false;        }        //不支持设置自定义聚焦,则使用自动聚焦,返回        if (parameters.getMaxNumFocusAreas() <= 0) {            return false;        }        List<Camera.Area> areas = new ArrayList<Camera.Area>();        int left = point.x - 300;        int top = point.y - 300;        int right = point.x + 300;        int bottom = point.y + 300;        left = left < -1000 ? -1000 : left;        top = top < -1000 ? -1000 : top;        right = right > 1000 ? 1000 : right;        bottom = bottom > 1000 ? 1000 : bottom;        areas.add(new Camera.Area(new Rect(left, top, right, bottom), 100));        parameters.setFocusAreas(areas);        try {            //本人使用的小米手机在设置聚焦区域的时候经常会出异常,看日志发现是框架层的字符串转int的时候出错了,            //目测是小米修改了框架层代码导致,在此try掉,对实际聚焦效果没影响            camera.setParameters(parameters);        } catch (Exception e) {//            e.printStackTrace();            return false;        }        return true;    }    public void setCameraAutoFocus(Camera.AutoFocusCallback autoFocusCallback) {        try {            if (camera != null)                camera.autoFocus(autoFocusCallback);        } catch (Exception e) {            e.printStackTrace();        }    }    /**     * 拍照     *     * @param context     * @param pictureCallback     */    public void takePicture(final Context context, Camera.PictureCallback pictureCallback) {        if (camera != null) {            //拍照            try{                camera.takePicture(new Camera.ShutterCallback() {                    @Override                    public void onShutter() {                        try {                            AudioManager meng = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);                            int volume = meng.getStreamVolume(AudioManager.STREAM_NOTIFICATION);                            if (volume != 0) {                                if (mShootSound == null) {                                    mShootSound = MediaPlayer.create(context, Uri.parse("file:///system/media/audio/ui/camera_click.ogg"));                                }                                if (mShootSound != null) {                                    mShootSound.start();                                }                            }                        } catch (Exception e) {                        }                    }                }, null, pictureCallback);            }catch (Exception e){                Toast.makeText(context,"拍照出现异常,请退出重新进入拍照",Toast.LENGTH_SHORT).show();            }        }    }    public void closeShutterSound() {        if (mShootSound != null) {            mShootSound.release();        }    }    /**     * 重拍     */    public void startPreview() {        if (camera != null) {            camera.startPreview();        }    }    /**     * 停止拍摄     */    public void stopPreview() {        camera.stopPreview();    }    /**     * 销毁摄像头     */    public void destroyCamera() {        if (camera != null) {            //当surfaceview关闭时,关闭预览并释放资源            camera.stopPreview();            camera.release();//释放相机            camera = null;        }    }    /**     * 返回最小的预览尺寸     *     * @param cameraInst     * @param type     * @return     */    private Camera.Size findMinResolution(Camera cameraInst, int type) throws Exception {        Camera.Parameters cameraParameters = cameraInst.getParameters();        List<Camera.Size> supportedPicResolutions = type == TYPE_PREVIEW ? cameraParameters.getSupportedPreviewSizes() : cameraParameters.getSupportedPictureSizes(); // 至少会返回一个值        if (supportedPicResolutions == null) {            return null;        }        Camera.Size resultSize = supportedPicResolutions.get(0);        for (Camera.Size size : supportedPicResolutions) {            if (size.width < resultSize.width) {                resultSize = size;            }        }        return resultSize;    }    /**     * 找到合适的尺寸     *     * @param cameraParameters     * @param maxDistortion    最大允许的宽高比     * @return     * @type 尺寸类型 0:preview  1:picture     */    public Camera.Size findBestResolution(Camera.Parameters cameraParameters, double maxDistortion, int type) throws Exception {        List<Camera.Size> supportedPicResolutions = type == TYPE_PREVIEW ? cameraParameters.getSupportedPreviewSizes() : cameraParameters.getSupportedPictureSizes(); // 至少会返回一个值//        StringBuilder picResolutionSb = new StringBuilder();//        for (Camera.Size supportedPicResolution : supportedPicResolutions) {//            picResolutionSb.append(supportedPicResolution.width).append('x')//                    .append(supportedPicResolution.height).append(" ");//        }////        Log.d(TAG, "Supported picture resolutions: " + picResolutionSb);////        Camera.Size defaultPictureResolution = cameraParameters.getPictureSize();//        Log.d(TAG, "default picture resolution " + defaultPictureResolution.width + "x"//                + defaultPictureResolution.height);        // 排序        List<Camera.Size> sortedSupportedPicResolutions = new ArrayList<Camera.Size>(                supportedPicResolutions);        Collections.sort(sortedSupportedPicResolutions, new Comparator<Camera.Size>() {            @Override            public int compare(Camera.Size a, Camera.Size b) {                int aRatio = a.width / a.height;                int bRatio = b.width / a.height;                if (Math.abs(aRatio - 1) <= Math.abs(bRatio - 1)) {                    return -1;                } else {                    return 1;                }            }        });        //返回最合适的        return sortedSupportedPicResolutions.get(sortedSupportedPicResolutions.size() - 1);    }    /**     * 返回合适的照片尺寸参数     *     * @param cameraParameters     * @param bl     * @return     */    private Camera.Size findFitPicResolution(Camera.Parameters cameraParameters, float bl) throws Exception {        List<Camera.Size> supportedPicResolutions = cameraParameters.getSupportedPictureSizes();        Camera.Size resultSize = null;        for (Camera.Size size : supportedPicResolutions) {            if ((float) size.width / size.height == bl && size.width <= ALLOW_PIC_LEN && size.height <= ALLOW_PIC_LEN) {                if (resultSize == null) {                    resultSize = size;                } else if (size.width > resultSize.width) {                    resultSize = size;                }            }        }        if (resultSize == null) {            return supportedPicResolutions.get(0);        }        return resultSize;    }    /**     * 返回合适的预览尺寸参数     *     * @param cameraParameters     * @return     */    private Camera.Size findFitPreResolution(Camera.Parameters cameraParameters) throws Exception {        List<Camera.Size> supportedPicResolutions = cameraParameters.getSupportedPreviewSizes();        Camera.Size resultSize = null;        for (Camera.Size size : supportedPicResolutions) {            if (size.width <= ALLOW_PIC_LEN) {                if (resultSize == null) {                    resultSize = size;                } else if (size.width > resultSize.width) {                    resultSize = size;                }            }        }        if (resultSize == null) {            return supportedPicResolutions.get(0);        }        return resultSize;    }}

SensorManger.java

import android.content.Context;import android.hardware.Sensor;import android.hardware.SensorEvent;import android.hardware.SensorEventListener;import android.hardware.SensorManager;/** * Created by zouguibao on 2017/11/23. */public class SensorManger implements SensorEventListener{    public static SensorManger intance;    private boolean autoFocus;    private OnAccelSensorListener accelSensorListener;    private SensorManager sensorManager;//使用传感器实现连续自动调整焦点    private Sensor mAccelSensor;//重力感应    private boolean mInvalidate = false;    private boolean mInitialized = false;    private float mLastX = 0;    private float mLastY = 0;    private float mLastZ = 0;    private SensorManger(){    }    public static SensorManger getIntance(){        if(intance == null){            intance = new SensorManger();        }        return intance;    }    public void initSensorManager(Context context){        sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);        mAccelSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);    }    public void registerListener(){        sensorManager.registerListener(this, mAccelSensor, SensorManager.SENSOR_DELAY_UI);    }    public void unRegisterListener(){        sensorManager.unregisterListener(this);    }    public void lockFocus(){        autoFocus = false;    }    public void unLockFocus(){        autoFocus = true;    }    @Override    public void onSensorChanged(SensorEvent event) {        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {            if (mInvalidate == true) {//            mView.invalidate();                mInvalidate = false;            }            float x = event.values[0];            float y = event.values[1];            float z = event.values[2];            if (!mInitialized) {                mLastX = x;                mLastY = y;                mLastZ = z;                mInitialized = true;            }            float deltaX = Math.abs(mLastX - x);            float deltaY = Math.abs(mLastY - y);            float deltaZ = Math.abs(mLastZ - z);            if (deltaX > .5 && autoFocus) {                autoFocus = false;                if(accelSensorListener != null){                    accelSensorListener.onAccelSensor();                }            }            if (deltaY > .5 && autoFocus) {                autoFocus = false;                if(accelSensorListener != null){                    accelSensorListener.onAccelSensor();                }            }            if (deltaZ > .5 && autoFocus) {                //AUTOFOCUS (while it is not autofocusing) */                autoFocus = false;                if(accelSensorListener != null){                    accelSensorListener.onAccelSensor();                }            }            mLastX = x;            mLastY = y;            mLastZ = z;        }    }    @Override    public void onAccuracyChanged(Sensor sensor, int accuracy) {    }    public void setAccelSensorListener(OnAccelSensorListener accelSensorListener) {        this.accelSensorListener = accelSensorListener;    }    public interface OnAccelSensorListener{         void onAccelSensor();    }}

CustomCameraActivity.java

import android.app.Activity;import android.graphics.Point;import android.hardware.Camera;import android.os.Bundle;import android.os.Handler;import android.support.annotation.Nullable;import android.util.DisplayMetrics;import android.view.Display;import android.view.MotionEvent;import android.view.OrientationEventListener;import android.view.Surface;import android.view.SurfaceHolder;import android.view.SurfaceView;import android.view.View;import android.view.ViewGroup;import android.view.WindowManager;import android.widget.ImageButton;import android.widget.RelativeLayout;import com.creditease.runningman.R;/** * Created by guibaozou on 2017/8/17. */public class CustomCameraActivity extends Activity implements View.OnClickListener, Camera.AutoFocusCallback, Camera.PictureCallback ,SensorManger.OnAccelSensorListener{    private SurfaceView surfaceView;    private ImageButton swapCameraBtn;    private ImageButton takePhotoBtn;    private ImageButton backBtn;    private ImageButton surePhotoBtn;    private ImageButton reTakeBtn;    private FocusView focusView;    private RelativeLayout rootLayout;    private OrientationEventListener orientationEventListener;    private int screenWidth;    private int screenHeight;    private String screenRate;    private SurfaceHolder holder;    private Handler mHandler = new Handler();    @Override    protected void onCreate(@Nullable Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // 全屏显示        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,                WindowManager.LayoutParams.FLAG_FULLSCREEN);        setContentView(R.layout.custom_camera);        surfaceView = (SurfaceView) findViewById(R.id.surfaceView);        swapCameraBtn = (ImageButton) findViewById(R.id.cameraSwap);        takePhotoBtn = (ImageButton) findViewById(R.id.takePhoto);        backBtn = (ImageButton) findViewById(R.id.backBtn);        surePhotoBtn = (ImageButton) findViewById(R.id.surePhoto);        reTakeBtn = (ImageButton) findViewById(R.id.reTakePhoto);        rootLayout = (RelativeLayout) findViewById(R.id.root_layout);        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(160, 160);        focusView = new FocusView(this);        focusView.setLayoutParams(layoutParams);        holder = surfaceView.getHolder();        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);//        holder.setFixedSize(176, 144);//设置分辨率        holder.setKeepScreenOn(true);//屏幕长亮        holder.addCallback(new SurfaceCallBack());////为SurfaceView的句柄添加一个回调函数        swapCameraBtn.setOnClickListener(this);        takePhotoBtn.setOnClickListener(this);        backBtn.setOnClickListener(this);        surePhotoBtn.setOnClickListener(this);        reTakeBtn.setOnClickListener(this);        WindowManager windowManager = getWindowManager();        Display display = windowManager.getDefaultDisplay();        DisplayMetrics metrics = new DisplayMetrics();        //获取屏幕的宽和高        display.getMetrics(metrics);        screenWidth = metrics.widthPixels;        screenHeight = metrics.heightPixels;        SensorManger.getIntance().initSensorManager(this);        SensorManger.getIntance().setAccelSensorListener(this);        screenRate = getSurfaceViewSize(screenWidth, screenHeight);        setSurfaceViewSize(screenRate);        orientationEventListener = new OrientationEventListener(this) {            @Override            public void onOrientationChanged(int orientation) {                if (orientation == OrientationEventListener.ORIENTATION_UNKNOWN) {                    return;  //手机平放时,检测不到有效的角度                }                //只检测是否有四个角度的改变                if (orientation > 350 || orientation < 10) { //0度                    orientation = 90;                } else if (orientation > 80 && orientation < 100) { //90度                    orientation = 0;                } else if (orientation > 170 && orientation < 190) { //180度                    orientation = 270;                } else if (orientation > 260 && orientation < 280) { //270度                    orientation = 180;                } else {                    orientation = 0;                }                DataUtils.degree = orientation;            }        };    }    private float startDis;    private boolean isTouch;    /**     * 记录是拖拉照片模式还是放大缩小照片模式     */    private static final int MODE_INIT = 0;    /**     * 放大缩小照片模式     */    private static final int MODE_ZOOM = 1;    private int mode = MODE_INIT;// 初始状态    private Point point;    @Override    public boolean onTouchEvent(MotionEvent event) {        switch (event.getAction() & MotionEvent.ACTION_MASK) {            case MotionEvent.ACTION_DOWN:                mode = MODE_INIT;                break;            case MotionEvent.ACTION_POINTER_DOWN:                if (event.getPointerCount() < 2)                    return super.onTouchEvent(event);                mode = MODE_ZOOM;                startDis = spacing(event);                break;            case MotionEvent.ACTION_MOVE:                if (mode == MODE_ZOOM) {                    if (event.getPointerCount() < 2)                        return super.onTouchEvent(event);                    float endDis = spacing(event);                    int scale = (int) ((endDis - startDis) / 10f);                    if (scale >= 1 || scale <= -1) {                        CameraManger.getInstance().setCameraZoom(scale);                        startDis = endDis;                    }                }                break;            case MotionEvent.ACTION_UP:                if (mode == MODE_INIT) {                    point = new Point((int) event.getX(), (int) event.getY());                    SensorManger.getIntance().lockFocus();                    isTouch = CameraManger.getInstance().setCameraFocusAreas(point);                    if (isTouch) {                        CameraManger.getInstance().setCameraAutoFocus(CustomCameraActivity.this);                    }                }                break;        }        return super.onTouchEvent(event);    }    /**     * 两点的距离     */    private float spacing(MotionEvent event) {        if (event == null) {            return 0;        }        float x = event.getX(0) - event.getX(1);        float y = event.getY(0) - event.getY(1);        return (float) Math.sqrt(x * x + y * y);    }    // 提供一个静态方法,用于根据手机方向获得相机预览画面旋转的角度    private int getPreviewDegree(Activity activity) {        // 获得手机的方向        int rotation = getWindowManager().getDefaultDisplay().getRotation();        int degree = 0;        // 根据手机的方向计算相机预览画面应该选择的角度        switch (rotation) {            case Surface.ROTATION_0:                degree = 90;                break;            case Surface.ROTATION_90:                degree = 0;                break;            case Surface.ROTATION_180:                degree = 270;                break;            case Surface.ROTATION_270:                degree = 180;                break;        }        return degree;    }    public String getSurfaceViewSize(int width, int height) {        if (equalRate(width, height, 1.33f)) {            return "4:3";        } else {            return "16:9";        }    }    public boolean equalRate(int width, int height, float rate) {        float r = (float) width / (float) height;        if (Math.abs(r - rate) <= 0.2) {            return true;        } else {            return false;        }    }    /**     * 根据分辨率设置预览SurfaceView的大小以防止变形     *     * @param surfaceSize     */    private void setSurfaceViewSize(String surfaceSize) {        ViewGroup.LayoutParams params = surfaceView.getLayoutParams();        if (surfaceSize.equals("16:9")) {            params.height = ViewGroup.LayoutParams.MATCH_PARENT;        } else if (surfaceSize.equals("4:3")) {            params.height = 4 * screenWidth / 3;        }        surfaceView.setLayoutParams(params);    }    @Override    protected void onResume() {        super.onResume();        if (orientationEventListener.canDetectOrientation()) {            orientationEventListener.enable();        }        SensorManger.getIntance().registerListener();    }    @Override    protected void onPause() {        super.onPause();        orientationEventListener.disable();        SensorManger.getIntance().unRegisterListener();    }    @Override    protected void onDestroy() {        super.onDestroy();    }    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.backBtn:                destroyCamera();                finish();                break;            case R.id.takePhoto:                //锁定焦点                SensorManger.getIntance().lockFocus();                //拍照                CameraManger.getInstance().takePicture(CustomCameraActivity.this, CustomCameraActivity.this);                break;            case R.id.reTakePhoto:                CameraManger.getInstance().startPreview();                takePhotoBtn.setVisibility(View.VISIBLE);                surePhotoBtn.setVisibility(View.GONE);                backBtn.setVisibility(View.VISIBLE);                reTakeBtn.setVisibility(View.GONE);                SensorManger.getIntance().unLockFocus();                break;            case R.id.surePhoto:                destroyCamera();                setResult(RESULT_OK);                CameraManger.getInstance().closeShutterSound();                finish();                break;            case R.id.cameraSwap:                CameraManger.getInstance().turnCamera(holder, CustomCameraActivity.this, getPreviewDegree(CustomCameraActivity.this),screenWidth,screenHeight);                break;            default:                break;        }    }    /**     * 自定聚焦监听器的方法     *     * @param success     * @param camera     */    @Override    public void onAutoFocus(boolean success, Camera camera) {        if (success) {            SensorManger.getIntance().unLockFocus();            rootLayout.removeView(focusView);            RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) focusView.getLayoutParams();            if (!isTouch) {                params.addRule(RelativeLayout.CENTER_IN_PARENT);            } else {                isTouch = false;                if (point != null) {                    params.leftMargin = point.x - 30;                    params.topMargin = point.y - 30;                } else {                    params.addRule(RelativeLayout.CENTER_IN_PARENT);                }            }            rootLayout.addView(focusView, params);            mHandler.postDelayed(new Runnable() {                @Override                public void run() {                    rootLayout.removeView(focusView);                }            }, 1000);        }    }    @Override    public void onPictureTaken(byte[] data, Camera camera) {        CameraManger.getInstance().stopPreview();        //将拍摄到的照片给自定义的对象        DataUtils.tempImageData = data;        takePhotoBtn.setVisibility(View.GONE);        surePhotoBtn.setVisibility(View.VISIBLE);        backBtn.setVisibility(View.GONE);        reTakeBtn.setVisibility(View.VISIBLE);        SensorManger.getIntance().unLockFocus();    }    @Override    public void onAccelSensor() {        CameraManger.getInstance().setCameraAutoFocus(this);    }    private final class SurfaceCallBack implements SurfaceHolder.Callback {        @Override        public void surfaceCreated(SurfaceHolder holder) {            CameraManger.getInstance().openCamera(holder,CustomCameraActivity.this,getPreviewDegree(CustomCameraActivity.this));        }        @Override        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {            CameraManger.getInstance().setCameraParameters(screenWidth,screenHeight);        }        @Override        public void surfaceDestroyed(SurfaceHolder holder) {            destroyCamera();        }    }    private void destroyCamera() {        CameraManger.getInstance().destroyCamera();        holder.getSurface().release();        surfaceView = null;    }}


xml:


<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:id="@+id/root_layout"    android:layout_width="match_parent"    android:layout_height="match_parent"    >    <SurfaceView        android:id="@+id/surfaceView"        android:layout_width="match_parent"        android:layout_height="match_parent" />    <ImageButton        android:id="@+id/cameraSwap"        android:layout_width="60dp"        android:layout_height="60dp"        android:src="@drawable/camera_swap"        android:layout_alignParentTop="true"        android:layout_alignParentRight="true"        android:background="@android:color/transparent"        />    <ImageButton        android:id="@+id/takePhoto"        android:layout_width="80dp"        android:layout_height="80dp"        android:src="@drawable/take_photo"        android:layout_alignParentBottom="true"        android:layout_centerHorizontal="true"        android:background="@android:color/transparent"        />    <ImageButton        android:id="@+id/reTakePhoto"        android:layout_width="80dp"        android:layout_height="80dp"        android:src="@drawable/re_take"        android:layout_alignParentBottom="true"        android:layout_alignParentLeft="true"        android:visibility="gone"        android:layout_marginLeft="10dp"        android:background="@android:color/transparent"        />    <ImageButton        android:id="@+id/backBtn"        android:layout_width="40dp"        android:layout_height="40dp"        android:src="@drawable/arrow_down_pressed"        android:layout_alignParentBottom="true"        android:layout_alignParentLeft="true"        android:layout_marginBottom="25dp"        android:layout_marginLeft="10dp"        android:background="@android:color/transparent"        />    <ImageButton        android:id="@+id/surePhoto"        android:layout_width="80dp"        android:layout_height="80dp"        android:src="@drawable/camera_sure"        android:layout_alignParentBottom="true"        android:layout_alignParentRight="true"        android:visibility="gone"        android:background="@android:color/transparent"        /></RelativeLayout>
辅助类DataUtils:
public class DataUtils {    public static byte[] tempImageData;    public static int degree;    public static boolean isBackCamera = true;}


辅助类FocusView:

import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.support.annotation.Nullable;import android.util.AttributeSet;import android.view.View;/** * Created by zouguibao on 2017/11/16. */public class FocusView extends View {    private int w;    private int h;    private Paint paint;    public FocusView(Context context) {        super(context);        init();    }    public FocusView(Context context, @Nullable AttributeSet attrs) {        super(context, attrs);        init();    }    public FocusView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {        super(context, attrs, defStyleAttr);        init();    }    private void init(){        paint = new Paint();        paint.setAntiAlias(true);        paint.setStrokeWidth(5);        paint.setStyle(Paint.Style.STROKE);        paint.setColor(Color.GREEN);    }    @Override    protected void onSizeChanged(int w, int h, int oldw, int oldh) {        super.onSizeChanged(w, h, oldw, oldh);        this.w = w;        this.h = h;    }    @Override    protected void onDraw(Canvas canvas) {        super.onDraw(canvas);        canvas.drawLine(0,0,this.w,0,paint);        canvas.drawLine(0,0,0,this.h,paint);        canvas.drawLine(this.w,0,this.w,this.h,paint);        canvas.drawLine(0,this.h,this.w,this.h,paint);    }}

每次拍完照片想要获取到竖屏的照片则如以下方式旋转即可:

Bitmap bm0 = BitmapFactory.decodeByteArray(DataUtils.tempImageData,0,DataUtils.tempImageData.length);Matrix m = new Matrix();int rotate = 0;//不论拍照时是在哪个方向上拍摄的,得到的都是竖直版的正向的图片,这是后置摄像头的if(DataUtils.isBackCamera){    if(DataUtils.degree == 90){        rotate = 90;    }else if(DataUtils.degree == 0){        rotate = 90;    }else if(DataUtils.degree == 180){        rotate = -90;    }else if(DataUtils.degree == 270){        rotate = -90;    }}else{
    //前置摄像头的    if(DataUtils.degree == 90){        rotate = 270;    }else if(DataUtils.degree == 0){        rotate = 270;    }else if(DataUtils.degree == 180){        rotate = 90;    }else if(DataUtils.degree == 270){        rotate = 90;    }}m.setRotate(rotate,(float) bm0.getWidth() / 2, (float) bm0.getHeight() / 2);final Bitmap bm = Bitmap.createBitmap(bm0, 0, 0, bm0.getWidth(), bm0.getHeight(), m, true);

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature    android:name="android.hardware.camera"    android:required="true" /><uses-feature    android:name="android.hardware.camera.autofocus"    android:required="true" />


以上就是全部内容了。其中借鉴了一些其他人的代码,再此感谢,参考如下:

https://github.com/huweigoodboy/SweetCamera



阅读全文
1 0
原创粉丝点击