Search code examples
androidandroid-layoutandroid-cameracamera-apicamera-view

Fotoapparat: Why does landscape CameraView captures in portrait mode?


I have implenented the Fotoapparat library to my app. To operate the whole app with one hand, I am trying to make the CameraView in a portrait mode parents ConstraintLayout. As you can see in the following screenshot, the CameraView itself is landscape, but the parent ConstraintLayout of the whole Fragment is portrait mode, so that user can operate app with one hand: One hand hold to capture landscape As you can see the CameraView is modelled in lanscape, of course this would mean a bit lost of quality.

Then I capture an image and show the captured image in the next fragment.. As you can see, the captured image is portrait mode now: Captured images shown in portrait

As you can see the difference, I captured the smartphones plastic cap also in landscape. The left and right corners fit very well. But the images top and bottom part have definetily more pixels than shown in the preview in the previous fragment.

I create the Fotoapparart object like:

fotoapparat = Fotoapparat
                .with(activity)
                .into(cameraView)
                .focusView(focusView)
                .sensorSensitivity(highestSensorSensitivity())
                .focusMode(firstAvailable(
                        FocusModeSelectorsKt.continuousFocusPicture(),
                        FocusModeSelectorsKt.autoFocus()))
                .lensPosition(back())
                .build();

my layout is like:

<io.fotoapparat.view.CameraView
    android:id="@+id/myapp_camera_view"
    android:layout_width="0dp"
    android:layout_height="0dp"
    android:layout_marginStart="@dimen/myapp_border_margin"
    android:layout_marginEnd="@dimen/myapp_border_margin"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintDimensionRatio="1.778"
    app:layout_constraintBottom_toTopOf="@+id/myapp_border"
    app:layout_constraintTop_toBottomOf="@id/myapp_holder"
    app:layout_constraintVertical_bias="0.5">

    <io.fotoapparat.view.FocusView
        android:id="@+id/myapp_focus_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    />

</io.fotoapparat.view.CameraView>

and here I have the takePhoto function:

void takePicture(final boolean fotoapparatIsStopped) {
    if (!fotoapparatIsStopped) {
        PhotoResult photoResult = fotoapparat.takePicture();

        photoResult.toBitmap()
        .whenDone(new WhenDoneListener<BitmapPhoto>() {
            @Override
            public void whenDone(@Nullable BitmapPhoto photo) {
                this.bitmapPhoto = photo;
            }
        });
    }
}

Versions: Fotoapparat 2.4.0 Java SDK 8 Android Studio 3.2

What am I dong wrong?

or with other words:

How can I capture a landscape crop while holding the camera/smartphone portrait?


Solution

  • I think Fotoapparat does not provide this functionality out of the box. You might have to do it manually by rotating the bitmap itself:

    // rotate Bitmap by means of rotation matrix    
    public void whenDone(@Nullable BitmapPhoto photo) {
        Matrix rotationMatrix = new Matrix();
        rotationMatrix.postRotate(phi); // int phi is the angle, here 90
    
        Bitmap landscapeBitmap = Bitmap.createBitmap(photo.bitmap, 0, 0, photo.bitmap.getWidth(), photo.bitmap.getHeight(), rotationMatrix, true);
        this.bitmapPhoto = new BitmapPhoto(landscapeBitmap, 0);
    }