2011-06-19 11 views
15

Estoy intentando leer la distancia de enfoque (distancia del objeto en una foto) de una cámara de Android. Sigo recibiendo 0 para todas las distancias de enfoque en mi HTC Desire, incluso cuando se autoenfoca correctamente. Aquí está toda la aplicación, solo funciona en v2.3.3 y superior.enfoque de la cámara se distancia

ImageCapture.java

package test.test; 

import java.io.IOException; 
import java.io.OutputStream; 
import java.text.SimpleDateFormat; 

import android.app.Activity; 
import android.content.Intent; 
import android.graphics.PixelFormat; 
import android.hardware.Camera; 
import android.hardware.Camera.AutoFocusCallback; 
import android.hardware.Camera.PictureCallback; 
import android.net.Uri; 
import android.os.Bundle; 
import android.provider.MediaStore.Images.Media; 
import android.util.Log; 
import android.view.KeyEvent; 
import android.view.MenuItem; 
import android.view.SurfaceHolder; 
import android.view.SurfaceView; 

//THIS CLASS READS THE FOCUS DISTANCES 
class ImageFocusCallback implements AutoFocusCallback { 
    @Override 
    public void onAutoFocus(boolean success, Camera camera) { 
     //READ FOCUS DISTANCES HERE 
     Camera.Parameters parameters = camera.getParameters(); 
     float[] distances = new float[3]; 
     if (success) { 
      // Only available with Android 9 (2.3) 
      // Focus Mode is always reported as auto but 
      // distances do not appear to be updating 
      // always: 0.1, 1.2, Infinity, (on my device it's 0,0,0) 
      Log.d("Focus Mode: ", parameters.getFocusMode()); 
      parameters.getFocusDistances(distances); 
      Log.d("focus distance near", Float.toString(distances[0])); 
      Log.d("focus distance optimum", Float.toString(distances[1])); 
      Log.d("focus distance far", Float.toString(distances[2])); 
     } 
    } 
} 

