解決SurfaceView預覽Camera拉伸問題
阿新 • • 發佈:2019-01-29
在android中實現錄製視訊時,都會要求實現一個視訊預覽的功能(一般都是全屏預覽),實現方式就是用SurfaceView來實時顯示Camera傳遞過來的影象。
但是我們都知道,android手機的螢幕尺寸千奇百怪,使用預設的預覽尺寸,部分手機會導致SurfaceView顯示時影象拉長,整個人的臉看起來比驢臉還長;如果設定Camera的預覽尺寸為螢幕尺寸,那麼如果剛好Camera不相容這個尺寸,則會直接報錯。
那就沒辦法了麼?
怎麼能難倒萬能的android開發者,如果螢幕尺寸與預覽尺寸不一致,那麼只要他們的寬高比一致,顯示出來的效果一樣是正常的。所以,重點是如何找到最相近的預覽尺寸引數,程式碼如下:
然後在初始化Camera的時候設定預覽尺寸的引數:/** * 通過對比得到與寬高比最接近的預覽尺寸(如果有相同尺寸,優先選擇) * * @param isPortrait 是否豎屏 * @param surfaceWidth 需要被進行對比的原寬 * @param surfaceHeight 需要被進行對比的原高 * @param preSizeList 需要對比的預覽尺寸列表 * @return 得到與原寬高比例最接近的尺寸 */ public static Camera.Size getCloselyPreSize(boolean isPortrait, int surfaceWidth, int surfaceHeight, List<Camera.Size> preSizeList) { int reqTmpWidth; int reqTmpHeight; // 當螢幕為垂直的時候需要把寬高值進行調換,保證寬大於高 if (isPortrait) { reqTmpWidth = surfaceHeight; reqTmpHeight = surfaceWidth; } else { reqTmpWidth = surfaceWidth; reqTmpHeight = surfaceHeight; } //先查詢preview中是否存在與surfaceview相同寬高的尺寸 for(Camera.Size size : preSizeList){ if((size.width == reqTmpWidth) && (size.height == reqTmpHeight)){ return size; } } // 得到與傳入的寬高比最接近的size float reqRatio = ((float) reqTmpWidth) / reqTmpHeight; float curRatio, deltaRatio; float deltaRatioMin = Float.MAX_VALUE; Camera.Size retSize = null; for (Camera.Size size : preSizeList) { curRatio = ((float) size.width) / size.height; deltaRatio = Math.abs(reqRatio - curRatio); if (deltaRatio < deltaRatioMin) { deltaRatioMin = deltaRatio; retSize = size; } } return retSize; }
Camera.Parameters parameters = mCamera.getParameters();
Camera.Size preSize = CameraUtil.getCloselyPreSize(true, screenWidth, screenHeight, parameters.getSupportedPreviewSizes());
parameters.setPreviewSize(preSize.width, preSize.height);
mCamera.setParameters(parameters);
因為我這裡SurfaceView是全屏顯示,所以,螢幕的寬高就是SurfaceView的寬高。
參考: