Android自定義相機Camera實現(xiàn)手動對焦的方法示例
前言
我采用的是Camera來實現(xiàn)自定義相機的,如果你使用的是Camera2,那本文將不適用你。為了減少篇幅,本文主要講解手動對焦的實現(xiàn)方式,前提是你已經(jīng)能實現(xiàn)自定義相機的預覽等基礎功能。
目錄
- 手動對焦的方法解析
- 實現(xiàn)用戶點擊屏幕后,設置對焦區(qū)域和測光區(qū)域
一、手動對焦的方法
手動對焦的實現(xiàn)主要通過兩個Camera方法來進行配置:
- setFocusAreas 設置對焦的區(qū)域
- setMeteringAreas 設置測光的區(qū)域
他們需要傳入一個Camera.Area集合,Camera.Area如圖:
/**
* Create an area with specified rectangle and weight.
*
* @param rect the bounds of the area.
* @param weight the weight of the area.
*/
public Area(Rect rect, int weight) {
this.rect = rect;
this.weight = weight;
}
第一個參數(shù)是對焦和測光的區(qū)域,范圍在[-1000,-1000]到[1000,1000],第二個參數(shù)是權重,范圍在0到1000,當傳入多個Area時,權重的大小決定著對焦或測光的優(yōu)先級,如果每次只對焦一個區(qū)域,那第二個參數(shù)直接傳入1000即可,大多數(shù)開發(fā)中也是如此。
說到第一個參數(shù)的范圍,請看下圖,將更加清晰明了:

我們可以看到,和手機屏幕的分辨率不同,Area到屏幕的映射區(qū)域是從左上角的-1000,-1000到右下角的1000,1000,中心點是0,0,我們點擊屏幕后獲取到的坐標,最終就需要轉化為映射區(qū)域的坐標,這是手動對焦最為重要的環(huán)節(jié),了解了這兩個必要的參數(shù)配置后,我們就可以開始手動對焦的實現(xiàn)了。
二、實現(xiàn)用戶點擊屏幕后,設置對焦區(qū)域和測光區(qū)域 獲取點擊預覽畫面的坐標值
用戶點擊屏幕,實際是點擊的預覽畫面的區(qū)域,拍照功能大家肯定都知道,這個就不多解釋,那么我們直接通過setOnTouchListener方法對View進行監(jiān)聽即可
surfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("MainActivity", "X坐標:" + event.getX()+",Y坐標:"+event.getY());
return false;
}
});
通過MotionEvent我們就可以獲取到用戶點擊屏幕時,相對于View的坐標值了
將View坐標值轉化為Area映射區(qū)域的坐標值
之前說過,Area映射區(qū)域是[-1000,-1000]到[1000,1000],那么通過下面的坐標換算公式,我們就可以得到點擊預覽畫面時,映射區(qū)域的坐標值了
surfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int areaX = (int) (event.getX() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的X坐標
int areaY = (int) (event.getY() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的Y坐標
return false;
}
});
獲取到映射區(qū)域的坐標后,我們就要設置一個對焦的范圍了,范圍是靈活的,我這里就創(chuàng)建一個長寬是200的矩形區(qū)域
surfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int areaX = (int) (event.getX() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的X坐標
int areaY = (int) (event.getY() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的Y坐標
// 創(chuàng)建Rect區(qū)域
Rect focusArea = new Rect();
focusArea.left = Math.max(x - 100, -1000); // 取最大或最小值,避免范圍溢出屏幕坐標
focusArea.top = Math.max(y - 100, -1000);
focusArea.right = Math.min(x + 100, 1000);
focusArea.bottom = Math.min(y + 100, 1000);
return false;
}
});
設置對焦和測光
完成這一步,那就已經(jīng)實現(xiàn)了手動對焦了,如下代碼:
surfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int areaX = (int) (event.getX() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的X坐標
int areaY = (int) (event.getY() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的Y坐標
// 創(chuàng)建Rect區(qū)域
Rect focusArea = new Rect();
focusArea.left = Math.max(x - 100, -1000); // 取最大或最小值,避免范圍溢出屏幕坐標
focusArea.top = Math.max(y - 100, -1000);
focusArea.right = Math.min(x + 100, 1000);
focusArea.bottom = Math.min(y + 100, 1000);
// 創(chuàng)建Camera.Area
Camera.Area cameraArea = new Camera.Area(focusArea, 1000);
List<Camera.Area> meteringAreas = new ArrayList<Camera.Area>();
List<Camera.Area> focusAreas = new ArrayList<Camera.Area>();
if (mParameters.getMaxNumMeteringAreas() > 0) {
meteringAreas.add(cameraArea);
focusAreas.add(cameraArea);
}
mParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); // 設置對焦模式
mParameters.setFocusAreas(focusAreas); // 設置對焦區(qū)域
mParameters.setMeteringAreas(meteringAreas); // 設置測光區(qū)域
try {
mCamera.cancelAutoFocus(); // 每次對焦前,需要先取消對焦
mCamera.setParameters(mParameters); // 設置相機參數(shù)
mCamera.autoFocus(mAutoFocusCallback); // 開啟對焦
} catch (Exception e) {
}
return false;
}
});
相關注釋都在代碼中,手動對焦其實很簡單,計算好Area映射區(qū)域的坐標,為相機設置對焦和測光區(qū)域即可。
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Android?Banner本地和網(wǎng)絡輪播圖使用介紹
大家好,本篇文章講的是Android?Banner本地和網(wǎng)絡輪播圖使用介紹,感興趣的同學趕快來看一看吧,希望本篇文章對你起到幫助2021-11-11
Android中使用ContentProvider管理系統(tǒng)資源的實例
這篇文章主要介紹了Android中使用ContentProvider管理系統(tǒng)資源的實例,講解了ContentProvider對系統(tǒng)中聯(lián)系人及多媒體資源的管理例子,需要的朋友可以參考下2016-04-04
Android?掃碼槍輸入時屏蔽軟鍵盤和頂部狀態(tài)欄的解決方案
在Android設備上,使用掃碼槍時常遇到軟鍵盤和頂部狀態(tài)欄顯示問題,本文介紹了在Android 7.1.2版本上,如何通過設置inputType為none屏蔽軟鍵盤,以及通過hideStatusBar和NoActionBar方法隱藏頂部狀態(tài)欄,以優(yōu)化掃碼槍使用界面,這些方法有助于提升使用掃碼槍場景的用戶體驗2024-10-10
Android實現(xiàn)檢測手機多點觸摸點數(shù)
這篇文章主要為大家詳細介紹了Android實現(xiàn)檢測手機多點觸摸點數(shù),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2022-05-05
Android RecyclerView仿新聞頭條的頻道管理功能
這篇文章主要介紹了Android RecyclerView仿新聞頭條的頻道管理功能,需要的朋友可以參考下2017-06-06
Android中在WebView里實現(xiàn)Javascript調用Java類的方法
這篇文章主要介紹了Android中在WebView里實現(xiàn)Javascript調用Java類的方法,本文直接給出示例,需要的朋友可以參考下2015-03-03

