此答案适用于 Camera API 1
首先检查您的设备是否支持设置测光区域,使用:
Camera.Parameters params = mCamera.getParameters();
if (params.getMaxNumMeteringAreas() > 0) {
// Supported!
} else {
// Not supported
}
然后,如果支持,Rect
使用您的 ROI(感兴趣区域)创建一个对象。
您需要考虑相机旋转,因为在不同的设备上,相机的方向可能不同。找出相机旋转超出了这个答案的范围,对不起:)
private Rect getRotatedRect(Rect rect, int previewWidth, int previewHeight, int cameraRotation) {
int resultLeft = rect.left;
int resultTop = rect.top;
int resultRight = rect.right;
int resultBottom = rect.bottom;
switch (cameraRotation) {
case 90:
resultLeft = top;
resultTop = previewHeight - right;
resultRight = bottom;
resultBottom = previewHeight - left;
break;
case 180:
resultLeft = previewWidth - right;
resultTop = previewHeight - bottom;
resultRight = previewWidth - left;
resultBottom = previewHeight - top;
break;
case 270:
resultLeft = previewWidth - bottom;
resultTop = left;
resultRight = previewWidth - top;
resultBottom = right;
break;
}
return new Rect(resultLeft, resultTop, resultRight, resultBottom);
}
请注意,相机 API 不使用 X 和 Y 坐标的绝对值,而是使用
从 (-1000, -1000) 到 (1000, 1000) 的坐标。
因此,您必须缩放 Rect 以便 (-1000, -1000) 代表相机的左上角
, (1000, 1000) 代表相机的右下角。
示例:如果您的相机预览尺寸为 800x480,并且您的 ROI 为 Rect(200, 120, 600, 360),
您应该创建一个新的 Rect(-500, -500, 500, 500)。
private Rect getScaledRect(Rect rect, int previewWidth, int previewHeight) {
float widthUnit = previewWidth / 2000f;
float heightUnit = previewHeight / 2000f;
int adjustedLeft = Math.max((int) (rect.left / widthUnit - 1000), -1000);
int adjustedTop = Math.max((int) (rect.top / heightUnit - 1000), -1000);
int adjustedRight = Math.max((int) (rect.right / widthUnit - 1000), -1000);
int adjustedBottom = Math.max((int) (rect.bottom / heightUnit - 1000), -1000);
return new Rect(adjustedLeft, adjustedTop, adjustedRight, adjustedBottom);
}
然后最后将新的 Rect 设置为测光区域。
您可以设置测光区域的权重(int 从 0 到 1000),这决定了您定义的区域对最终曝光计算的影响程度。
总结一下:
Camera.Parameters params = mCamera.getParameters();
if (params.getMaxNumMeteringAreas() > 0) {
// Supported!
// Create rotated Rect
Rect rotatedRect = getRotatedRect(yourAbsoluteCoordinatesROIRect, mPreviewSize.width, mPreviewSize.height, mCameraOrientation);
// Scale Rect to make it appropriate for Camera API
Rect scaledRect = getScaledRect(rotatedRect, mPreviewSize.width, mPreviewSize.height);
// Create metering area with maximum weight
Camera.Area meteringArea = new Camera.Area(scaledRect, 1000);
// Create a list because setMeteringAreas() expects a List
List<Camera.Area> meteringAreaList = new ArrayList<>();
meteringAreaList.add(meteringArea);
// Set metering area
params.setMeteringAreas(meteringAreaList);
mCamera.setParameters(params);
} else {
// Not supported
}