【问题标题】:Android Camera API ISO Setting?Android相机API ISO设置?
【发布时间】:2011-02-28 00:24:52
【问题描述】:

有人知道在 Android SDK 中从哪里控制相机的 ISO 设置吗? 这应该是可能的,因为 HTC Desire 上的本机相机应用程序具有 ISO 设置。

【问题讨论】:

    标签: android camera iso


    【解决方案1】:

    原谅我的无知,但这与通过 setExposureCompensation() 设置的“曝光补偿”有何不同? Wikipedia 有一些您可能会觉得有用的转换公式。

    【讨论】:

    • 我不完全确定曝光设置是否会与 iso 设置达到相同的结果,这是可能的。然而,愿望正在运行 2.1,并且 setExposureCompensation 可用于 API 级别 8,即 2.2,因此 2.1 中必须有另一种方法来做到这一点。感谢您的回答
    • ISO 是传感器灵敏度,曝光是图像曝光的时间。通常,较长的曝光会导致照片更模糊但更亮,而高 ISO 值会导致照片更亮但颗粒感更强。
    【解决方案2】:

    您应该看看android.hardware.Camera.Parameters 中的方法flatten()unflatten()get(String key)set(String key, String value)。 还要考虑source code of that class。它可能会让事情变得更清楚。

    首先您需要获取Camera.Parameters。将其展开为String 并对其进行调查。我正在开发 HTC Desire 并获得以下String

    sharpness-max=30;zoom=0;taking-picture-zoom=0;zoom-supported=true;sharpness-min=0;sharpness=10;contrast=5;whitebalance=auto;jpeg-quality=100;preview-format-values=yuv420sp;jpeg-thumbnail-quality=75;preview-format=yuv420sp;preview-size=640x480;focal-length=3.53;iso=auto;meter-mode=meter-center;front-camera-mode=mirror;flash-mode-values=off,auto,on,torch;preview-frame-rate-values=15;preview-frame-rate=15;focus-mode-values=auto,infinity;jpeg-thumbnail-width=640;jpeg-thumbnail-size-values=640x480,512x384,384x288,0x0;zoom-ratios=100,114,131,151,174,200;saturation-def=5;preview-size-values=1280x720,800x480,768x432,720x480,640x480,576x432,480x320,400x240,384x288,352x288,320x240,272x272,240x240,240x160,176x144,160x120;smart-contrast=off;picture-size-values=2592x1952,2592x1456,2592x1936,2592x1728,2592x1552,2048x1536,2048x1360,2048x1216,2048x1152,1600x1200,1584x1056,1280x960,1280x848,1280x768,1280x720,1024x768,640x480,640x416,640x384,640x368,512x384,400x400,272x272;contrast-min=0;min-exposure-compensation=-4;brightness-min=0;antibanding=auto;taking-picture-zoom-min=0;saturation-min=1;contrast-max=10;vertical-view-angle=42.5;taking-picture-zoom-max=21;contrast-def=5;brightness-max=6;horizontal-view-angle=54.8;brightness=3;jpeg-thumbnail-height=480;cam-mode=0;focus-mode=auto;sharpness-def=10;front-camera-mode-values=mirror,reverse;picture-format-values=jpeg;saturation-max=10;max-exposure-compensation=4;exposure-compensation=0;exposure-compensation-step=0.5;flash-mode=off;effect-values=none,mono,negative,solarize,sepia,posterize,aqua;meter-mode-values=meter-average,meter-center,meter-spot;picture-size=2592x1952;max-zoom=5;effect=none;saturation=5;whitebalance-values=auto,incandescent,fluorescent,daylight,cloudy-daylight;picture-format=jpeg;brightness-def=3;iso-values=auto,deblur,100,200,400,800,1250;enable-caf=off;antibanding-values=off,50hz,60hz,auto
    

    所以基本上有一个名为iso-values 的键来检索支持的值,还有一个键iso 保存当前值。

    您可以执行以下操作:

    Camera cam = Camera.open();
    Camera.Parameters camParams = cam.getParameters();
    String supportedIsoValues = camParams.get("iso-values"); //supported values, comma separated String
    camParams.set("iso", (String)newValue);
    cam.setParameters(camParams);
    

    关于未展平的参数,我假设 ISO 和曝光补偿设置之间存在差异。

    【讨论】:

    • parameters.get("iso-values") 在 HTC Desire 上返回 NULL。还有其他想法吗?
    • @radhoo Desire 应该支持 ISO。请参阅下面的答案以从 camera.parameters.flatten() 检索有效 ISO 值(和关键字)的列表。
    【解决方案3】:

    szias 的答案是正确的。

    只有

    String supportedIsoValues = camParams.get("iso-values"); 
    

    在某些设备上返回 null。

    不过你可以通过设置iso

    Camera cam = Camera.open();
    Camera.Parameters camParams = cam.getParameters();
    camParams.set("iso", "400"); // values can be "auto", "100", "200", "400", "800", "1600"
    cam.setParameters(camParams);
    

    我不知道是否所有设备都支持“800”或“1600”

    你可以通过

    检查你做了什么
    String newVAlue = camParams.get("iso");
    

    【讨论】:

    • 作为参考,在我的两部手机(均为三星型号)上,可接受的值都以“ISO”为前缀,其中一部可以使用 800,但两者都不支持 1600。
    【解决方案4】:

    到目前为止 (KK 4.4.2) android 没有官方 API 来管理 ISO。
    ISO 管理完全依赖于设备,到目前为止我测试的 8/18 设备根本不支持 ISO 设置。
    Camera.getParameters().flatten()字符串检查有效关键字,每个设备可以使用不同的关键字!!
    大多数设备使用“iso-values”关键字来定义一个逗号分隔的可能值列表,以便与“iso”关键字一起使用,如下所示:

    param.set("iso", valid_value_from_list);
    

    其他一些设备使用“iso-mode-values”和“iso”关键字(Galaxy Nexus)。
    我还发现了一个使用“iso-speed-values”和“iso-speed”的设备(Micromax A101)。
    另一个让我难过的是“nv-picture-iso-values”->“nv-picture-iso”(LG dual P990)。

    请关注szia 回答,了解如何使用这些关键字。

    下面是一些代码,我使用已知关键字获取有效值列表:

    String flat = param.flatten();
    String[] isoValues = null;
    String values_keyword=null;
    String iso_keyword=null;
    if(flat.contains("iso-values")) {
        // most used keywords
        values_keyword="iso-values";
        iso_keyword="iso";
    } else if(flat.contains("iso-mode-values")) {
        // google galaxy nexus keywords
        values_keyword="iso-mode-values";
        iso_keyword="iso";
    } else if(flat.contains("iso-speed-values")) {
        // micromax a101 keywords
        values_keyword="iso-speed-values";
        iso_keyword="iso-speed";
    } else if(flat.contains("nv-picture-iso-values")) {
        // LG dual p990 keywords
        values_keyword="nv-picture-iso-values";
        iso_keyword="nv-picture-iso";
    }
    // add other eventual keywords here...
    if(iso_keyword!=null) {
        // flatten contains the iso key!!
        String iso = flat.substring(flat.indexOf(values_keyword));
        iso = iso.substring(iso.indexOf("=")+1);
    
        if(iso.contains(";")) iso = iso.substring(0, iso.indexOf(";"));
    
        isoValues = iso.split(",");
    
    } else {
        // iso not supported in a known way
    }
    

    【讨论】:

    • 对于 google galaxy nexus 关键字,iso_keyword 不应该是“iso-mode”而不是“iso”吗?
    【解决方案5】:

    因为我在查找设备是否具有ISO 参数时遇到了同样的问题,所以我查看了这个答案https://stackoverflow.com/a/23567103/3976589 并看到@jc 通过列出他找到的一些参数解决了 8/18 设备的问题在不同的设备上。根据该清单,我发现每个参数都包含 isovalues 两个词(有时只有这些词,有时是其他词)。

    因此,如果我列出所有相机参数并搜索包含两个单词的字符串,我将知道ISO 参数的名称(如果存在)。此外,如果参数存在,我可以采用支持的ISO 值,如果我想设置其中一个值,即更改相机参数,我可以删除iso-values 参数末尾的-values,然后我可以成功更改ISO的值。

    我现在将分享我的代码来完成这项任务。首先是一个 sn-p,它检索具有支持的 ISO 值的列表。

        private String ISOValuesParameter = null;
        private String ISOParameter = null;
        private String ISOValues = null;
    
    
        private void initCamera() {
            Camera mCamera = Camera.open();
    
            // this will list supported values
            String ISOvalues = getISOValues(); 
            textViewISO = (TextView) findViewById(R.id.viewISO);
            textViewISO.setText(ISOvalues);
    
        // setting Minimum ISO value
        if(ISOValuesParameter != null) {
            Camera.Parameters params = mCamera.getParameters();
    
            ISOParameter = ISOValuesParameter.replace("-values", "");
            params.set(ISOParameter, getMinISO());
    
            mCamera.setParameters(params);
    
            // get the updated ISO value
            params = mCamera.getParameters();
    
            String ISO = params.get(ISOParameter);
    
            Toast.makeText(this,"ISO set to: " + ISO, Toast.LENGTH_SHORT).show();
        }
    
        }
    
        // returns a list with supported ISO values
        private String getISOValues() {
                ISOValuesParamter = getISOValuesParameter();
                Camera.Parameters params = mCamera.getParameters();
                ISOValues = params.get(ISOValuesParamter);
    
                return ISOValues!=null ? ISOValues : "ISO not supported";
        }
    
        // this will return the name of the ISO parameter containing supported ISO values
        private String getISOValuesParameter() {
                Camera.Parameters params = mCamera.getParameters();
    
                String flatten = params.flatten();
                String[] paramsSeparated = flatten.split(";");
                for(String cur : paramsSeparated) {
                    if(cur.contains("iso") && cur.contains("values")) {
                        return cur.substring(0,cur.indexOf('='));
                    }
                }
    
                return null;
        }
    

    此 sn-p 仅列出支持的 ISO 值。在我的应用程序中,我需要选择最低的 ISO。这是我的解决方案:

    private String getMinISO() {
        if(ISOValues == null) {
            return null;
        }
    
        String[] ISOarray = ISOValues.split(",");
        Arrays.sort(ISOarray, myComparator);
    
        String minISO = ISOarray[ISOarray.length-1];
    
        return minISO;
    }
    

    这里myComparator是一个比较两个字符串并按降序对数组进行排序的类。所有字母单词都在开头,所有数字都在结尾。这是我的实现:

    // Singelton class
    public class MyComparator implements  Comparator<String> {
    
    private static MyComparator myComparator = null;
    
    private MyComparator() {}
    
    @Override
    public int compare(String a, String b) {
        return compareString(a,b);
    }
    
    public static int compareString(String a, String b) {
        if (a.length() > b.length())
            return -1;
        if (a.length() == b.length()) {
            if (a.compareTo(b) > 0)
                return -1;
            else if (a.compareTo(b) == 0)
                return 0;
        }
    
        return 1;
    }
    
    public static synchronized MyComparator getInstance() {
        if(myComparator==null) {
            myComparator = new MyComparator();
        }
    
        return myComparator;
    }
    
    }
    

    我希望我的回答对其他人有所帮助。 :)

    干杯! @ee3509

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-04-02
      • 2023-03-11
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 2021-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多