2011-06-19 91 views
15

我正嘗試從Android相機讀取焦距(照片中拍攝對象的距離)。即使正確自動聚焦,我仍然在HTC Desire上獲得所有焦距的0。這是整個應用程序,只適用於v2.3.3及以上版本。相機焦距

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> 

難道說,有在設備驅動程序中的錯誤?在Android源代碼Camera.java中調用native_autoFocus()和native_getParameters()來讀取距離。有誰知道在哪裏獲得本地電話的來源?

回答

0

可能它是攝像頭驅動程序中的一個錯誤,如果您再次設置了手機,只能修復此問題,是的,我知道它確實很糟糕,但我也有同樣的問題。

但我選擇使用自定義ROM爲我的設備。使用Android Revolution HD的Atm im 6.1.1 http://forum.xda-developers.com/showthread.php?t=840040

對於您的secound問題,您可以從使用ROM下載的軟件包中取出相機應用程序的源文件。可能如果你改變它,它會起作用。

此致

2

在Froyo的,框架/鹼/核心/ JNI/android_hardware_Camera.cpp實現native_autoFocus()通過調用android_hardware_Camera_autoFocus(),這似乎在運行時綁定到設備/供應商的特定代碼。

不幸的是,「如果相機不支持自動對焦並且調用了自動對焦,則會立即調用onFocusFocus,同時將成功的假值設置爲真。是documented behavior

我很好奇它的使用功能要求2.3.3,API等級10

+0

有問題的部分是getFocusDistances()。 autoFocus()工作正常。 – siamii

+0

我可以在一些Froyo設備上嘗試該程序,但您明確要求使用2.3.3 /薑餅。你使用哪種呼叫實際上需要這些? –

0

我不知道在哪裏可以得到本地呼叫的來源。但是getFocusDistances(float [])方法中的所有焦點距離都爲0,那麼讀取this issue即可。在那裏你可以看到這個錯誤不是設備的錯誤,而是Android SDK的錯誤。

0

這是錯誤14341 - 「無論實際焦距如何,Camera.Parameters.getFocusDistances()返回的距離都不會在Nexus S上更改」。

第一次報告2011年1月26日,最後一次報告在2014年3月18日。因此,在遇到Bug之前不久就報告了Bug,並且尚未修復至今。它是專門針對您的設備報告的。

報告要求這個Bug影響 「的Nexus S」 的各種評論, 「HTC迷情」, 「Galaxy S的升級」, 「GALAXY S II」, 「HTC Desire HD的」, 「Galaxy Nexus的」,「 Xperia Mini ST15i「,」Nexus 5「,」Galaxy R「和」Galaxy Note II「;有一條評論聲稱它完美地適用於「Galaxy Nexus」。

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

這是你的源代碼中尋找:https://android.googlesource.com/platform/frameworks/base/+/froyo-release/core/jni/android_hardware_Camera.cpp