Android自定義相機(jī)Camera實(shí)現(xiàn)手動(dòng)對(duì)焦的方法示例
前言
我采用的是Camera來(lái)實(shí)現(xiàn)自定義相機(jī)的,如果你使用的是Camera2,那本文將不適用你。為了減少篇幅,本文主要講解手動(dòng)對(duì)焦的實(shí)現(xiàn)方式,前提是你已經(jīng)能實(shí)現(xiàn)自定義相機(jī)的預(yù)覽等基礎(chǔ)功能。
目錄
- 手動(dòng)對(duì)焦的方法解析
- 實(shí)現(xiàn)用戶(hù)點(diǎn)擊屏幕后,設(shè)置對(duì)焦區(qū)域和測(cè)光區(qū)域
一、手動(dòng)對(duì)焦的方法
手動(dòng)對(duì)焦的實(shí)現(xiàn)主要通過(guò)兩個(gè)Camera方法來(lái)進(jìn)行配置:
- setFocusAreas 設(shè)置對(duì)焦的區(qū)域
- setMeteringAreas 設(shè)置測(cè)光的區(qū)域
他們需要傳入一個(gè)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;
}
第一個(gè)參數(shù)是對(duì)焦和測(cè)光的區(qū)域,范圍在[-1000,-1000]到[1000,1000],第二個(gè)參數(shù)是權(quán)重,范圍在0到1000,當(dāng)傳入多個(gè)Area時(shí),權(quán)重的大小決定著對(duì)焦或測(cè)光的優(yōu)先級(jí),如果每次只對(duì)焦一個(gè)區(qū)域,那第二個(gè)參數(shù)直接傳入1000即可,大多數(shù)開(kāi)發(fā)中也是如此。
說(shuō)到第一個(gè)參數(shù)的范圍,請(qǐng)看下圖,將更加清晰明了:

