1、利用硬件传感器去实现自动对焦
注册传感器:
- SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
- sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_UI);
传感器接口:
- implements SensorEventListener
实现传感器接口方法:
- public void onSensorChanged(SensorEvent event) {
- float x = event.values[0];
- float y = event.values[1];
- float z = event.values[2];
- if (initFirstSensor) {//初始化默认进入时候的坐标
- mLastX = x;
- mLastY = y;
- mLastZ = z;
- initFirstSensor = false;
- return;
- }
- float deltaX = Math.abs(mLastX - x);
- float deltaY = Math.abs(mLastY - y);
- float deltaZ = Math.abs(mLastZ - z);
- if (deltaX > 2.5 || deltaY > 2.5 || deltaZ > 2.5) {//计算坐标偏移值
- if (!isPhoto && mCamera != null) {
- playFocusAnimal(focusX, focusY);//播放对焦动画
- // mCamera.autoFocus(autoFocusCallback);//调用相机对焦
- }
- }
- mLastX = x;
- mLastY = y;
- mLastZ = z;
- }
2、单点触摸对焦
监听touch事件拿到event:
- public boolean onTouch(View v, MotionEvent event) {
- if (!isPhoto && mCamera != null) {
- playFocusAnimal((int) event.getX(), (int) event.getY());
- touchFocus(event);
- }
- return false;
- }
根据触摸位置设置对焦点的对焦权值:
(解释一下:每个对焦区域是一个具有特定权值的长方形。方向与重力感应的方向有关。而且不会受到 setDisplayOrientation(int)旋转画面设置的影响。矩形的坐标范围指定从-1000到1000 ,(-1000,-1000)是左上角点(1000,1000)是右下角点。对焦权值的取值范围是1-1000,权值为矩形范围像素所平分,这意味着同样的权值对焦区域大的对整体的对焦影响小。
理论结合实际的说就是,假如你的整个屏幕的宽度是width,那么点击某个位置算x,那么要划定对焦区域,就要告诉相机对焦的坐标,根据对焦坐标的范围为-1000到1000,所以要用公式计算对应的对焦坐标实际上是: x/width*2000-1000=对焦x坐标,同样获取到对焦y坐标,然后以x,y为中心,指定对焦区域,设置对焦权值,越大表示优先对焦该位置)
代码:
- private void touchFocus(MotionEvent event) {
- mCamera.cancelAutoFocus();
- Camera.Parameters p = mCamera.getParameters();
- float touchX = (event.getRawX() / screenWidth) * 2000 - 1000;
- float touchY = (event.getRawY() / screenHeight) * 2000 - 1000;
- int left = clamp((int) touchX - AREA_SIZE / 2, -1000, 1000);
- int right = clamp(left + AREA_SIZE, -1000, 1000);
- int top = clamp((int) touchY - AREA_SIZE / 2, -1000, 1000);
- int bottom = clamp(top + AREA_SIZE, -1000, 1000);
- Rect rect = new Rect(left, top, right, bottom);
- if (p.getMaxNumFocusAreas() > 0) {
- List<Camera.Area> areaList = new ArrayList<Camera.Area>();
- areaList.add(new Camera.Area(rect, 1000));
- p.setFocusAreas(areaList);
- }
- if (p.getMaxNumMeteringAreas() > 0) {
- List<Camera.Area> areaList = new ArrayList<Camera.Area>();
- areaList.add(new Camera.Area(rect, 1000));
- p.setMeteringAreas(areaList);
- }
- p.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
- try {
- mCamera.setParameters(p);
- } catch (Exception e) {
- }
- mCamera.autoFocus(autoFocusCallback);
- }
- private int clamp(int x, int min, int max) {//保证坐标必须在min到max之内,否则异常
- if (x > max) {
- return max;
- }
- if (x < min) {
- return min;
- }
- return x;
- }
3、小米的坑
miui上的时候如果设置预览分辨率过高,则会导致拍照时候小米假死,无响应
解决方案:预览分辨率设置在屏幕分辨率左右,对miui特殊对待
- private void initCameraParameters() {
- Camera.Parameters parameters = mCamera.getParameters();
- List<Camera.Size> vSizeList = parameters.getSupportedPictureSizes();
- Camera.Size showSize = null;
- Camera.Size tempSize;
- Camera.Size miuiSize = null;
- for (int num = 0; num < vSizeList.size(); num++) {
- tempSize = vSizeList.get(num);
- try {
- parameters.setPreviewSize(tempSize.width, tempSize.height);
- mCamera.setParameters(parameters);
- if (showSize == null || (showSize != null && tempSize.width > showSize.width)) {
- showSize = tempSize;//设置最高可以支持的屏幕分辨率
- }
- if (screenWidth < tempSize.width && (miuiSize == null || miuiSize.width > tempSize.width)) {
- miuiSize = tempSize;//设置miui的预览大小在屏幕分辨率左右
- }
- } catch (Exception e) {
- }
- try {
- parameters.setPictureSize(tempSize.width, tempSize.height);
- mCamera.setParameters(parameters);
- if (highSize == null || (highSize != null && tempSize.width > highSize.width)) {
- highSize = tempSize;//设置相机可支持的最高保存分辨率
- }
- } catch (Exception e) {
- }
- if (screenWidth > tempSize.width && (nomalSize == null || nomalSize.width < tempSize.width)) {
- nomalSize = tempSize;//设置一般相机保存的分辨率
- }
- }
- if (showSize != null) {
- if (android.os.Build.MANUFACTURER.equals("Xiaomi")) {//对待小米特殊设置
- parameters.setPreviewSize(miuiSize.width, miuiSize.height);
- } else {
- parameters.setPreviewSize(showSize.width, showSize.height);
- }
- }
- if (nomalSize != null) {
- parameters.setPictureSize(nomalSize.width, nomalSize.height);
- isNomal = true;
- if (picQualityButton != null) {
- picQualityButton.setImageDrawable(getResources().getDrawable(R.drawable.camera_pic_quality_nomal));
- }
- }
- if (isSupportFlash) {
- switch (currentFlashMode % 3) {
- case 0:
- parameters.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
- break;
- case 1:
- parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
- break;
- case 2:
- parameters.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
- break;
- }
- }
- parameters.setPictureFormat(PixelFormat.JPEG);
- parameters.setJpegQuality(100);
- mCamera.setParameters(parameters);
- mCamera.startPreview();
- playFocusAnimal(screenWidth / 2, screenHeight / 2);
- mCamera.autoFocus(autoFocusCallback);
- }
author:iamwsbear@gmail.com
http://blog.csdn.net/iamws/article/details/50401886