2010-06-04 25 views
9

¿Alguien sabría dónde controlar la configuración ISO para la cámara en el SDK de Android? Debe ser posible ya que la aplicación de cámara nativa en el HTC Desire tiene configuraciones ISO.Android Camera API ISO?

Respuesta

1

Perdone mi ignorancia, pero ¿cómo se diferencia esto de la "compensación de exposición" a través de setExposureCompensation()? Wikipedia tiene algunas de las fórmulas de conversión que pueden serle útiles.

+0

No estoy del todo seguro de si la configuración de exposición lograría los mismos resultados con la configuración iso, podría ser posible. Sin embargo, el deseo es ejecutar 2.1 y setExposureCompensation está disponible para API nivel 8, que es 2.2 Por lo que debe haber otra manera en 2.1 para hacerlo. Gracias por su respuesta – ee3509

15

debería echar un vistazo a los métodos flatten(), unflatten(), get(String key), set(String key, String value) en android.hardware.Camera.Parameters. Considere también el source code of that class. Podría aclarar las cosas.

Primero debe obtener el Camera.Parameters. Desbloquearlo a un String e investigarlo. Estoy desarrollando en un HTC Desire así obtener un String lo siguiente:

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 

Así que básicamente no es una clave llamada iso-values para recuperar los valores admitidos y una clave iso que mantiene el valor actual.

Usted puede hacer lo siguiente:

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

y con referencia a los parámetros sin acoplar quiero suponer que hay una diferencia entre los valores de compensación de la ISO y la exposición.

+0

parameters.get ("iso-values") devuelve NULL en un HTC Desire. ¿Alguna otra idea? – radhoo

+0

@radhoo El deseo debe ser compatible con ISO. Vea mi respuesta a continuación para recuperar una lista de valores ISO válidos (y las palabras clave) de camera.parameters.flatten(). –

4

szias La respuesta es correcta.

Sólo

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

rendimientos nulos en algunos dispositivos.

Sin embargo, puede definir el iso por

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

No sé si "800" o "1600" es compatible con todos los dispositivos

puede comprobar lo que hizo por

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

Como referencia, en mis dos teléfonos (ambos modelos de Samsung), los valores aceptables llevan el prefijo "ISO", y 800 está disponible en uno pero no en ambos, mientras que ninguno admite 1600. – Jules

8

Por ahora (KK 4.4.2) Android no tiene API oficiales para administrar ISO.
La gestión de ISO es un asunto totalmente dependiente del dispositivo, y 8/18 dispositivos que he probado hasta ahora no admiten la configuración de ISO en absoluto.
Investigar Camera.getParameters().flatten() Cadena para comprobar palabras clave válidas, ¡cada dispositivo puede usar palabras clave diferentes!
mayoría de los dispositivos utilizan "iso-valores" palabra clave para definir una coma de lista de posibles valores para usar con "iso" palabra clave, como esto separa:

param.set("iso", valid_value_from_list); 

Algunos otros dispositivos utiliza "modo iso palabras clave "valores" e "iso" (Galaxy Nexus).
Encontré también un dispositivo que usa "iso-speed-values" e "iso-speed" (Micromax A101).
Otro que me entristece es "nv-picture-iso-values" -> "nv-picture-iso" (LG dual P990).

Siga szia respuesta sobre cómo utilizar estas palabras clave.

Aquí hay un código que utilizo para obtener una lista de valores válidos utilizando palabras clave conocidas:

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

No debería iso_keyword ser "modo iso" en lugar de "iso" para google galaxy nexus palabras clave? – Thracian

4

desde que tuve el mismo problema de encontrar si el dispositivo tiene un parámetro ISO Miré a esta respuesta https://stackoverflow.com/a/23567103/3976589 y sierra que @jc había resuelto el problema para 8/18 dispositivos al enumerar algunos parámetros que había encontrado en diferentes dispositivos. Basado en esa lista encontré que cada parámetro contiene las palabras iso y values (a veces solo esas palabras, a veces algo adicional).

Así que si enumero todos los parámetros de la cámara y busco una cadena que contenga ambas palabras, sabré cuál es el nombre del parámetro ISO, si existe. Además, si el parámetro existe puedo tomar los valores admitidos ISO y si deseo establecer uno de esos valores, es decir, cambiar el parámetro de la cámara, simplemente puedo eliminar el -values al final del parámetro iso-values y luego puedo cambiar el valor ISO con éxito .

Ahora compartiré mi código para esta tarea. Primero, un fragmento que recupera una lista con los valores ISO admitidos.

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

Este fragmento sólo enumera los valores soportados ISO. En mi aplicación, necesitaba elegir el ISO más bajo. Aquí está mi solución:

private String getMinISO() { 
    if(ISOValues == null) { 
     return null; 
    } 

    String[] ISOarray = ISOValues.split(","); 
    Arrays.sort(ISOarray, myComparator); 

    String minISO = ISOarray[ISOarray.length-1]; 

    return minISO; 
} 

aquí myComparator es una clase que compara dos cadenas y ordena la matriz en orden descendente. Todas las palabras del alfabeto están al principio y todos los números están al final. Aquí está mi implementación:

// 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; 
} 

} 

Espero que mi respuesta ayude a otras personas. :)

¡Salud! @ ee3509