我們可以看到,和手機(jī)屏幕的分辨率不同,Area到屏幕的映射區(qū)域是從左上角的-1000,-1000到右下角的1000,1000,中心點(diǎn)是0,0,我們點(diǎn)擊屏幕后獲取到的坐標(biāo),最終就需要轉(zhuǎn)化為映射區(qū)域的坐標(biāo),這是手動(dòng)對(duì)焦最為重要的環(huán)節(jié),了解了這兩個(gè)必要的參數(shù)配置后,我們就可以開(kāi)始手動(dòng)對(duì)焦的實(shí)現(xiàn)了。
二、實(shí)現(xiàn)用戶(hù)點(diǎn)擊屏幕后,設(shè)置對(duì)焦區(qū)域和測(cè)光區(qū)域 獲取點(diǎn)擊預(yù)覽畫(huà)面的坐標(biāo)值
用戶(hù)點(diǎn)擊屏幕,實(shí)際是點(diǎn)擊的預(yù)覽畫(huà)面的區(qū)域,拍照功能大家肯定都知道,這個(gè)就不多解釋?zhuān)敲次覀冎苯油ㄟ^(guò)setOnTouchListener方法對(duì)View進(jìn)行監(jiān)聽(tīng)即可
surfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
Log.e("MainActivity", "X坐標(biāo):" + event.getX()+",Y坐標(biāo):"+event.getY());
return false;
}
});
通過(guò)MotionEvent我們就可以獲取到用戶(hù)點(diǎn)擊屏幕時(shí),相對(duì)于View的坐標(biāo)值了
將View坐標(biāo)值轉(zhuǎn)化為Area映射區(qū)域的坐標(biāo)值
之前說(shuō)過(guò),Area映射區(qū)域是[-1000,-1000]到[1000,1000],那么通過(guò)下面的坐標(biāo)換算公式,我們就可以得到點(diǎn)擊預(yù)覽畫(huà)面時(shí),映射區(qū)域的坐標(biāo)值了
surfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int areaX = (int) (event.getX() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的X坐標(biāo)
int areaY = (int) (event.getY() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的Y坐標(biāo)
return false;
}
});
獲取到映射區(qū)域的坐標(biāo)后,我們就要設(shè)置一個(gè)對(duì)焦的范圍了,范圍是靈活的,我這里就創(chuàng)建一個(gè)長(zhǎ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坐標(biāo)
int areaY = (int) (event.getY() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的Y坐標(biāo)
// 創(chuàng)建Rect區(qū)域
Rect focusArea = new Rect();
focusArea.left = Math.max(x - 100, -1000); // 取最大或最小值,避免范圍溢出屏幕坐標(biāo)
focusArea.top = Math.max(y - 100, -1000);
focusArea.right = Math.min(x + 100, 1000);
focusArea.bottom = Math.min(y + 100, 1000);
return false;
}
});
設(shè)置對(duì)焦和測(cè)光
完成這一步,那就已經(jīng)實(shí)現(xiàn)了手動(dòng)對(duì)焦了,如下代碼:
surfaceView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int areaX = (int) (event.getX() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的X坐標(biāo)
int areaY = (int) (event.getY() / surfaceView.getWidth() * 2000) - 1000; // 獲取映射區(qū)域的Y坐標(biāo)
// 創(chuàng)建Rect區(qū)域
Rect focusArea = new Rect();
focusArea.left = Math.max(x - 100, -1000); // 取最大或最小值,避免范圍溢出屏幕坐標(biāo)
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); // 設(shè)置對(duì)焦模式
mParameters.setFocusAreas(focusAreas); // 設(shè)置對(duì)焦區(qū)域
mParameters.setMeteringAreas(meteringAreas); // 設(shè)置測(cè)光區(qū)域
try {
mCamera.cancelAutoFocus(); // 每次對(duì)焦前,需要先取消對(duì)焦
mCamera.setParameters(mParameters); // 設(shè)置相機(jī)參數(shù)
mCamera.autoFocus(mAutoFocusCallback); // 開(kāi)啟對(duì)焦
} catch (Exception e) {
}
return false;
}
});
相關(guān)注釋都在代碼中,手動(dòng)對(duì)焦其實(shí)很簡(jiǎn)單,計(jì)算好Area映射區(qū)域的坐標(biāo),為相機(jī)設(shè)置對(duì)焦和測(cè)光區(qū)域即可。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
android圖像繪制(七)ClipRect局部繪圖/切割原圖繪制總結(jié)
這幾天開(kāi)始學(xué)游戲地圖制作,今天小小的總結(jié)一下Canvas的clipRect()接口的使用,接下來(lái)介紹ClipRect局部繪圖/切割原圖繪制感興趣的朋友可以了解下2013-01-01
Android 詳解Studio引用Library與導(dǎo)入jar
這篇文章主要介紹了Android Studio引用Library與導(dǎo)入jar的相關(guān)資料,需要的朋友可以參考下2017-01-01
Android實(shí)現(xiàn)手勢(shì)控制ImageView圖片大小
這篇文章主要介紹了Android實(shí)現(xiàn)手勢(shì)控制ImageView圖片大小的相關(guān)資料,需要的朋友可以參考下2016-02-02
Android Studio 中運(yùn)行 groovy 程序的方法圖文詳解
這篇文章主要介紹了Android Studio 中 運(yùn)行 groovy 程序的方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-03-03
Android 判斷是否能真正上網(wǎng)的實(shí)例詳解
這篇文章主要介紹了Android 判斷是否能真正上網(wǎng)的實(shí)例詳解相關(guān)資料,希望通過(guò)本文大家能夠掌握判斷是否上網(wǎng)的方法,需要的朋友可以參考下2017-10-10
Android學(xué)習(xí)筆記--使用剪切板在Activity中傳值示例代碼
相對(duì)于getText和setText而言,利用ClipData對(duì)象來(lái)傳遞數(shù)據(jù),更符合面向?qū)ο蟮乃枷耄宜軅鬟f的數(shù)據(jù)類(lèi)型也多樣化了2013-06-06
Android CountDownTimer實(shí)現(xiàn)定時(shí)器和倒計(jì)時(shí)效果
這篇文章主要為大家詳細(xì)介紹了Android CountDownTimer實(shí)現(xiàn)定時(shí)器和倒計(jì)時(shí)效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-02-02
android 應(yīng)用退出時(shí)不播放動(dòng)畫(huà)的解決方法
在Android應(yīng)用中,默認(rèn)情況下,當(dāng)用戶(hù)點(diǎn)擊返回按鈕退出應(yīng)用時(shí),系統(tǒng)會(huì)為應(yīng)用添加一個(gè)默認(rèn)的退出動(dòng)畫(huà)效果,本文將介紹如何在Android應(yīng)用中禁止退出動(dòng)畫(huà)的播放,感興趣的朋友一起看看吧2024-05-05
android自動(dòng)化測(cè)試知識(shí)點(diǎn)總結(jié)
在本文里小編給大家分享了關(guān)于android自動(dòng)化測(cè)試入門(mén)的相關(guān)知識(shí)點(diǎn),需要的朋友們跟著參考下吧。2019-06-06
Android小程序?qū)崿F(xiàn)訪問(wèn)聯(lián)系人
這篇文章主要為大家詳細(xì)介紹了Android小程序?qū)崿F(xiàn)訪問(wèn)聯(lián)系人,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一2020-05-05

