相机预览显示为拉伸

时间:2019-05-31 14:06:06

标签: android android-camera2

我正在尝试将相机2与Google示例中的AutoFitTextureView一起使用。

我是这样设置的

private void setUpCameraOutputs() {
    CameraManager manager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
    try {
        if (manager != null) {
            for (String cameraId : manager.getCameraIdList()) {
                CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);

                // We don't use a front facing camera in this sample.
                //noinspection ConstantConditions
                if (characteristics.get(LENS_FACING) == LENS_FACING_FRONT) continue;

                StreamConfigurationMap map = characteristics.get(SCALER_STREAM_CONFIGURATION_MAP);

                if(map != null) {
                    // For still image captures, we use the largest available size.
                    List<Size> outputSizes = Arrays.asList(map.getOutputSizes(sImageFormat));
                    Size largest = Collections.max(outputSizes, new CompareSizesByArea());
                    mImageReader = ImageReader.newInstance(640, 480, sImageFormat, 8);
                    mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
                    // Danger, W.R.! Attempting to use too large a preview size could exceed the camera
                    // bus' bandwidth limitation, resulting in gorgeous previews but the storage of
                    // garbage capture data.
                    mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class), largest.getWidth(), largest.getHeight(), largest);
                    //mPreviewSize = new Size(largest.getWidth(), largest.getHeight());
                    setAspectRatio2(mPreviewSize);
                    Logging.e(TAG, "WIDTH: " + mPreviewSize.getWidth() + " HEIGHT: " + mPreviewSize.getHeight());

                    mCameraId = cameraId;
                }
                //return;
            }
        }else{
            Logging.e(TAG,"No Manager");
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private void setAspectRatio(){
    int orientation = mContext.getResources().getConfiguration().orientation;
    if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
        mTextureView.setAspectRatio(mPreviewSize.getWidth(),mPreviewSize.getHeight());
    } else {
        mTextureView.setAspectRatio(mPreviewSize.getHeight(),mPreviewSize.getWidth());
    }
}

private void setAspectRatio2(Size largest){
    float cameraAspectRatio = (float) largest.getHeight() / largest.getWidth();
    //Preparation
    DisplayMetrics metrics = new DisplayMetrics();
    WindowManager wm = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE));
    wm.getDefaultDisplay().getMetrics(metrics);
    int screenWidth = metrics.widthPixels;
    int screenHeight = metrics.heightPixels;
    int finalWidth = screenWidth;
    int finalHeight = screenHeight;
    int widthDifference = 0;
    int heightDifference = 0;
    float screenAspectRatio = (float) screenWidth / screenHeight;

    //Determines whether we crop width or crop height
    if (screenAspectRatio > cameraAspectRatio) { //Keep width crop height
        finalHeight = (int) (screenWidth / cameraAspectRatio);
        heightDifference = finalHeight - screenHeight;
    } else { //Keep height crop width
        finalWidth = (int) (screenHeight * cameraAspectRatio);
        widthDifference = finalWidth - screenWidth;
    }

    //Apply the result to the Preview
    LayoutParams lp = (FrameLayout.LayoutParams) mTextureView.getLayoutParams();
    lp.width = finalWidth;
    lp.height = finalHeight;
    //Below 2 lines are to center the preview, since cropping default occurs at the right and bottom
    lp.leftMargin = - (widthDifference / 2);
    lp.topMargin = - (heightDifference / 2);
    mTextureView.setLayoutParams(lp);
}

private static Size chooseOptimalSize(Size[] choices, int width, int height, Size aspectRatio) {
    // Collect the supported resolutions that are at least as big as the preview Surface
    List<Size> bigEnough = new ArrayList<>();
    int w = aspectRatio.getWidth();
    int h = aspectRatio.getHeight();
    double ratio = (double) h / w;
    for (Size option : choices) {
        double optionRatio = (double) option.getHeight() / option.getWidth();
        if (ratio == optionRatio) {
            bigEnough.add(option);
        }
    }

    // Pick the smallest of those, assuming we found any
    if (bigEnough.size() > 0) {
        return Collections.min(bigEnough, new CompareSizesByArea());
    } else {
        Logging.e(TAG, "Couldn't find any suitable preview size");
        return choices[1];
    }
}

我尝试用2种不同的方法设置纵横比,但是似乎没有一种方法可以满足我的需要。 预览可以根据需要显示所有屏幕,但是相机预览总是显得狭窄,看起来更细。 我已经尝试过一些来自stackoverflow的建议,但是仍然没有得到理想的结果。

1 个答案:

答案 0 :(得分:0)

有许多库可简化CameraView的使用。 例如,您可以查看this onethis one