设定相机预览和保存照片尺寸

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;
    }

猜你喜欢

转载自blog.csdn.net/m0_37168878/article/details/80738266