1. 程式人生 > >解決SurfaceView預覽Camera拉伸問題

解決SurfaceView預覽Camera拉伸問題

在android中實現錄製視訊時,都會要求實現一個視訊預覽的功能(一般都是全屏預覽),實現方式就是用SurfaceView來實時顯示Camera傳遞過來的影象。

但是我們都知道,android手機的螢幕尺寸千奇百怪,使用預設的預覽尺寸,部分手機會導致SurfaceView顯示時影象拉長,整個人的臉看起來比驢臉還長;如果設定Camera的預覽尺寸為螢幕尺寸,那麼如果剛好Camera不相容這個尺寸,則會直接報錯。

那就沒辦法了麼?

怎麼能難倒萬能的android開發者,如果螢幕尺寸與預覽尺寸不一致,那麼只要他們的寬高比一致,顯示出來的效果一樣是正常的。所以,重點是如何找到最相近的預覽尺寸引數,程式碼如下:

/**
 * 通過對比得到與寬高比最接近的預覽尺寸(如果有相同尺寸,優先選擇)
 *
 * @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的時候設定預覽尺寸的引數:
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的寬高。

參考: