以编程方式创建布局时预览在Camera2 API中拉伸

时间:2018-12-07 17:51:30

标签: java android android-camera android-camera2

在更新我们的应用程序之后,我们现在使用Camera2 API,不幸的是,在我们的测试设备上显示了预览:三星SM-J330F / DS,Android版本8.0.0,API 26

由于我们在同一设备上的Google Camera2Basic项目没有遇到此问题,因此我们尝试调整项目以使用与预览相同的实现。目前,我们只是无法弄清两个项目之间不同预览的确切原因。

Streched preview experienced with our preview.

这是预期的:

Correct preview of the Camera2Basic project on the same device

与Camera2Basic项目相反,我们在活动类中以编程方式创建了RelativeLayout,然后将AutoFitTextureView添加到了该对象:

mMainLayout = new FrameLayout(this);
mMainLayout.setBackgroundColor(Color.BLACK);
mMainLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT));

mPreview = new AutoFitTextureView(this);
mPreview.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
        LayoutParams.MATCH_PARENT, Gravity.TOP));

mMainLayout.addView(mPreview);
this.setContentView(mMainLayout);

AutoFitTextureView的实现与Camera2Basic项目中的实现相同。

setUpCameraOutputs()中的预览设置为640x480 px(所有设备均应支持的分辨率)后,在Camera2类中,我们在mPreview上调用setAspectRatio(width, height)

mPreviewSize = new Size(640, 480);

if (mFrameOrientation == Configuration.ORIENTATION_LANDSCAPE) {
    mTextureView.setAspectRatio(
        mPreviewSize.getWidth(), mPreviewSize.getHeight()
    );
} else {
    mTextureView.setAspectRatio(
        mPreviewSize.getHeight(), mPreviewSize.getWidth()
    );
}

注意:同样在较新的设备(如Honor 10)上,预览效果也不错。

2 个答案:

答案 0 :(得分:0)

我认为问题是您固定了QTEMP的值。因此,相机预览会在某些分辨率大于640 * 480的设备上进行。

mPreviewSize的大小应与mPreviewSize相同。

AutoFitTextureView

答案 1 :(得分:0)

解决此问题的方法是在openCamera()onSurfaceTextureSizeChanged()中调用以下函数:

/**
 * Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.
 * This method should be called after the camera preview size is determined in
 * setUpCameraOutputs and also the size of `mTextureView` is fixed.
 *
 * @param viewWidth  The width of `mTextureView`
 * @param viewHeight The height of `mTextureView`
 */
private void configureTransform(int viewWidth, int viewHeight) {
    Activity activity = getActivity();
    if (null == mTextureView || null == mPreviewSize || null == activity) {
        return;
    }
    int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
    Matrix matrix = new Matrix();
    RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
    RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
    float centerX = viewRect.centerX();
    float centerY = viewRect.centerY();
    if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
        bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
        matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
        float scale = Math.max(
                (float) viewHeight / mPreviewSize.getHeight(),
                (float) viewWidth / mPreviewSize.getWidth());
        matrix.postScale(scale, scale, centerX, centerY);
        matrix.postRotate(90 * (rotation - 2), centerX, centerY);
    } else if (Surface.ROTATION_180 == rotation) {
        matrix.postRotate(180, centerX, centerY);
    }
    mTextureView.setTransform(matrix);
}