赞
踩
将camera肯定是要有预览界面来配合着才有激情,不然无图无真相。那就讲的没有太大的激情。
我们对camera的使用一般是在app里面有用到设置获取图片的时候提供一个拍照功能,一般是跳转到系统的拍照界面使用camera来获取图片;有的app有需求就跳转到自己的拍照界面。我们知道系统的应用其实也是个app,无论是跳转到系统拍照界面还是自己的拍照界面其实都是一个preview,然后再“截屏”生成一个图片。我下面讲一些关于camera的基础和preview的结合使用。
首先要获取camera的属性:Camera.Parameters parameters = camera.getParameters();
camera的基本属性设置:
(1)设置预览大小 :
parameters.setPreviewSize(“宽”, “高”);
一般设置的预览大小就是手机屏幕的宽高,那么就要获取屏幕的宽高,然后再经过稍微的处理:
- WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- Display display = manager.getDefaultDisplay();
- 宽:display.getWidth() 高:display.getHeight()
由于下面的介绍都会用到一个系统的实体Point,所以我这里把宽高设置到这个实体里面,然后方便使用,然后就得到下面的代码:
- WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE);
- Display display = manager.getDefaultDisplay();
-
- //获取屏幕的宽高(像素值)设置到一个实体(point)里面
- Point screenResolution = new Point(display.getWidth(), display.getHeight());
然后再根据屏幕的宽高做优化处理:
/*根据相机的参数和手机屏幕参数来重新设置相机的*/ public Point getCameraResolution(Camera.Parameters parameters, Point screenResolution) { String previewSizeValueString = parameters.get("preview-size-values"); if (previewSizeValueString == null) { previewSizeValueString = parameters.get("preview-size-value"); } Point cameraResolution = null; if (previewSizeValueString != null) { cameraResolution = findBestPreviewSizeValue(previewSizeValueString, screenResolution); } if (cameraResolution == null) { //没有找到最优的预览效果,那么至少也要确保相机分辨率是8的倍数(我也不知道为什么),下面的操作就是防备屏幕不是8的倍数,如果 //是8的倍数,就会在上面的寻找最优size的时候会找到的 cameraResolution = new Point( (screenResolution.x >> 3) << 3, (screenResolution.y >> 3) << 3); } return cameraResolution; } /*根据预览大小和手机屏幕大小来设一个比较完美的预览效果*/ public Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) { int bestX = 0; int bestY = 0; int diff = Integer.MAX_VALUE;//差值 for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) { previewSize = previewSize.trim(); int dimPosition = previewSize.indexOf('x'); if (dimPosition < 0) { //这是一个很差的预览大小 continue; } int newX; int newY; try { newX = Integer.parseInt(previewSize.substring(0, dimPosition)); newY = Integer.parseInt(previewSize.substring(dimPosition + 1)); } catch (NumberFormatException nfe) { //字符串转换异常,这是自己写的tryCatch,是为了安全起见 continue; } int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y); if (newDiff == 0) { bestX = newX; bestY = newY; break; } else if (newDiff < diff) { bestX = newX; bestY = newY; diff = newDiff; } } if (bestY > 0 && bestX > 0) { return new Point(bestX, bestY); } return null; }
- Camera.Parameters parameters = camera.getParameters();
- parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);//设置相机的预览size
(2)设置闪光灯:
- /*设置闪光灯,本来是不用设置的,应该是直接获取,但是根据三星建议说防止黑客攻击,最好设置一下*/
- private void setFlash(Camera.Parameters parameters) {
- if (Build.MODEL.contains("Behold II") && Integer.parseInt(Build.VERSION.SDK) == 3) {
- parameters.set("flash-value", 1);
- } else {
- parameters.set("flash-value", 2);
- }
- parameters.set("flash-mode", "off");
- }
(3)设置缩放:
一般使用camera进行拍照和录制视频的时候都要支持手势识别进行缩放,原理就是把手势缩放的xy值然后进行算法转换然后动态的设置到camera的parameter上。
使用的时候你可以直接进行设置,parameter.set("zoom","10");来设置缩放。
/*设置缩放*/ private void setZoom(Camera.Parameters parameters) { String zoomSupportString = parameters.get("zoom-supported"); if (zoomSupportString != null && !Boolean.parseBoolean(zoomSupportString)) { return; } int tenDesiredZoom = TEN_DESIRED_ZOOM;//TEN_DESIRED_ZOOM = 27 String maxZoomString = parameters.get("max-zoom"); if (maxZoomString != null) { try { int tenMaxZoom = (int) (10.0 * Double.parseDouble(maxZoomString)); if (tenDesiredZoom > tenMaxZoom) { tenDesiredZoom = tenMaxZoom; } } catch (NumberFormatException e) { Log.i(TAG, "获取原本的缩放最大级别转换失败"); } String takingPictureZoomMaxString = parameters.get("taking-picture-zoom-max"); if (takingPictureZoomMaxString != null) { try { int takePicMax = Integer.parseInt(takingPictureZoomMaxString); if (tenDesiredZoom > takePicMax) { tenDesiredZoom = takePicMax; } Log.i(TAG, "拍照缩放级别被最原始级别小"); } catch (NumberFormatException nfe) { Log.i(TAG, "拍照缩放级别转换失败"); } } String motZoomMaxString = parameters.get("mot-zoom-values"); if (motZoomMaxString != null) { tenDesiredZoom = findBestMotZoomValue(motZoomMaxString, tenDesiredZoom); } String motZoomStepString = parameters.get("mot-zoom-step"); if (motZoomStepString != null) { try { double motZoomStep = Double.parseDouble(motZoomStepString.trim()); int tenZoomStep = (int) (10.0 * motZoomStep); if (tenZoomStep > 1) { tenDesiredZoom -= tenDesiredZoom % tenZoomStep; } } catch (NumberFormatException nfe) { } } if (maxZoomString != null || motZoomMaxString != null) { parameters.set("zoom", String.valueOf(tenDesiredZoom / 10.0)); } if (takingPictureZoomMaxString != null) { parameters.set("taking-picture-zoom", tenDesiredZoom); } } } private static int findBestMotZoomValue(CharSequence stringValues, int tenDesireZoom) { int tenBestValue = 0; for (String stringValue : COMMA_PATTERN.split(stringValues)) { stringValue = stringValue.trim(); double value; try { value = Double.parseDouble(stringValue); } catch (NumberFormatException nfe) { return tenDesireZoom; } int tenValue = (int) (10.0 * value); if (Math.abs(tenDesireZoom - value) < Math.abs(tenDesireZoom - tenBestValue)) { tenBestValue = tenValue; } } return tenBestValue; }
最后贴一个完整测camera的配置类:
import android.content.Context; import android.graphics.Point; import android.hardware.Camera; import android.os.Build; import android.util.Log; import android.view.Display; import android.view.WindowManager; import java.lang.reflect.Method; import java.util.regex.Pattern; public class CameraConfigurationManager { private static final String TAG = "Cy==CameraConfigManager"; private Context mContext; private Point screenResolution; private static final Pattern COMMA_PATTERN = Pattern.compile(","); private Point cameraResolution; private static final int TEN_DESIRED_ZOOM = 27;//设置十级缩放级别 private int previewFormat; private String previewFormatString; private CameraConfigurationManager() { } public Point getCameraResolution() { return cameraResolution; } public Point getScreenResolution() { return screenResolution; } public int getPreviewFormat() { return previewFormat; } public String getPreviewFormatString() { return previewFormatString; } private static final class Holder { private static final CameraConfigurationManager CAMERA_CONFIGURATION_MANAGER = new CameraConfigurationManager(); } public static CameraConfigurationManager getInstance() { return Holder.CAMERA_CONFIGURATION_MANAGER; } public CameraConfigurationManager setContext(Context mContext) { this.mContext = mContext; return this; } /*获取手机的相机和手机屏幕的一些基本参数*/ public void getCameraParams(Camera camera) { Camera.Parameters parameters = camera.getParameters(); //获取相机预览界面格式 previewFormat = parameters.getPreviewFormat(); previewFormatString = parameters.get("preview-format"); WindowManager manager = (WindowManager) mContext.getSystemService(Context.WINDOW_SERVICE); Display display = manager.getDefaultDisplay(); //获取屏幕的宽高(像素值)设置到一个实体(point)里面 screenResolution = new Point(display.getWidth(), display.getHeight()); //尽量获取相机最好的point cameraResolution = getCameraResolution(parameters, screenResolution); } /*设置相机的预览参数(渴望设置成什么样就设置成什么样)*/ public void setDseiredCameraParameters(Camera camera) { Camera.Parameters parameters = camera.getParameters(); parameters.setPreviewSize(cameraResolution.x, cameraResolution.y);//设置相机的预览size setFlash(parameters); setZoom(parameters); setDisplayOrientation(camera, 90); camera.setParameters(parameters); } /*设置展示角度*/ private void setDisplayOrientation(Camera camera, int orientation) { Class<? extends Camera> clazz = camera.getClass(); try { Method displayOrientation = clazz.getMethod("setDisplayOrientation", new Class[]{int.class}); if (displayOrientation != null) { displayOrientation.invoke(camera, new Object[]{orientation}); } } catch (Exception e) { e.printStackTrace(); } } /*设置缩放*/ private void setZoom(Camera.Parameters parameters) { String zoomSupportString = parameters.get("zoom-supported"); if (zoomSupportString != null && !Boolean.parseBoolean(zoomSupportString)) { return; } int tenDesiredZoom = TEN_DESIRED_ZOOM;//TEN_DESIRED_ZOOM = 27 String maxZoomString = parameters.get("max-zoom"); if (maxZoomString != null) { try { int tenMaxZoom = (int) (10.0 * Double.parseDouble(maxZoomString)); if (tenDesiredZoom > tenMaxZoom) { tenDesiredZoom = tenMaxZoom; } } catch (NumberFormatException e) { Log.i(TAG, "获取原本的缩放最大级别转换失败"); } String takingPictureZoomMaxString = parameters.get("taking-picture-zoom-max"); if (takingPictureZoomMaxString != null) { try { int takePicMax = Integer.parseInt(takingPictureZoomMaxString); if (tenDesiredZoom > takePicMax) { tenDesiredZoom = takePicMax; } Log.i(TAG, "拍照缩放级别被最原始级别小"); } catch (NumberFormatException nfe) { Log.i(TAG, "拍照缩放级别转换失败"); } } String motZoomMaxString = parameters.get("mot-zoom-values"); if (motZoomMaxString != null) { tenDesiredZoom = findBestMotZoomValue(motZoomMaxString, tenDesiredZoom); } String motZoomStepString = parameters.get("mot-zoom-step"); if (motZoomStepString != null) { try { double motZoomStep = Double.parseDouble(motZoomStepString.trim()); int tenZoomStep = (int) (10.0 * motZoomStep); if (tenZoomStep > 1) { tenDesiredZoom -= tenDesiredZoom % tenZoomStep; } } catch (NumberFormatException nfe) { } } if (maxZoomString != null || motZoomMaxString != null) { parameters.set("zoom", String.valueOf(tenDesiredZoom / 10.0)); } if (takingPictureZoomMaxString != null) { parameters.set("taking-picture-zoom", tenDesiredZoom); } } } private static int findBestMotZoomValue(CharSequence stringValues, int tenDesireZoom) { int tenBestValue = 0; for (String stringValue : COMMA_PATTERN.split(stringValues)) { stringValue = stringValue.trim(); double value; try { value = Double.parseDouble(stringValue); } catch (NumberFormatException nfe) { return tenDesireZoom; } int tenValue = (int) (10.0 * value); if (Math.abs(tenDesireZoom - value) < Math.abs(tenDesireZoom - tenBestValue)) { tenBestValue = tenValue; } } return tenBestValue; } /*设置闪光灯,本来是不用设置的,应该是直接获取,但是根据三星建议说防止黑客攻击,最好设置一下*/ private void setFlash(Camera.Parameters parameters) { if (Build.MODEL.contains("Behold II") && CameraManager.SDK_INT == 3) { parameters.set("flash-value", 1); } else { parameters.set("flash-value", 2); } parameters.set("flash-mode", "off"); } /*根据相机的参数和手机屏幕参数来重新设置相机的*/ public Point getCameraResolution(Camera.Parameters parameters, Point screenResolution) { String previewSizeValueString = parameters.get("preview-size-values"); if (previewSizeValueString == null) { previewSizeValueString = parameters.get("preview-size-value"); } Point cameraResolution = null; if (previewSizeValueString != null) { cameraResolution = findBestPreviewSizeValue(previewSizeValueString, screenResolution); } if (cameraResolution == null) { //没有找到最优的预览效果,那么至少也要确保相机分辨率是8的倍数(我也不知道为什么),下面的操作就是防备屏幕不是8的倍数,如果 //是8的倍数,就会在上面的寻找最优size的时候会找到的 cameraResolution = new Point( (screenResolution.x >> 3) << 3, (screenResolution.y >> 3) << 3); } return cameraResolution; } /*根据预览大小和手机屏幕大小来设一个比较完美的预览效果*/ public Point findBestPreviewSizeValue(CharSequence previewSizeValueString, Point screenResolution) { int bestX = 0; int bestY = 0; int diff = Integer.MAX_VALUE;//差值 for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) { previewSize = previewSize.trim(); int dimPosition = previewSize.indexOf('x'); if (dimPosition < 0) { //这是一个很差的预览大小 continue; } int newX; int newY; try { newX = Integer.parseInt(previewSize.substring(0, dimPosition)); newY = Integer.parseInt(previewSize.substring(dimPosition + 1)); } catch (NumberFormatException nfe) { //字符串转换异常,这是自己写的tryCatch,是为了安全起见 continue; } int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - screenResolution.y); if (newDiff == 0) { bestX = newX; bestY = newY; break; } else if (newDiff < diff) { bestX = newX; bestY = newY; diff = newDiff; } } if (bestY > 0 && bestX > 0) { return new Point(bestX, bestY); } return null; } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。