Camera - SurfaceView displays stretched preview

Hello!

I’m having a hard time getting the right ratio to display in a SurfaceView. At the moment the SurfaceView is full screen.

I am using CameraSource from com.google.android.gms.vision.CameraSource and it has a method setRequestedPreviewSize(width, height). I am not using and would rather not use CameraX as it’s still in beta.

My problem is that on different devices the preview is stretched. I’ve tried some approaches but didn’t manage to get it right.

My layout looks like this (with some other views that are not relevant):

<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width=“match_parent”
android:layout_height=“match_parent”
android:animateLayoutChanges=“true”>

    <SurfaceView
        android:id="@+id/surfaceView_camera"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
       
        .......

</androidx.constraintlayout.widget.ConstraintLayout>

At the moment the best results I managed to get were using something like this:

  • use an initial width x height of 1920 x 1080
  • calculate the screen ratio using screen height/screen width, resulting in ratio X
  • use that ratio, ratio X, to calculate a resized width/height

This works on some of the devices, that have a bigger height/width ratio, but not on devices that have a smaller height/width ratio.

Any tips would help. I’m missing something, but I cannot figure it out. Thank you in advance! :grinning:

Then I really recommend that you use Fotoapparat, CameraKit/Android, or another higher-level library for taking pictures. I cover those two in The Busy Coder’s Guide to Android Development, though that material is a few years old now.

IOW, if you are doing the SurfaceView yourself, you’re hopefully doing it wrong.

This sort of challenge is one of the reasons why I abandoned my own pair of camera libraries and is one of the reasons why I very firmly steer developers towards libraries that have some sort of camera preview widget.

If you are running into the sorts of problems that I was with similar symptoms, your issue may be that the camera preview is based on the camera’s aspect ratio, which is not strictly related to the screen’s aspect ratio and will depend a bit on what camera settings you are using. You would need to try to find the SurfaceView size that maintains the camera’s aspect ratio yet fits maximally within the available space for the SurfaceView (which may be completely unrelated to the screen size, such as in split-screen mode, freeform multi-window like Chrome OS, foldables, etc.).

The problem with using libraries is that I also need the OCR function of CameraSource. CameraSource.Builder takes a TextRecognizer as a parameter to it. So I guess I’ll try the camera’s aspect ratio approach.

Ah, OK. I thought perhaps you were just trying to use something Googly.

Sorry I don’t get this :sweat_smile:

You originally wrote:

Since CameraX was an option (“it’s still in beta”), and since you chose com.google.android.gms.vision, I assumed that your focus was on choosing something written by Google.

If you need OCR, I’m not certain if that’s an available option with CameraX, though I have not checked recently.

Got it! Thanks! Hopefully I’ll manage to keep the camera’s aspect ratio…