有谁知道在 Android SDK 中从哪里控制相机的 ISO 设置?这应该是可能的,因为 HTC Desire 上的本机相机应用程序具有 ISO 设置。
5 回答
你应该看看方法flatten()
, unflatten()
, get(String key)
, set(String key, String value)
in android.hardware.Camera.Parameters
。还要考虑该类的源代码。它可能会让事情变得更清楚。
首先,您需要获得Camera.Parameters
. 将其展开为 aString
并对其进行调查。我正在开发 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 和曝光补偿设置之间存在差异。
By now (KK 4.4.2) android has no official APIs to manage ISO.
ISO management is a totally device dependant matter, and 8/18 devices i tested so far doesn't support ISO settings at all.
Investigate Camera.getParameters().flatten()
String to check valid keywords, every device can use different keywords!!
Most devices use "iso-values" keyword to define a comma separated list-of-possible-values to use with "iso" keyword, like this:
param.set("iso", valid_value_from_list);
Some other devices uses "iso-mode-values" and "iso" keywords (Galaxy Nexus).
I found also a device that uses "iso-speed-values" and "iso-speed" (Micromax A101).
Another one that make me sad is "nv-picture-iso-values" -> "nv-picture-iso" (LG dual P990).
Follow szia answer on how to use these keywords.
Here's some code i use to get a list of valid values using known keywords:
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
}
因为我在查找设备是否有ISO
参数时遇到了同样的问题,所以我查看了这个答案https://stackoverflow.com/a/23567103/3976589并看到@jc 通过列出一些参数解决了 8/18 设备的问题他在不同的设备上发现的。根据该清单,我发现每个参数都包含单词iso
and values
(有时只有这些单词,有时是附加的)。
因此,如果我列出所有相机参数并搜索包含两个单词的字符串,我将知道ISO
参数的名称是什么(如果存在)。此外,如果参数存在,我可以采用支持的ISO
值,如果我想设置其中一个值,即更改相机参数,我可以删除参数-values
末尾的iso-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
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");
请原谅我的无知,但这与通过 setExposureCompensation() 设置的“曝光补偿”有何不同? 维基百科有一些您可能会觉得有用的转换公式。