2011-06-19 1 views
15

J'essaie de lire la distance de mise au point (distance du sujet dans une photo) d'un appareil photo Android. Je continue à obtenir 0 pour toutes les distances de mise au point sur mon HTC Desire même quand il se autofocus correctement. Voici l'application entière, ne fonctionne que sur les versions 2.3.3 et supérieures.Distances de mise au point de l'appareil photo

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> 

Se pourrait-il que qu'il ya un bogue dans le pilote de périphérique? Dans la source Android Camera.java, appelez native_autoFocus() et native_getParameters() pour lire les distances. Est-ce que quelqu'un sait où trouver la source pour les appels natifs?

Répondre

0

Probablement un bug dans le pilote de l'appareil photo, vous ne pouvez résoudre ce problème si vous configurez votre téléphone à nouveau, oui je sais que c'est vraiment merdique, mais j'ai eu exactement le même problème.

Mais j'ai choisi d'utiliser une ROM personnalisée pour mon appareil. Utilisation de la version Android Revolution HD 6.1.1 http://forum.xda-developers.com/showthread.php?t=840040

Pour votre question Vous pouvez extraire le fichier source de l'application Appareil photo du package que vous téléchargez avec la ROM. Probablement si vous le changez, cela fonctionnera.

Best Regards

2

Dans Froyo, les cadres/base/core/jni/android_hardware_Camera.cpp implémente native_autoFocus() en appelant android_hardware_Camera_autoFocus(), qui semble se lier à l'exécution de l'appareil/fournisseur code spécifique. Malheureusement, "Si la caméra ne prend pas en charge la mise au point automatique et l'autofocus est appelée, onAutoFocus sera appelée immédiatement avec une fausse valeur de succès définie sur" true "." est un documented behavior.

Je suis curieuse des fonctions que vous utilisez nécessite 2.3.3, niveau de l'API 10.

+0

la partie problématique est getFocusDistances(). AutoFocus() fonctionne correctement. – siamii

+0

Je pourrais essayer le programme sur quelques appareils Froyo, mais vous appelez explicitement 2.3.3/Gingerbread. Quels appels que vous utilisez en ont réellement besoin? –

0

Je ne sais pas où vous pouvez obtenir la source pour les appels natifs. Mais qu'en est-il de l'obtention de 0 pour toutes les distances de mise au point dans la méthode getFocusDistances (float []), vous pouvez lire this issue. Là, vous pouvez lire que cette erreur n'est pas l'erreur de l'appareil mais du SDK Android.

0

Ceci est le bogue 14341 - "Les distances retournées par Camera.Parameters.getFocusDistances() ne changent pas sur le Nexus S quelle que soit la distance de mise au point réelle".

Premier signalé le 26 janvier 2011 avec le dernier rapport du 18 mars 2014. Ainsi, le Bug a été signalé peu de temps avant que vous ne l'ayez rencontré et qu'il n'ait pas été corrigé à ce jour. Il est spécifiquement signalé contre votre appareil.

divers commentaires dans la demande de rapporter ce bogue affecte le "Nexus S", "HTC Sensation", "Galaxy S Plus", "Galaxy S II", "HTC Desire HD", "Galaxy Nexus", " Xperia Mini ST15i "," Nexus 5 "," Galaxy R "et" Galaxy Note II "; avec un commentaire affirmant qu'il fonctionne parfaitement sur le "Galaxy Nexus".

Référence: https://code.google.com/p/android/issues/detail?id=14341.

Est-ce le code source que vous recherchez: https://android.googlesource.com/platform/frameworks/base/+/froyo-release/core/jni/android_hardware_Camera.cpp