public class ImageCapture extends Activity implements SurfaceHolder.Callback { 
    //CALL AUTO FOCUS HERE 
    @Override 
    public boolean onKeyDown(int keyCode, KeyEvent event) { 
     if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 
      ImageFocusCallback autoFocusCallBack = new ImageFocusCallback(); 
      //AUTOFOCUS IS CALLED HERE 
      camera.autoFocus(autoFocusCallBack); 
      return true; 
     } 
     return false; 
    } 

    //REST OF THE CODE 
    private Camera   camera; 
    private boolean   isPreviewRunning = false; 
    private SimpleDateFormat timeStampFormat = new SimpleDateFormat("yyyyMMddHHmmssSS"); 

    private SurfaceView  surfaceView; 
    private SurfaceHolder surfaceHolder; 
    private Uri    target   = Media.EXTERNAL_CONTENT_URI; 


    @Override 
    public void onCreate(Bundle icicle) { 
     super.onCreate(icicle); 
     Log.e(getClass().getSimpleName(), "onCreate"); 
     getWindow().setFormat(PixelFormat.TRANSLUCENT); 
     setContentView(R.layout.main); 
     surfaceView = (SurfaceView) findViewById(R.id.surface); 
     surfaceHolder = surfaceView.getHolder(); 
     surfaceHolder.addCallback(this); 
     surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

    } 

    @Override 
    public boolean onCreateOptionsMenu(android.view.Menu menu) { 
     MenuItem item = menu.add(0, 0, 0, "goto gallery"); 
     item.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() { 
      @Override 
      public boolean onMenuItemClick(MenuItem item) { 
       Intent intent = new Intent(Intent.ACTION_VIEW, target); 
       startActivity(intent); 
       return true; 
      } 
     }); 
     return true; 
    } 

    @Override 
    protected void onRestoreInstanceState(Bundle savedInstanceState) { 
     super.onRestoreInstanceState(savedInstanceState); 
    } 

    Camera.PictureCallback mPictureCallbackRaw = new Camera.PictureCallback() { 
                @Override 
                public void onPictureTaken(byte[] data, Camera c) { 
                 Log.e(getClass().getSimpleName(), "PICTURE CALLBACK RAW: " + data); 
                 camera.startPreview(); 
                } 
               }; 

    Camera.PictureCallback mPictureCallbackJpeg = new Camera.PictureCallback() { 
                @Override 
                public void onPictureTaken(byte[] data, Camera c) { 
                 Log.e(getClass().getSimpleName(), "PICTURE CALLBACK JPEG: data.length = " + data); 
                } 
               }; 

    Camera.ShutterCallback mShutterCallback  = new Camera.ShutterCallback() { 
                @Override 
                public void onShutter() { 
                 Log.e(getClass().getSimpleName(), "SHUTTER CALLBACK"); 
                } 
               }; 




    // ImageCaptureCallback iccb = null; 
    // if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 
    // try { 
    // String filename = timeStampFormat.format(new Date()); 
    // ContentValues values = new ContentValues(); 
    // values.put(Media.TITLE, filename); 
    // values.put(Media.DESCRIPTION, "Image capture by camera"); 
    // Uri uri = getContentResolver().insert(Media.EXTERNAL_CONTENT_URI, 
    // values); 
    // // String filename = timeStampFormat.format(new Date()); 
    // iccb = new 
    // ImageCaptureCallback(getContentResolver().openOutputStream(uri)); 
    // } catch (Exception ex) { 
    // ex.printStackTrace(); 
    // Log.e(getClass().getSimpleName(), ex.getMessage(), ex); 
    // } 
    // } 
    // if (keyCode == KeyEvent.KEYCODE_BACK) { 
    // return super.onKeyDown(keyCode, event); 
    // } 
    // 
    // if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) { 
    // camera.takePicture(mShutterCallback, mPictureCallbackRaw, iccb); 
    // return true; 
    // } 
    // 
    // return false; 
    // } 

    @Override 
    protected void onResume() { 
     Log.e(getClass().getSimpleName(), "onResume"); 
     super.onResume(); 
    } 

    @Override 
    protected void onSaveInstanceState(Bundle outState) { 
     super.onSaveInstanceState(outState); 
    } 

    @Override 
    protected void onStop() { 
     Log.e(getClass().getSimpleName(), "onStop"); 
     super.onStop(); 
    } 

    @Override 
    public void surfaceCreated(SurfaceHolder holder) { 
     Log.e(getClass().getSimpleName(), "surfaceCreated"); 
     camera = Camera.open(); 
     Camera.Parameters parameters = camera.getParameters(); 
     float[] distances = new float[3]; 
     Log.d("Focus Mode: ", parameters.getFocusMode()); 
     parameters.getFocusDistances(distances); 
     Log.d("focus distance 0", Float.toString(distances[0])); 
     Log.d("focus distance 1", Float.toString(distances[1])); 
     Log.d("focus distance 2", Float.toString(distances[2])); 
    } 

    @Override 
    public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { 
     Log.e(getClass().getSimpleName(), "surfaceChanged"); 
     if (isPreviewRunning) { 
      camera.stopPreview(); 
     } 
     Camera.Parameters p = camera.getParameters(); 
     p.setPreviewSize(w, h); 
     camera.setParameters(p); 
     try { 
      camera.setPreviewDisplay(holder); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     camera.startPreview(); 
     isPreviewRunning = true; 
    } 

    @Override 
    public void surfaceDestroyed(SurfaceHolder holder) { 
     Log.e(getClass().getSimpleName(), "surfaceDestroyed"); 
     camera.stopPreview(); 
     isPreviewRunning = false; 
     camera.release(); 
    } 

} 



class ImageCaptureCallback implements PictureCallback { 

    private OutputStream filoutputStream; 

    public ImageCaptureCallback(OutputStream filoutputStream) { 
     this.filoutputStream = filoutputStream; 
    } 

