相机的功能丰富,加入前后摄像头的翻转,闪光灯,对焦功能。
首先加入我们相机的自动对焦功能
这里我们用到一个工具类来进行对焦,主要的实现自动对焦功能,该类的主要逻辑是通过对传感器的x、y、z轴的监听来判断当前设备是否需要进行自动对焦,在这个基础上也做了时间的约定,方式过于频繁的对焦,导致体验和性能的浪费。
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
if (mLastUpdate + 100 > curTime) {
return;
}
long diffTime = (curTime - mLastUpdate);
mLastUpdate = curTime;
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float dx = x - mLastX;
float dy = y - mLastY;
float dz = z - mLastZ;
float speed = (float) (Math.sqrt(dx * dx + dy * dy + dz * dz)
/ diffTime * 10000);
mLastX = x;
mLastY = y;
mLastZ = z;
//LogEx.i("speed: " + speed + ", MOVE_THRESHOLD: " + MOVE_THRESHOLD);
if (speed > MOVE_THRESHOLD) {
staticCount = staticCount < 0 ? --staticCount : -1;
if (staticCount + kMotiveThresholdCount <= 0) {
waitingFocuse = true;
}
} else {
staticCount = staticCount > 0 ? ++staticCount : 1;
if (waitingFocuse && staticCount >= kStaticThresholdCount) {
waitingFocuse = false;
if (null != listener) {
listener.needFocuse();
}
}
}
}
}
上面只贴出了传感器变化的时候的逻辑,处理工作,这里注册监听方法needFocuse
,方便外面回调进行自己的处理(该类来自网络),后期会加上点击对焦,和点击焦点框的跟随。
下面是摄像头的翻转操作
摄像头的翻转主要是通过一个标记来设置打开的是前置或后置摄像头,设置默认后置摄像头id为0,然后通过去通过系统api去判断是否有前置摄像头,然后在切换摄像头的操作中,始终保证当前摄像头的实时赋值,现在的手机后面有双摄像头,由于我这里没有设备,这里暂时不做说明,后期会补上。下面是简单的几行代码:
//赋值当前摄像头,在去判断是否前置摄像头
currentCameraId = 0;
frontCameraId = findFrontFacingCamera();
if (-1 == frontCameraId) {
bnToggleCamera.setVisibility(View.INVISIBLE);
}
//下面是findFrontFacingCamera方法,如果返回值是-1,则不许显示翻转摄像头的按钮。
private int findFrontFacingCamera() {
int cameraId = -1;
// Search for the front facing camera
int numberOfCameras = Camera.getNumberOfCameras();
for (int i = 0; i < numberOfCameras; i++) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(i, info);
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
Log.d(TAG, "Camera found");
cameraId = i;
break;
}
}
return cameraId;
}
闪光灯的设置
闪光灯设置有两种,一种是常见的手电筒功能,也是现在应用上用的最多的;另一种就是美图相机的那种和系统类似的闪光灯,在拍照的时候闪烁。
下面分开介绍一下,其实很简单,主要是设置相机的参数,如果你完整的做过相机的功能,你会发现好多实现都是设置相机参数,包括焦距调整,白平衡设置等等
下面简单介绍一个手电筒的功能:
这个就非常的简单了,只是通过获取相机的parameter来设置参数就可以了,下面贴出代码:
private void openORCloseLight() {
if (isOpen) {
Camera.Parameters parameter = camera.getParameters();
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(parameter);
isOpen = false;
} else {
Camera.Parameters parameter = camera.getParameters();
parameter.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(parameter);
isOpen = true;
}
bnToggleLight.setChecked(isOpen);
}
下面介绍一下标准的闪光灯模式
这里我们分为三种模式分别为开闪光灯、关闭闪光灯、自动闪光模式
我这里的思路是通过集合+当前模式选择的标记来做,下面是简单的代码:
//存放三个图标,当前图标为0
private int[] image = new int[]{
R.drawable.flashlight_off_icn,
R.drawable.flashlight_on_icn,
R.drawable.flashlight_auto_icn
};
private int currentImg = 0;
//下面是点击事件的处理操作,只是简单设置参数
if (currentImg >= 2) {
currentImg = -1;
}
tv_open_beauty.setImageResource(image[++currentImg]);
if (null == camera) {
camera = Camera.open();
}
switch (currentImg) {
case 0:
Camera.Parameters params = camera.getParameters();
List<String> flashModes = params.getSupportedFlashModes();
if (flashModes.contains(Camera.Parameters.FLASH_MODE_OFF)) {
params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
}
camera.setParameters(params);
break;
case 1:
params = camera.getParameters();
flashModes = params.getSupportedFlashModes();
if (flashModes.contains(Camera.Parameters.FLASH_MODE_ON)) {
params.setFlashMode(Camera.Parameters.FLASH_MODE_ON);
}
camera.setParameters(params);
break;
case 2:
params = camera.getParameters();
flashModes = params.getSupportedFlashModes();
if (flashModes.contains(Camera.Parameters.FLASH_MODE_AUTO)) {
params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
}
camera.setParameters(params);
break;
}
上面我最初的代码,后来在测试的过程中发现,如果这是这样简单的设置,在小米note上会引起一个问题,就是你前面如果设置了其他参数会失效,所以这只这个的时候要考虑到会不会其他的参数产生影响。
下一篇会介绍相机的照片的水印功能,优化相机打开速度比较慢的体验问题,相机的连拍功能等。