Android Camera2之 手動點擊區(qū)域?qū)?/h1>

引言

最近做一套基于Camera2 API的相機應(yīng)用剪廉,發(fā)現(xiàn)有關(guān)Camera2 手動點擊區(qū)域?qū)沟奈恼律僦稚偻扪瑹o奈痛苦研究了一天手動區(qū)域?qū)梗K于達到理想效果斗蒋。

展示一下效果:


screen.gif

有關(guān)Camera2 API的基本使用請自行Google捌斧,本文基于研究Camera2點擊對焦實現(xiàn)基礎(chǔ)之上,如有不足泉沾,歡迎指出捞蚂。

手動對焦基本原理

我們都應(yīng)該知道,手機改變焦距是通過分析攝像頭拍攝二維圖爆哑,并經(jīng)過算法根據(jù)對焦區(qū)域來測量光度情況進行對焦洞难。因此,Camera2中也提供了該對焦方式的API,我們只需提供基于Camera2所需的對焦區(qū)域(Rect)即可队贱。

Camera2通過不同的接口色冀,給應(yīng)用層提供了這方面的信息:

SENSOR_INFO_PIXEL_ARRAY_SIZE表示的是攝像頭成像區(qū)域所使用的內(nèi)存大小。

SENSOR_INFO_ACTIVE_ARRAY_SIZE表示真正接收光線的區(qū)域柱嫌,因此成像的區(qū)域是該參數(shù)指定的區(qū)域锋恬,當然該矩形區(qū)域的坐標系基于SENSOR_INFO_PIXEL_ARRAY_SIZE

SCALER_CROP_REGION表示最終的輸出內(nèi)容是基于SENSOR_INFO_ACTIVE_ARRAY_SIZE裁剪的部分编丘,而該值指定裁剪的區(qū)域与学。

image

上圖灰色區(qū)域可以理解為通過 CameraCharacteristics.SENSOR_INFO_PIXEL_ARRAY_SIZE拿到的區(qū)域,這個區(qū)域就是我們攝像頭拍攝照片的最大分辨率(比如我的三星s8嘉抓,最大分辨率為4032*3024)索守。

藍色區(qū)域是通過CaptureRequest.SCALER_CROP_REGION 拿到的部分該部分經(jīng)測試與*SENSOR_INFO_PIXEL_ARRAY_SIZE *拿到的區(qū)域大小是一樣的抑片。

橘黃色區(qū)域和綠色區(qū)域分別代表我們的應(yīng)用界面裁剪區(qū)域卵佛。橘黃色一般為豎屏,綠色一般為橫屏敞斋。這個兩個部分的大小其實就是我們在設(shè)定相機預(yù)覽界面時的大小截汪,這個可以根據(jù)需要來設(shè)定。但這個區(qū)域顯示在手機屏幕的時候是等比縮放的植捎。所以我們在處理手指的點擊區(qū)域時衙解,我們需要根據(jù)預(yù)覽界面相對于相機取景最大分辨率進行調(diào)整觸摸坐標位置。

開始對焦

原理介紹完了焰枢,開始切入正題

首先我們需要知道蚓峦,手動對焦是通過CaptureRequest.Builder的CONTROL_AF_REGIONS(控制對焦區(qū)域)和CONTROL_AE_REGIONS(控制曝光區(qū)域)來控制的。上代碼(Kotlin):

mPreViewBuilder.apply{
    set(CaptureRequest.CONTROL_AF_REGIONS, arrayOf(MeteringRectangle(rect, 1000)))

    set(CaptureRequest.CONTROL_AE_REGIONS, arrayOf(MeteringRectangle(rect, 1000)))

    set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_AUTO)

    set(CaptureRequest.CONTROL_AF_TRIGGER, CameraMetadata.CONTROL_AF_TRIGGER_START)

    set(CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER,CameraMetadata.CONTROL_AE_PRECAPTURE_TRIGGER_START)
}