    @Override 
    public void onPictureTaken(byte[] data, Camera camera) { 
     try { 
      Log.v(getClass().getSimpleName(), "onPictureTaken=" + data + " length = " + data.length); 
      filoutputStream.write(data); 
      filoutputStream.flush(); 
      filoutputStream.close(); 
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
    } 

} 
} 

main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="fill_parent" 
    android:layout_height="fill_parent" 
    android:orientation="vertical"> 
    <SurfaceView android:id="@+id/surface" 
    android:layout_width="fill_parent" 
     android:layout_height="10dip" 
     android:layout_weight="1"> 
    </SurfaceView> 
</LinearLayout> 

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
     package="test.test" 
     android:versionCode="1" 
     android:versionName="1.0"> 
    <uses-sdk android:minSdkVersion="10" /> 
    <uses-permission android:name="android.permission.CAMERA" /> 
    <uses-feature android:name="android.hardware.camera" /> 
<uses-feature android:name="android.hardware.camera.autofocus" /> 

    <application android:icon="@drawable/icon" android:label="@string/app_name"> 
     <activity android:name=".ImageCapture" 
        android:label="@string/app_name"> 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 
       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 

    </application> 
</manifest> 

Podría ser que que hay un error en el controlador de dispositivo? En la fuente de Android Camera.java, llama a native_autoFocus() y native_getParameters() para leer las distancias. ¿Alguien sabe dónde obtener la fuente para las llamadas nativas?

Respuesta

0

Probablemente es un error en el controlador de la cámara, solo puede solucionarlo si vuelve a configurar su teléfono, sí, lo sé realmente de mierda, pero también tuve el mismo problema.

Pero Elegí usar una ROM personalizada para mi dispositivo. Atm im utilizando Android Revolution HD 6.1.1 http://forum.xda-developers.com/showthread.php?t=840040

Para su segunda pregunta Puede sacar el archivo fuente de la aplicación de la cámara del paquete que descargue con la rom. Probablemente si lo cambias, funcionará.

Best Regards

2

En Froyo, marcos/base/core/jni/android_hardware_Camera.cpp implementa native_autoFocus() llamando android_hardware_Camera_autoFocus(), que parece unirse en tiempo de ejecución para el código específico de dispositivo/proveedor.

Desafortunadamente, "Si la cámara no admite el enfoque automático y se invoca el enfoque automático, se llamará automáticamente a AutoFocus con un valor falso de éxito establecido en verdadero". es un documented behavior.

Tengo curiosidad por cuál de las funciones que utiliza requiere 2.3.3, el nivel de API 10.

+0

la parte problemática es getFocusDistances(). autoFocus() funciona bien. – siamii

+0

Podría probar el programa en un par de dispositivos Froyo, pero llama explícitamente a 2.3.3/Gingerbread. ¿Qué llamadas que usa en realidad necesitan eso? –

0

No sé donde se puede obtener la fuente de las llamadas nativas. Pero ¿qué hay de conseguir 0 para todas las distancias focales en getFocusDistances (float []) método, se puede leer this issue. Allí puede leer que este error no es el error del dispositivo sino del SDK de Android.

0

Ésta es Bug 14341 - "Las distancias devueltas por Camera.Parameters.getFocusDistances() no cambian en Nexus S independientemente de la distancia de enfoque real".

Primera reportaron 26 Ene, 2011 con el último informe, el mar 18, 2014. Por lo tanto, se informó del fallo poco antes de ejecutar en él y no se ha fijado para el día de hoy. Se informa específicamente contra su dispositivo.

varios comentarios en la reclamación informe de este error afecta a la "Nexus S", "HTC Sensation", "Galaxy S Plus", "Galaxy S II", "HTC Desire HD", "Galaxy Nexus", " Xperia Mini ST15i "," Nexus 5 "," Galaxy R "y" Galaxy Note II "; con un comentario que dice que funciona perfectamente en el "Galaxy Nexus".

Referencia: https://code.google.com/p/android/issues/detail?id=14341.

es éste el código fuente que estás buscando: https://android.googlesource.com/platform/frameworks/base/+/froyo-release/core/jni/android_hardware_Camera.cpp

Cuestiones relacionadas