2010-06-04 131 views
9

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

回答

1

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

+0

我不完全确定曝光设置是否可以通过iso设置获得相同的结果,这可能是可能的。 然而,愿望正在运行2.1并且setExposureCompensation可用于API级别8,即2.2 因此,在2.1中必须有另一种方式来实现它。 感谢您的回答 – ee3509 2010-06-04 23:20:59

15

你应该看看flatten(),unflatten(),get(String key),set(String key, String value),android.hardware.Camera.Parameters的方法。 另请考虑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和曝光补偿设置之间的差异。

+0

parameters.get(“iso-values”)在HTC Desire上返回NULL。任何其他想法? – radhoo 2011-10-05 11:22:22

+0

@radhoo欲望应该支持ISO。请参阅下面的答案以从camera.parameters.flatten()中检索有效的ISO值(以及关键字)列表。 – 2014-05-09 14:38:56

4

szias答案是正确的。

只有

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

回报在某些设备上无效。

不过您可以通过

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); 

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

你可以检查你没有通过

String newVAlue = camParams.get("iso"); 
什么
+0

作为参考,在我的两部手机(均为三星型号)上,可接受的值以“ISO”为前缀,800可用于其中一个,但不能同时支持1600. – Jules 2014-02-28 15:19:45

8

现在(KK 4.4.2)android没有管理ISO的官方API。
ISO管理是一个完全依赖于设备的问题,目前为止我测试的8/18设备根本不支持ISO设置。
调查Camera.getParameters().flatten()字符串检查有效的关键字,每个设备可以使用不同的关键字!
大多数设备使用“异值”关键字来定义以逗号分隔的列表的-可能值用“异”,以使用关键字,像这样:

param.set("iso", valid_value_from_list); 

其他一些设备使用“异模式值“和”iso“关键字(Galaxy Nexus)。
我还发现使用“等速值”和“等速”(Micromax A101)的设备。
另一个令我伤心的是“nv-picture-iso-values” - >“nv-picture-iso”(LG双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 
} 
+0

不应将iso_keyword设置为“iso-mode”谷歌星系nexus关键字的“iso”? – Thracian 2017-06-21 06:39:09

4

因为我已经发现的同样的问题,如果设备有一个ISO参数我看着这个答案https://stackoverflow.com/a/23567103/3976589和锯@jc通过列出他在不同设备上找到的一些参数,解决了8/18设备的问题。根据该清单,我发现每个参数都包含isovalues这两个字(有时只是这些字,有时候还有一些额外的)。

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

我现在将分享我的代码以完成此任务。首先检索一个支持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; 
    } 

此代码段仅列出了支持的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