可以見得手動對焦關(guān)鍵在于如何獲取上述代碼中的rect變量医咨。也就是相對于整個相機最大分辨率枫匾,手指的點擊區(qū)域架诞。繼續(xù)上代碼(在這里我們暫只考慮豎屏情況拟淮,橫屏情況參考注釋):

  /**
  * 獲取點擊區(qū)域
  * @param x:手指觸摸點x坐標
  * @param y: 手指觸摸點y坐標 
  */
 private fun getFocusRect( x: Int, y: Int): Rect {
    val screenW = FontDisplayUtil.getScreenWidth()//獲取屏幕長度
    val screenH = FontDisplayUtil.getScreenHeight()//獲取屏幕寬度
    
    //因為獲取的SCALER_CROP_REGION是寬大于高的,也就是默認橫屏模式谴忧,豎屏模式需要對調(diào)width和height
    var realPreviewWidth = mPreviewSize.height 
    var realPreviewHeight = mPreviewSize.width
    
    //根據(jù)預(yù)覽像素與拍照最大像素的比例很泊,調(diào)整手指點擊的對焦區(qū)域的位置
    val focusX = realPreviewWidth.toFloat() / screenW * x
    val focusY = realPreviewHeight.toFloat() / screenH * y
    LogUtil.i("focusX=$focusX,focusY=$focusY")
    
    //獲取SCALER_CROP_REGION,也就是拍照最大像素的Rect
    val totalPicSize = mPreViewBuilder!!.get(CaptureRequest.SCALER_CROP_REGION)
    LogUtil.i("camera pic area size=$totalShowSize")

    //計算出攝像頭剪裁區(qū)域偏移量
    val cutDx = (totalPicSize.height() - mPreviewSize.height) / 2
    LogUtil.i("cutDx=$cutDx")

    //我們默認使用10dp的大小沾谓,也就是默認的對焦區(qū)域長寬是10dp委造,這個數(shù)值可以根據(jù)需要調(diào)節(jié)
    val width = FontDisplayUtil.dip2px(10f)
    val height = FontDisplayUtil.dip2px(10f)
    
    //返回最終對焦區(qū)域Rect
    return Rect(focusY.toInt(), focusX.toInt() + cutDx, (focusY + height).toInt(), (focusX + cutDx + width).toInt())
}

其中cutDx變量是屏幕比例相對于攝像頭剪裁區(qū)域的偏移量。因為在我的項目中屏幕是固定豎屏的均驶,也就是說我的屏幕高度與SCALER_CROP_REGION獲取的最大高度時相等的昏兆,所以只需要考慮寬度的調(diào)整「狙ǎ可以參考下圖整理一下思路...


示例

至此爬虱,點擊對焦的大部分工作均已完成隶债。不要忘了在設(shè)置完mPreViewBuilder的手動對焦模式之后,使用setRepeatingRequest方法來實現(xiàn)畫面的連貫加載跑筝。

本文參考:http://www.reibang.com/p/76225ac72b56
如有不足死讹,歡迎指出,謝謝曲梗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末赞警,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子虏两,更是在濱河造成了極大的恐慌愧旦,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件定罢,死亡現(xiàn)場離奇詭異忘瓦,居然都是意外死亡,警方通過查閱死者的電腦和手機引颈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門耕皮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人蝙场,你說我怎么就攤上這事凌停。” “怎么了售滤?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵罚拟,是天一觀的道長。 經(jīng)常有香客問我完箩,道長赐俗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任弊知,我火速辦了婚禮阻逮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秩彤。我一直安慰自己叔扼,他們只是感情好,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布漫雷。 她就那樣靜靜地躺著瓜富,像睡著了一般。 火紅的嫁衣襯著肌膚如雪降盹。 梳的紋絲不亂的頭發(fā)上与柑,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機與錄音,去河邊找鬼价捧。 笑死每辟,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的干旧。 我是一名探鬼主播渠欺,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼椎眯!你這毒婦竟也來了挠将?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤编整,失蹤者是張志新(化名)和其女友劉穎舔稀,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掌测,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡内贮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了汞斧。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夜郁。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖粘勒,靈堂內(nèi)的尸體忽然破棺而出竞端,到底是詐尸還是另有隱情,我是刑警寧澤庙睡,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布事富,位于F島的核電站,受9級特大地震影響乘陪,放射性物質(zhì)發(fā)生泄漏统台。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一啡邑、第九天 我趴在偏房一處隱蔽的房頂上張望贱勃。 院中可真熱鬧,春花似錦谣拣、人聲如沸募寨。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仪缸,卻和暖如春贵涵,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工宾茂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瓷马,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓跨晴,卻偏偏與公主長得像欧聘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子端盆,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

推薦閱讀更多精彩內(nèi)容