package com.yydcdut.note.model.camera.impl;
import android.graphics.Rect;
import android.hardware.Camera;
import com.yydcdut.note.model.camera.ICameraFocus;
import com.yydcdut.note.utils.YLog;
import java.util.Arrays;
/**
* Created by yuyidong on 16/2/6.
*/
public class CameraFocusModel implements ICameraFocus {
private static final String TAG = CameraFocusModel.class.getSimpleName();
private static final int LEFT = -1000;
private static final int TOP = -1000;
private static final int RIGHT = 1000;
private static final int BOTTOM = 1000;
private static final int WIDTH = 2000;
private static final int HEIGHT = 2000;
private static final int HALF_WIDTH = 1000;
private static final int HALF_HEIGHT = 1000;
private static final int MEASURE_WIDTH = 200;
private static final int MEASURE_HEIGHT = 200;
private static final int WEIGHT = 900;
private int mState = FOCUS_STATE_IDLE;
private Camera mCamera;
private boolean mIsSupport = false;
private int mViewWidth;
private int mViewHeight;
public CameraFocusModel(Camera camera, int viewWidth, int viewHeight) {
this.mCamera = camera;
mIsSupport = isSupportFocus();
mViewWidth = viewWidth;
mViewHeight = viewHeight;
}
@Override
public int getFocusState() {
if (mIsSupport) {
return mState;
} else {
//不支持,那么状态一直为IDLE
return FOCUS_STATE_IDLE;
}
}
@Override
public void triggerFocus(int viewWidth, int viewHeight, int x, int y) {
if (mIsSupport) {
mState = FOCUS_STATE_FOCUSING;
Camera.Parameters parameters = mCamera.getParameters();
parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
parameters.setFocusAreas(Arrays.asList(convert(calculateTapArea(viewWidth, viewHeight, x, y, 1f))));
parameters.setMeteringAreas(Arrays.asList(convert(calculateTapArea(viewWidth, viewHeight, x, y, 2f))));
try {
mCamera.setParameters(parameters);
} catch (Exception e) {
YLog.e(e);
}
mCamera.autoFocus(mAutoFocusCallback);
}
}
/**
* Convert touch position x:y in (-1000~1000)
*/
private Rect calculateTapArea(int viewWidth, int viewHeight, float x, float y, float coefficient) {
int areaSize = Float.valueOf(300 * coefficient).intValue();
x = x / viewWidth;
y = y / viewHeight;
float cameraX = y;
float cameraY = 1 - x;
int centerX = (int) (cameraX * 2000 - 1000);
int centerY = (int) (cameraY * 2000 - 1000);
int left = clamp(centerX - areaSize / 2, -1000, 1000);
int top = clamp(centerY - areaSize / 2, -1000, 1000);
int right = clamp(left + areaSize, -1000, 1000);
int bottom = clamp(top + areaSize, -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;
}
@Override
public void cancelFocus() {
mCamera.cancelAutoFocus();
}
private Camera.AutoFocusCallback mAutoFocusCallback = new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
mState = FOCUS_STATE_FOCUSED_GOOD;
} else {
mState = FOCUS_STATE_FOCUSED_BAD;
}
}
};
/**
* 将自己的Area转换成Camera.Area
*
* @return
*/
private Camera.Area convert(int x, int y) {
return new Camera.Area(convertArea(x, y), WEIGHT);
}
private Camera.Area convert(Rect rect) {
return new Camera.Area(rect, WEIGHT);
}
/**
* 判断是否支持focus
*
* @return
*/
private boolean isSupportFocus() {
Camera.Parameters parameters = mCamera.getParameters();
if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO)) {
if (parameters.getMaxNumFocusAreas() <= 0) {
return false;
} else {
return true;
}
} else {
return false;
}
}
/**
* 将坐标转换
*/
@Deprecated
private Rect convertArea(int x, int y) {
int newX = (int) ((((float) y) / mViewHeight) * WIDTH - HALF_WIDTH);
int newY = (int) (-((((float) x) / mViewWidth) * HEIGHT)) + HALF_HEIGHT;
int newLeft = newX - MEASURE_WIDTH / 2;
int newTop = newY - MEASURE_WIDTH / 2;
int newRight = newX + MEASURE_WIDTH / 2;
int newBottom = newY + MEASURE_WIDTH / 2;
newLeft = newLeft < LEFT ? LEFT : newLeft;
newTop = newTop < TOP ? TOP : newTop;
newRight = newRight > RIGHT ? RIGHT : newRight;
newBottom = newBottom > BOTTOM ? BOTTOM : newBottom;
YLog.i(TAG, new Rect(newLeft, newTop, newRight, newBottom).toString());
return new Rect(newLeft, newTop, newRight, newBottom);
}
}