設定相機預覽和保存照片尺寸

1、獲取相機支持的預覽和保存照片的尺寸

  • 獲取 mPreviewSizes 和 mPictureSizes 的代碼
/**
     * 打開攝像頭
     */
    private void openCamera() {
        if (mCamera != null) {
            releaseCamera();
        }
        mCamera = Camera.open(mCameraId);
        mCameraParameters = mCamera.getParameters();
        // Supported preview sizes
        mPreviewSizes.clear();
        for (Camera.Size size : mCameraParameters.getSupportedPreviewSizes()) {
            mPreviewSizes.add(new Size(size.width, size.height));
        }
        // Supported picture sizes;
        mPictureSizes.clear();
        for (Camera.Size size : mCameraParameters.getSupportedPictureSizes()) {
            mPictureSizes.add(new Size(size.width, size.height));
        }
        // AspectRatio
        if (mAspectRatio == null) {
            mAspectRatio = Constants.DEFAULT_ASPECT_RATIO;
        }
        adjustCameraParameters();
        mCamera.setDisplayOrientation(calcDisplayOrientation(mDisplayOrientation));
        mCallback.onCameraOpened();

        if (null != mRecordVideoManager) {
            mRecordVideoManager.onCameraOpened(mFacing);
        }
    }
  • 某360手機支持的預覽尺寸和保存尺寸,分組依據是寬高比,比如4:3和16:9

預覽尺寸保存尺寸

  • 再來看某華爲平板支持的預覽尺寸和保存尺寸,分組依據是寬高比,比如4:3和16:9

預覽尺寸保存尺寸

說的這裏就有個問題了,之前公司開發認爲有個bug是這款華爲平板拍照保存的照片尺寸太小,條件是分辨率≤1920 * 1080,但是他們限制了寬高比爲4:3所以取到的只有value[1]的4個分辨率,符合條件的最大分辨率爲640 * 480,導致照片不夠清晰以及一些其他問題,後來把寬高比限制爲4:3 or 16:9,就可以取到最符合的分辨率1920 * 1080了。


2、獲取滿足條件的預覽和保存照片的尺寸

我們獲取4:3 or 16:9的分辨率尺寸,我的最佳分辨率的算法是,在該設備下(屏幕固定),並限定寬高比的條件下,利用分辨率的面積(寬*高,可以理解爲像素的個數)和目標的分辨率面積,進行比對差值最小的即爲最佳分辨率。

    //用來比對的絕對值
    private int mPictureAbs = -1;

    /**
     * 設定相機相關參數,比如預覽和保存的圖片大小
     */
    private void adjustCameraParameters() {
        SortedSet<Size> previewSizes = new TreeSet<>();
        SortedSet<Size> pictureSizes = new TreeSet<>();
        AspectRatio aspectRatio4_3 = checkAspectRatio(Constants.DEFAULT_ASPECT_RATIO);
        AspectRatio aspectRatio16_9 = checkAspectRatio(Constants.SECOND_ASPECT_RATIO);
        //預覽圖片尺寸集合
        previewSizes.addAll(mPreviewSizes.sizes(aspectRatio4_3));
        previewSizes.addAll(mPreviewSizes.sizes(aspectRatio16_9));
        //保存圖片尺寸集合
        pictureSizes.addAll(mPictureSizes.sizes(aspectRatio4_3));
        pictureSizes.addAll(mPictureSizes.sizes(aspectRatio16_9));

        //預覽的尺寸集合,選擇最佳的預覽尺寸
        Size previewSize = chooseOptimalSize(previewSizes);

        // Always re-apply camera parameters
        if (mShowingPreview) {
            stopPreview();
        }

        Size pictureSize = pictureSizes.last();
        if (null == mRecordVideoManager) {
            for (Size tempSize : pictureSizes) {
                //根據像素點(面積)計算最符合目標的分辨率
                int referencePixels = MultiMediaConfig.MAX_PIC_WIDTH * MultiMediaConfig.MAX_PIC_HEIGHT;
                int picturePixels = tempSize.getWidth() * tempSize.getHeight();
                int abs = Math.abs(referencePixels - picturePixels);
                if (mPictureAbs < 0 || mPictureAbs > abs) {
                    mPictureAbs = abs;
                    pictureSize = tempSize;
                } else {
                    mPictureAbs = -1;
                    break;
                }
            }
            mCameraParameters.setPictureFormat(ImageFormat.JPEG);
            mCameraParameters.setJpegQuality(100);
            mCameraParameters.setPictureSize(pictureSize.getWidth(), pictureSize.getHeight());
        } else {
            mRecordVideoManager.setPreviewSize(previewSize);
        }

        mCameraParameters.setPreviewSize(previewSize.getWidth(), previewSize.getHeight());
        mCameraParameters.setRotation(calcCameraRotation(mDisplayOrientation));

        setAutoFocusInternal(mAutoFocus);
        setFlashInternal(mFlash);
        mCamera.setParameters(mCameraParameters);
        if (mShowingPreview) {
            startPreview();
        }
    }

檢查相機是否支持該寬高比

    /**
     * 檢查相機是否支持該寬高比
     *
     * @param mAspectRatio
     * @return
     */
    private AspectRatio checkAspectRatio(AspectRatio mAspectRatio) {
        AspectRatio r = null;
        for (AspectRatio ratio : mPreviewSizes.ratios()) {
            r = ratio;
            if (ratio.equals(mAspectRatio)) {
                return ratio;
            }
        }
        return r;
    }

獲取最佳的預覽尺寸

    //用來比對的絕對值
    private int mPreviewAbs = -1;

    /**
     * 設置最佳顯示尺寸
     *
     * @param sizes
     * @return
     */
    @SuppressWarnings("SuspiciousNameCombination")
    private Size chooseOptimalSize(SortedSet<Size> sizes) {
        if (!mPreview.isReady()) { // Not yet laid out
            return sizes.last(); // Return the smallest size
        }

        int surfaceWidth = mPreview.getWidth();
        int surfaceHeight = mPreview.getHeight();
        Size result = sizes.last();
        for (Size size : sizes) {
            //根據像素點(面積)計算最符合目標的分辨率
            int referencePixels = surfaceWidth * surfaceHeight;
            int picturePixels = size.getWidth() * size.getHeight();
            int abs = Math.abs(referencePixels - picturePixels);
            if (mPreviewAbs < 0 || mPreviewAbs > abs) {
                mPreviewAbs = abs;
                result = size;
            } else {
                mPreviewAbs = -1;
                break;
            }
        }
        return result;
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章