Предварительный просмотр в API Camera2 при программном создании макета - PullRequest
0 голосов
/ 07 декабря 2018

После обновления нашего приложения мы теперь используем API-интерфейс Camera2, к сожалению, предварительный просмотр загружен на нашем тестовом устройстве: Samsung SM-J330F / DS, Android-версия 8.0.0, API 26

.не испытывайте эту проблему с проектом Googles Camera2Basic на одном устройстве, мы попытались настроить наш проект так, чтобы он использовал те же реализации предварительного просмотра.В настоящее время мы просто не можем выяснить точную причину различных предварительных просмотров между обоими проектами.

Streched preview experienced with our preview.

Это ожидается:

Correct preview of the Camera2Basic project on the same device

В отличие от проекта Camera2Basic наш RelativeLayout создается программно в классе Activity, а затем к этому объекту добавляется 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.

Позже в классе Camera2 после установки предварительного просмотра в setUpCameraOutputs() равным 640x480 px (разрешение, которое должно поддерживаться всеми устройствами) мы будем называть setAspectRatio(width, height) в mPreview:

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 голосов
/ 19 июля 2019

Решением этой проблемы было вызвать следующую функцию в 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);
}
0 голосов
/ 14 декабря 2018

Я думаю, проблема в том, что вы установили значение mPreviewSize.По этой причине предварительный просмотр камеры в некоторых устройствах с разрешением более 640 * 480.

mPreviewSize должен быть такого же размера, как AutoFitTextureView.

mPreviewSize = new Size(mPreview.getHeight(), mPreview.getWidth());
.
...