首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >安卓相机应用: Spot Metering

安卓相机应用: Spot Metering
EN

Stack Overflow用户
提问于 2013-06-27 01:02:07
回答 3查看 3.1K关注 0票数 3

我正在尝试使用android手机实现Spot Metering。Parameters.set(“自动曝光”,“光点测量”);

然而,我对计量是如何工作的感到有点困惑。如果我理解正确,Spot Metering是通过选择一个区域来设置曝光值的。

但是,在展平Camera.Parameters类并显示结果时,测光面积为(0,0,0,0,0),这意味着它的宽度、高度和重量为零,而自动曝光设置为正确的“点测光”。然而,在API中,"getMeteringAreas()“文档规定计量区域的宽度和高度不能为零。

那么,当测量区域大小为0时,我如何使用“点测量”呢?我试着将测光区设置在右上角,但对曝光没有任何影响。

这让我相信自动曝光=光斑测量与测量areas....which没有任何关系是很奇怪的。

如果不是这样的话,有没有人能帮我弄明白我做错了什么?如果您需要更多信息,我很乐意提供代码。

如果是这样的话(例如,测光区与光点测量没有任何关系),有人能帮我找出如何选择自动曝光测量仪的光点吗?我想它默认为居中。

谢谢!

EN

回答 3

Stack Overflow用户

发布于 2014-06-09 09:00:30

MeteringAreas参数用于自动对焦计量。

没有用于曝光测量模式的Android api。您需要找到正确的未记录的参数名称和值来设置它(例如,通过native_getParameters转储所有参数)。

例如,三星Galaxy Note3的参数名称为metering,可接受的值为centermatrixspot。所以你只需调用set("metering", "spot");,它就会神奇地工作。

票数 2
EN

Stack Overflow用户

发布于 2014-05-09 07:32:27

计量是一个与设备相关的问题。

在API level 14之前,没有用于管理计量的标准API,我认为一些品牌选择了自己的方式来管理它(在您的案例中:"auto-exposure“关键字),但不是通过标准API。这就是您无法获取有效区域的原因。parameters.flatten()中的计量区域(0,0,0,0,0)表示不支持计量区域(weight=0),我猜getMaxNumMeteringAreas()返回0:

应用程序应该首先调用getMaxNumMeteringAreas()来知道计量区域的最大数量。如果值为0,则不支持计量面积。

到目前为止,很少有设备支持计量区域(在我的经验中是3/20)。

票数 1
EN

Stack Overflow用户

发布于 2019-04-16 23:17:09

此答案适用于Camera API 1

首先,使用以下命令检查您的设备是否支持设置计量区域:

代码语言:javascript
运行
复制
Camera.Parameters params = mCamera.getParameters();
if (params.getMaxNumMeteringAreas() > 0) {
    // Supported!
} else {
    // Not supported
}

然后,如果支持,使用您的感兴趣区域(感兴趣区域)创建一个Rect对象。

您需要考虑相机旋转,因为在不同的设备上相机可能会有不同的方向。找出摄像机旋转超出了此答案的范围,很抱歉:)

代码语言:javascript
运行
复制
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);
}

请注意,不是对X和Y坐标使用绝对值,

camera API使用(-1000,-1000)到(1000,1000)之间的坐标。

所以你必须缩放你的Rect,使(-1000,-1000)代表左上角

和(1000,1000)表示相机的右下角。

示例:如果相机预览大小为800x480,ROI为Rect(200,120,600,360),

您应该创建一个新的Rect(-500,-500,500,500)。

代码语言:javascript
运行
复制
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),它决定了您定义的区域对最终曝光计算的影响程度。

总结一下:

代码语言:javascript
运行
复制
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
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17326221

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档