如何改变camera2 preview的宽高比?

时间:2016-12-19 11:09:22

标签: android android-camera2

我尝试更改Camera2预览的宽高比,但我失败了: - (

对于裁剪,我必须使用SCALER_CROP_REGION,但我不能正常工作。

我使用Google的android-Camera2Video示例进行测试。

openCamera方法中,我添加了以下行:

mSensorSize = characteristics.get(CameraCharacteristics.SENSOR_INFO_ACTIVE_ARRAY_SIZE);

startPreview我添加了这个:

final int centerX = mSensorSize.width() / 2;
final int centerY = mSensorSize.height() / 2;
final int cropSize = Math.min(mSensorSize.width(), mSensorSize.height());
final Rect crop = new Rect(centerY - cropSize / 2,
                           centerX - cropSize / 2,
                           cropSize,
                           cropSize);
mPreviewBuilder.set(CaptureRequest.SCALER_CROP_REGION, crop);

我应该以1:1的比例进行预览,但它是3:4: - (

我错了什么?

1 个答案:

答案 0 :(得分:1)

您可以尝试更改AutofitTextureView类中的onMeasure方法

public class AutoFitTextureView extends TextureView {

    int maxwidth = 0;
    int maxheight = 0;
    private int mRatioWidth = 0;
    private int mRatioHeight = 0;
    private Size previewSize;

    public AutoFitTextureView(Context context) {
        this(context, null);
    }

    public AutoFitTextureView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    public void setAspectRatio(int width, int height, int maxwidth, int maxheight, Size preview) {
        if (width < 0 || height < 0) {
            throw new IllegalArgumentException("Size cannot be negative.");
        }
        mRatioWidth = width;
        mRatioHeight = height;
        this.maxwidth = maxwidth;
        this.maxheight = maxheight;
        this.previewSize = preview;
        enterTheMatrix();
        requestLayout();
    }



    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);

        int width = MeasureSpec.getSize(widthMeasureSpec);
        int height = MeasureSpec.getSize(heightMeasureSpec);
        boolean isFullBleed = true;
        if (0 == mRatioWidth || 0 == mRatioHeight) {
            setMeasuredDimension(width, height);
        } else {
            setMeasuredDimension(height * mRatioWidth / mRatioHeight,height);
         }

    }


    private void adjustAspectRatio(int previewWidth,
                                   int previewHeight,
                                   int rotation) {
        Matrix txform = new Matrix();
        int viewWidth = getWidth();
        int viewHeight = getHeight();
        RectF rectView = new RectF(0, 0, viewWidth, viewHeight);
        float viewCenterX = rectView.centerX();
        float viewCenterY = rectView.centerY();
        RectF rectPreview = new RectF(0, 0, previewHeight, previewWidth);
        float previewCenterX = rectPreview.centerX();
        float previewCenterY = rectPreview.centerY();

        if (Surface.ROTATION_90 == rotation ||
                Surface.ROTATION_270 == rotation) {
            rectPreview.offset(viewCenterX - previewCenterX,
                    viewCenterY - previewCenterY);

            txform.setRectToRect(rectView, rectPreview,
                    Matrix.ScaleToFit.FILL);

            float scale = Math.max((float) viewHeight / previewHeight,
                    (float) viewWidth / previewWidth);

            txform.postScale(scale, scale, viewCenterX, viewCenterY);
            txform.postRotate(90 * (rotation - 2), viewCenterX,
                    viewCenterY);
        } else {
            if (Surface.ROTATION_180 == rotation) {
                txform.postRotate(180, viewCenterX, viewCenterY);
            }
        }

        if (LollipopCamera.type == 1) {
            txform.postScale(-1, 1, viewCenterX, viewCenterY);
        }

        setTransform(txform);
    }

    private void enterTheMatrix() {
        if (previewSize != null) {
            adjustAspectRatio(mRatioWidth,
                    mRatioHeight,
                    ((Activity) getContext()).getWindowManager().getDefaultDisplay().getRotation());
        }
    }
}

这是在应用上述方法之前 enter image description here

这是在应用上述方法之后 enter image description here
Camera2Video google sample

我还删除了fragment_camera2_video.xml

中的两行
 android:layout_below="@id/texture"
    android:background="#4285f4"

我从我的相机Fragment调用setAspectRation,如下所示

  mPreviewSize = chooseOptimalSize(map.getOutputSizes(ImageFormat.JPEG),
                        rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
                        maxPreviewHeight, largest);

                // We fit the aspect ratio of TextureView to the size of preview we picked.
                int orientation = getResources().getConfiguration().orientation;
                if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
                    mTextureView.setAspectRatio(
                            mPreviewSize.getWidth(), mPreviewSize.getHeight(), universal_width, universal_height, largest);
                } else {
                    mTextureView.setAspectRatio(
                            mPreviewSize.getHeight(), mPreviewSize.getWidth(), universal_width, universal_height, largest);
                }