2011-06-19 52 views
15

Tôi đang cố gắng đọc khoảng cách lấy nét (khoảng cách chủ thể trong ảnh) từ máy ảnh Android. Tôi tiếp tục nhận được 0 cho tất cả các khoảng cách lấy nét trên HTC Desire của tôi ngay cả khi nó tự động lấy nét chính xác. Đây là toàn bộ ứng dụng, chỉ hoạt động trên phiên bản v2.3.3 trở lên.Khoảng cách lấy nét của máy ảnh

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> 

Nó có thể được rằng có một lỗi trong trình điều khiển thiết bị? Trong nguồn Android, hãy gọi hàm native.jautoFocus() và native_getParameters() để đọc khoảng cách. Có ai biết nơi để có được nguồn cho các cuộc gọi bản địa?

Trả lời

0

Có lẽ đó là lỗi trong trình điều khiển máy ảnh, bạn chỉ có thể sửa lỗi này nếu bạn thiết lập lại điện thoại, vâng tôi biết nó thực sự tồi tệ, nhưng tôi cũng gặp vấn đề tương tự.

Nhưng tôi đã chọn sử dụng rom tùy chỉnh cho thiết bị của mình. Atm im sử dụng Android Revolution HD 6.1.1 http://forum.xda-developers.com/showthread.php?t=840040

Câu hỏi bảo mật của bạn có thể lấy tệp nguồn cho ứng dụng máy ảnh từ gói bạn tải xuống bằng rom. Có lẽ nếu bạn thay đổi nó, nó sẽ hoạt động.

Trân trọng

2

Trong Froyo, khung/cơ sở/lõi/JNI/android_hardware_Camera.cpp thực hiện native_autoFocus() bằng cách gọi android_hardware_Camera_autoFocus(), sẽ xuất hiện để ràng buộc trong thời gian chạy vào mã cụ thể thiết bị/nhà cung cấp.

Thật không may, "Nếu máy ảnh không hỗ trợ lấy nét tự động và tự động lấy nét được gọi, onAutoFocus sẽ được gọi ngay lập tức với giá trị thành công giả được đặt thành true". là documented behavior.

tôi tò mò mà các chức năng bạn sử dụng đòi hỏi 2.3.3, mức API 10

+0

phần có vấn đề là getFocusDistances(). autoFocus() hoạt động tốt. – siamii

+0

Tôi có thể thử chương trình trên một vài thiết bị Froyo, nhưng bạn gọi rõ ràng cho 2.3.3/Gingerbread. Những cuộc gọi mà bạn sử dụng thực sự cần điều đó? –

0

tôi không biết nơi bạn có thể lấy nguồn cho các cuộc gọi mẹ đẻ. Nhưng những gì về việc lấy 0 cho tất cả các khoảng cách lấy nét trong phương thức getFocusDistances (float []), bạn có thể đọc this issue. Ở đó bạn có thể đọc rằng lỗi này không phải là lỗi của thiết bị mà là của Android SDK.

0

Đây là lỗi 14341 - "Khoảng cách được trả về bởi Camera.Parameters.getFocusDistances() không thay đổi trên Nexus S bất kể khoảng cách lấy nét thực tế".

Báo cáo lần đầu vào ngày 26 tháng 1 năm 2011 với báo cáo cuối cùng vào ngày 18 tháng 3 năm 2014. Do đó, lỗi đã được báo cáo ngay trước khi bạn gặp phải lỗi và chưa được khắc phục cho đến ngày nay. Nó được báo cáo cụ thể đối với Thiết bị của bạn.

Nhận xét khác nhau trong báo cáo xác nhận lỗi này ảnh hưởng đến "Nexus S", "HTC Sensation", "Galaxy S Plus", "Galaxy S II", "HTC Desire HD", "Galaxy Nexus", " Xperia Mini ST15i "," Nexus 5 "," Galaxy R "và" Galaxy Note II "; với một chú thích tuyên bố nó hoạt động hoàn hảo trên "Galaxy Nexus".

Tham chiếu: https://code.google.com/p/android/issues/detail?id=14341.

Đây có phải là Mã nguồn bạn đang tìm kiếm không: https://android.googlesource.com/platform/frameworks/base/+/froyo-release/core/jni/android_hardware_Camera.cpp

Các vấn đề liên quan