4

I am using the Camera2Basic example from Google Samples (https://github.com/googlesamples/android-Camera2Basic) to display a camera preview inside a fragment. This fragment contains a RelativeLayout and a custom AutoFitTextureView. The latter can be found on the link above. I have adjusted the layout to center the preview and remove control buttons:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/camera_rel">

    <uk.co.deluxe_digital.messngr.AutoFitTextureView
    android:id="@+id/texture"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_centerInParent="true"
    android:layout_centerHorizontal="true"
    android:layout_centerVertical="true" />

</RelativeLayout>

I have three total fragments that are displayed within a ViewPager. I did make some small changes to the Camera2BasicFragment to make it an android.support.v4.app.Fragment to work with my ViewPager and remove the buttons.

What I would like is to make the camera preview fill the entire screen. This is possible by stretching the preview image. That is not what I want. Does anyone know a way of scaling up the preview or TextureView so that the height of the preview matches the container even if the sides are cropped off. I would like it to fill the view and maintain aspect ratio. This would mean that some of the preview at either side is lost, but that is okay.

This is what I currently have: current incorrect display of camera preview

The FloatingActionButton takes care of capturing the image. That is on the main parent activity.

Even if you can point me in the right direction to working this out, that would be a huge help!

2 Answers2

5

I had a same problem, I was using the Google example and I adapted that to my project. To fix it I added an else option in configuredTransform method to scale correctly in vertical position.

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);
    } /*I added this else*/ else {
        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(0, centerX, centerY);

    }
    mTextureView.setTransform(matrix);
}
1

AutoFitTextureView extends TextureView to keep aspect ratio. If you want to fill the entire scree, just use:

<TextureView
    android:id="@+id/texture"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
 />
  • I have tried this, but it stretches the preview, making it distorted. I am looking for a way of scaling it up, fitting the screen whilst maintaining aspect ratio. –  Jan 22 '17 at 11:37
  • Then you should set transformation matrix: texturePreview.setTransform(matrix); example how to do that: https://android.googlesource.com/platform/packages/apps/Camera2/+/android-6.0.1_r63/src/com/android/camera/TextureViewHelper.java – Sergey Voloshyn Jan 22 '17 at 11:43
  • I switched to a TextureView then worked out by how much it was stretched upwards. I then stretched the width by the same amount. All is good for now. Thank you! –  Jan 22 '17 at 13:26
  • Mine is same issue. – Mohsin Oct 03 '17 at 14:01