2011-05-04 189 views
30

內置的攝像機應用程序(如HTC EVO上的應用程序)似乎只在預覽圖像更改時纔會調用camera.autoFocus()。如果穩定握住相機,則不會發生camera.autoFocus()
我想重複這種行爲,而camera.startPreview()是活躍在低於初始預覽設置代碼:安卓相機AutoFocus on Demand

camera = camera.open(); 
Camera.Parameters parameters = camera.getParameters(); 
List<String> focusModes = parameters.getSupportedFocusModes(); 
if (focusModes.contains(Camera.Parameters.FOCUS_MODE_AUTO)) 
{ 
    parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); 
} 
camera.setParameters(parameters); 
camera.setPreviewDisplay(holder); 
camera.startPreview(); 

所有我發現自動對焦()的例子中看到每500ms被調用它2000毫秒,或一次拍攝照片或錄製開始之前的瞬間。
EVO攝像機應用似乎使用傳感器或算法來觸發autoFocus()。然而這個觸發器已經完成,它工作得非常好。有沒有人知道如何在需要時按需觸發autoFocus()。那就是當相機靠近或遠離主體移動或相機輕微搖攝? 謝謝, Gerry

+1

你會回答或評論任何答案?或者你剛剛爲了它而發佈? – 2012-05-17 11:19:47

回答

22

Android已經引入continuous auto focus自API等級9(薑餅)。它比定期調用Camera.autoFocus更好。

+2

即使API> 9,某些HTC設備也不支持連續自動對焦。使用parameters.getSupportedFocusModes()。contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)來檢查它是否受支持。 – d2vid 2014-09-25 06:44:34

+0

@ d2vid,這是真的。我在API 15 HTC上開發,它不支持連續自動對焦! – Johnny 2014-12-17 00:04:31

19

我在我的一個應用程序中遇到了同樣的問題。

我的解決方案是使用傳感器偵聽器,並在用戶將設備擺動到某個閾值時進行自動對焦。這是代碼。

public void setCameraFocus(AutoFocusCallback autoFocus){ 
if (mCamera.getParameters().getFocusMode().equals(mCamera.getParameters().FOCUS_MODE_AUTO) || 
     mCamera.getParameters().getFocusMode().equals(mCamera.getParameters().FOCUS_MODE_MACRO)){ 
    mCamera.autoFocus(autoFocus); 
} 

}

自動對焦回調:

// this is the autofocus call back 
private AutoFocusCallback myAutoFocusCallback = new AutoFocusCallback(){ 

    public void onAutoFocus(boolean autoFocusSuccess, Camera arg1) { 
     //Wait.oneSec(); 
     mAutoFocus = true; 
    }}; 

,並呼籲重點的方式。

public void onSensorChanged(SensorEvent event) { 

if (mInvalidate == true){ 
    mView.invalidate(); 
    mInvalidate = false; 
} 
float x = event.values[0]; 
float y = event.values[1]; 
float z = event.values[2]; 
if (!mInitialized){ 
    mLastX = x; 
    mLastY = y; 
    mLastZ = z; 
    mInitialized = true; 
} 
float deltaX = Math.abs(mLastX - x); 
float deltaY = Math.abs(mLastY - y); 
float deltaZ = Math.abs(mLastZ - z); 

if (deltaX > .5 && mAutoFocus){ //AUTOFOCUS (while it is not autofocusing) 
    mAutoFocus = false; 
    mPreview.setCameraFocus(myAutoFocusCallback); 
} 
if (deltaY > .5 && mAutoFocus){ //AUTOFOCUS (while it is not autofocusing) 
    mAutoFocus = false; 
    mPreview.setCameraFocus(myAutoFocusCallback); 
} 
if (deltaZ > .5 && mAutoFocus){ //AUTOFOCUS (while it is not autofocusing) */ 
    mAutoFocus = false; 
    mPreview.setCameraFocus(myAutoFocusCallback); 
} 

mLastX = x; 
mLastY = y; 
mLastZ = z; 

}

您可以在這裏看到完整的項目:http://adblogcat.com/a-camera-preview-with-a-bounding-box-like-google-goggles/

+2

'if(mAutoFocus &&(deltaX> .5 || deltaY> .5 || deltaZ> .5))'也會很好地做 – 2013-06-04 14:40:29

+0

呵呵,是的。我沒有重構這段代碼。 – 2013-06-12 20:30:59

2

這是非常可能調用重新聚焦具有更簡單的技術,如果你有攝像頭視圖內的白盒閃光(從代碼,而不是一個真正的盒子),它會迅速調用重新調焦。我擁有EVO 4G,以前的其中一張海報是正確的,它不斷重新調整焦點,無需改變自從薑餅更新以來所看到的內容。

2

拍照時,可以設置this

在這種模式下,應用程序可以調用autoFocus(AutoFocusCallback)。如果自動對焦正在掃描中,則焦點回調將在完成時返回。如果自動對焦未掃描,焦點回調將立即返回一個布爾值,指示焦點是否清晰。應用程序可以決定是要立即拍攝照片還是將對焦模式更改爲自動,並運行完整的自動對焦週期。