首先是基于前一篇文章:
https://blog.csdn.net/zhangkai19890929/article/details/88305440
另外聚焦和聚光的理论要参考这篇文章:
https://blog.csdn.net/gh8609123/article/details/67633093
所以要结合2篇文章来看.
所谓自动聚焦,意思很明白,就是让摄像头聚焦在手指触摸的范围内,让这个范围内的图像信息看的更清晰.
所谓自动聚光,就是手机触摸的范围内,光线更充足.
另外,上面的功能,还需要同时支持前置和后置.
关于前置,绝大部分的前置镜头不支持自动聚焦,只支持自动聚光.
point是你自己触摸时候屏幕上的位置坐标信息,在第一篇文章中有介绍.
public void onFocus(Point point,int width ,int height , Camera.AutoFocusCallback callback){
if(mCamera == null) return ;
// Camera.Parameters parameters=mCamera.getParameters();
// Camera.Size previewSize = parameters.getPreviewSize();
//
// if (parameters.getMaxNumFocusAreas() > 0) {
// Log.e(TAG," support auto focus");
// mCamera.cancelAutoFocus();
// List areas=new ArrayList();
// Rect focusRect = calculateTapArea(point.x, point.y, 1.0f, previewSize , width,height);
// areas.add(new Camera.Area(focusRect, 1000));
//// parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
// parameters.setFocusAreas(areas);
// mCamera.autoFocus(callback);
// }
//
// if(parameters.getMaxNumMeteringAreas() > 0)
// {
// Log.e(TAG," support meter areas");
// List areasMetrix=new ArrayList();
// Rect metrixRect = calculateTapArea(point.x, point.y, 1.0f, previewSize , width ,height);
// areasMetrix.add(new Camera.Area(metrixRect,1000));
// parameters.setMeteringAreas(areasMetrix);
// }
//
// //public 模块
// parameters.setAutoWhiteBalanceLock(true);
// parameters.setAutoExposureLock(true);
// try {
// mCamera.setParameters(parameters);
// } catch (Exception e) {
// // TODO: handle exception
// e.printStackTrace();
// }
Rect focusRect = calculateTapArea(point.x, point.y, 1f, width, height);
Rect meteringRect = calculateTapArea(point.x, point.y, 1.5f, width, height);
mCamera.cancelAutoFocus();
Camera.Parameters params = mCamera.getParameters();
final String currentFocusMode = params.getFocusMode();
if(params.getMaxNumFocusAreas() > 0)
{
params.setFocusMode(Camera.Parameters.FOCUS_MODE_MACRO);
List focusAreas = new ArrayList<>();
focusAreas.add(new Camera.Area(focusRect, 800));
params.setFocusAreas(focusAreas);
}
else
{
Log.e(TAG,"camera do not support focus areas ");
}
if (params.getMaxNumMeteringAreas() > 0) {
List meteringAreas = new ArrayList<>();
meteringAreas.add(new Camera.Area(meteringRect, 1000));
params.setMeteringAreas(meteringAreas);
} else {
Log.e(TAG, "metering areas not supported");
}
try {
mCamera.setParameters(params);
}catch (Exception e)
{
Log.e(TAG,"Set params Faild:"+e.getMessage() );
}
mCamera.autoFocus(new Camera.AutoFocusCallback() {
@Override
public void onAutoFocus(boolean success, Camera camera) {
Camera.Parameters params = camera.getParameters();
params.setFocusMode(currentFocusMode);
camera.setParameters(params);
}
});
}
private static Rect calculateTapArea(float x, float y, float coefficient, int width, int height) {
float focusAreaSize = 300;
int areaSize = Float.valueOf(focusAreaSize * coefficient).intValue();
int centerX = (int) (x / width * 2000 - 1000);
int centerY = (int) (y / height * 2000 - 1000);
int halfAreaSize = areaSize / 2;
RectF rectF = new RectF(clamp(centerX - halfAreaSize, -1000, 1000)
, clamp(centerY - halfAreaSize, -1000, 1000)
, clamp(centerX + halfAreaSize, -1000, 1000)
, clamp(centerY + halfAreaSize, -1000, 1000));
Log.e(TAG,"left:" + Math.round(rectF.left) + " -- top:" + Math.round(rectF.top) + " -- right:" + Math.round(rectF.right) + " -- bottom:"+ Math.round(rectF.bottom) );
return new Rect(Math.round(rectF.left), Math.round(rectF.top), Math.round(rectF.right), Math.round(rectF.bottom));
}
private static int clamp(int x, int min, int max) {
if (x > max) {
return max;
}
if (x < min) {
return min;
}
return x;
}