Android中關(guān)于自定義相機(jī)預(yù)覽界面拉伸問題
關(guān)于自定義相機(jī)預(yù)覽界面拉伸問題
1、導(dǎo)致主要變形的原因是Camera預(yù)覽界面旋轉(zhuǎn)的角度和攝像頭掛載的角度不同導(dǎo)致的
2、我們的Activity設(shè)置的方向是豎屏,這是手機(jī)的自然方向 所以寬比高短
3、角度:所謂屏幕和攝像頭的角度,指的是相對于自然方向旋轉(zhuǎn)過的角度,根據(jù)旋轉(zhuǎn)角度即可獲知當(dāng)前的方向
4、假如說:手機(jī)是豎屏的情況下, 自然角度為0,但是Camera逆時(shí)針旋轉(zhuǎn)90度,那咱們設(shè)置順時(shí)針旋轉(zhuǎn)90度,就正常 。手機(jī)是橫屏的情況下Camera返回為0度 ,如果設(shè)置順時(shí)針旋轉(zhuǎn)90度,就回旋轉(zhuǎn)
怎么設(shè)置預(yù)覽界面與實(shí)景保持一致的方法,官方給出的文檔:
public static void setCameraDisplayOrientation(Activity activity,int cameraIo, Camera camera){ Camera.CameraInfo info=new Camera.CameraInfo(); Camera.getCameraInfo(cameraIo,info); int rotation=activity.getWindowManager().getDefaultDisplay().getRotation(); int degress=0; switch(rotation){ case Surface.ROTATION_0: degress=0; break; case Surface.ROTATION_90: degress=90; break; case Surface.ROTATION_180: degress=180; break; case Surface.ROTATION_270: degress=270; break; } int result; if(info.facing=Camera.CameraInfo.CAMERA_FACING_FRONT){ result = (info.orientation + degrees) % 360; > 就是攝像頭需要順時(shí)針轉(zhuǎn)過多少度才能恢復(fù)自然方向 result = (360 - result) % 360; } else { // back-facing result = (info.orientation - degrees + 360) % 360; } camera.setDisplayOrientation(result); switch (result) { case 0: case 180: setCameraSize(camera.getParameters(), getScreenWidth(), getScreenHeight()); break; case 90: case 270: setCameraSize(camera.getParameters(), getScreenHeight(), getScreenWidth()); break; } } public static void setCameraSize(Camera.Parameters parameters, int width, int height) { Map<String, List<Size>> allSizes = new HashMap<>(); String typePreview = "typePreview"; String typePicture = "typePicture"; allSizes.put(typePreview, parameters.getSupportedPreviewSizes()); allSizes.put(typePicture, parameters.getSupportedPictureSizes()); Iterator iterator = allSizes.entrySet().iterator(); while (iterator.hasNext()) { Map.Entry<String, List<Size>> entry = (Map.Entry<String, List<Size>>) iterator.next(); List<Size> sizes = entry.getValue(); if (sizes == null || sizes.isEmpty()) continue; ArrayList<WrapCameraSize> wrapCameraSizes = new ArrayList<>(sizes.size()); for (Size size : sizes) { WrapCameraSize wrapCameraSize = new WrapCameraSize(); wrapCameraSize.setWidth(size.width); wrapCameraSize.setHeight(size.height); wrapCameraSize.setD(Math.abs((size.width - width)) + Math.abs((size.height - height))); if (size.width == width && size.height == height) { if (typePreview.equals(entry.getKey())) { parameters.setPreviewSize(size.width, size.height); } else if (typePicture.equals(entry.getKey())) { parameters.setPictureSize(size.width, size.height); } Log.d(TAG, "best size: width=" + size.width + ";height=" + size.height); break; } wrapCameraSizes.add(wrapCameraSize); } Log.d(TAG, "wrapCameraSizes.size()=" + wrapCameraSizes.size()); Size resultSize = null; if (typePreview.equals(entry.getKey())) { resultSize = parameters.getPreviewSize(); } else if (typePicture.equals(entry.getKey())) { resultSize = parameters.getPictureSize(); } if (resultSize == null || (resultSize.width != width && resultSize.height != height)) { //找到相機(jī)Preview Size 和 Picture Size中最適合的大小 if(wrapCameraSizes.isEmpty()) continue; WrapCameraSize minCameraSize = Collections.min(wrapCameraSizes); while (!(minCameraSize.getWidth() >= width && minCameraSize.getHeight() >= height)) { wrapCameraSizes.remove(minCameraSize); if(wrapCameraSizes.isEmpty()) break; minCameraSize = null; minCameraSize = Collections.min(wrapCameraSizes); } Log.d(TAG, "best min size: width=" + minCameraSize.getWidth() + ";height=" + minCameraSize.getHeight()); if (typePreview.equals(entry.getKey())) { parameters.setPreviewSize(minCameraSize.getWidth(), minCameraSize.getHeight()); } else if (typePicture.equals(entry.getKey())) { parameters.setPictureSize(minCameraSize.getWidth(), minCameraSize.getHeight()); } } iterator.remove(); } }
先將獲取手機(jī)支持預(yù)覽的尺寸列表通過parmeters.getSupportPreviewSize返回的是一個集合。
進(jìn)行屏幕方向的判斷,因?yàn)轭A(yù)覽的尺寸都是w>h 如果是豎屏,則需要將寬和高進(jìn)行調(diào)換。
將預(yù)覽尺寸列表的每個元素的寬和高與SurfaceView的寬和高進(jìn)行比較,如果存在寬和高尺寸SurfaceView的寬和高,相同的size,則將當(dāng)前的寬高設(shè)置為預(yù)覽尺寸。
如果沒有找到該步驟,則將尺寸列表的比例和SUrfaceView的比例做比較,找一個相同或者相近的 。
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android?Camera1實(shí)現(xiàn)預(yù)覽框顯示
- Android CameraX打開攝像頭預(yù)覽教程
- Android?CameraX?打開攝像頭預(yù)覽功能
- Android Camera2 實(shí)現(xiàn)預(yù)覽功能
- Android實(shí)現(xiàn)Camera2預(yù)覽和拍照效果
- Android camera實(shí)時(shí)預(yù)覽 實(shí)時(shí)處理,人臉識別示例
- Android編程中調(diào)用Camera時(shí)預(yù)覽畫面有旋轉(zhuǎn)問題的解決方法
- Android仿微信照片選擇器實(shí)現(xiàn)預(yù)覽查看圖片
- android 7自定義相機(jī)預(yù)覽及拍照功能
- Android Camera2實(shí)現(xiàn)最簡單的預(yù)覽框顯示
相關(guān)文章
Android view更改背景資源與padding消失的問題解決辦法
這篇文章主要介紹了Android view更改背景資源與padding消失的問題解決辦法的相關(guān)資料,需要的朋友可以參考下2017-04-04Android開發(fā)之圖形圖像與動畫(三)Animation效果的XML實(shí)現(xiàn)
使用XML來定義Tween Animation動畫的XML文件在工程中res/anim目錄,這個文件必須包含一個根元素,感興趣的友可以了解一下,希望本文對你有所幫助2013-01-01Android實(shí)現(xiàn)測試環(huán)境噪音分貝
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)測試環(huán)境噪音分貝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01Android自定義View之RadioGroup實(shí)現(xiàn)跨多行顯示
這篇文章主要介紹了Android自定義View之RadioGroup實(shí)現(xiàn)跨多行顯示,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11Android如何通過Retrofit提交Json格式數(shù)據(jù)
本篇文章主要介紹了Android如何通過Retrofit提交Json格式數(shù)據(jù),具有一定的參考價(jià)值,有興趣的可以了解一下2017-08-08Android將項(xiàng)目導(dǎo)出為Library并在項(xiàng)目中使用教程
這篇文章主要介紹了Android將項(xiàng)目導(dǎo)出為Library并在項(xiàng)目中使用教程,本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-07-07