9

I'm following the CameraX codelab and I'm getting a wrong aspect ratio on the preview even using setTargetAspectRatio and setTargetResolution methods.

private fun startCamera() {
    // Create configuration object for the viewfinder use case
    val previewConfig = PreviewConfig.Builder().apply {
        setTargetAspectRatio(Rational(1, 1))
        setTargetResolution(Size(640, 640))
    }.build()
    ...

And the layout is using a hardcoded size as presented in the codelab.

<TextureView
    android:id="@+id/view_finder"
    android:layout_width="640px"
    android:layout_height="640px"
    ...

It would be nice if the library had CameraTextureView and a property android:scaleType (similar to the existing for the ImageView) to adjust the preview to the preview size.

CameraX wrong aspect ratio

Vadim Kotov
  • 8,084
  • 8
  • 48
  • 62
nglauber
  • 18,674
  • 6
  • 70
  • 75

4 Answers4

21

did you try it?

    val metrics = DisplayMetrics().also { viewFinder.display.getRealMetrics(it) }
    val screenSize = Size(metrics.widthPixels, metrics.heightPixels)
    val screenAspectRatio = Rational(metrics.widthPixels, metrics.heightPixels)

    val viewFinderConfig = PreviewConfig.Builder().apply {
            //...
            setTargetResolution(screenSize)
            setTargetAspectRatio(screenAspectRatio)
            setTargetRotation(viewFinder.display.rotation)
        }.build()

    val preview = AutoFitPreviewBuilder.build(viewFinderConfig, viewFinder)

And AutoFitPreviewBuilder you can find here: https://gist.github.com/yevhenRoman/90681822adef43350844464be95d23f1

I would recommend you to set width and height for your TextureView using dp or constaraints. Let me know if it works for you, thanks!

yevhen_69
  • 560
  • 3
  • 9
  • 5
    Sorry. Also didn't work :( The preview stills stretched... Regarding the view size, I know that dp is the recommended approach, I'm just following the codelab. – nglauber May 23 '19 at 11:13
  • 1
    Strange things. It's alpha version, maybe it doesn't work on some devices now. Hope you will solve this issue, good luck! – yevhen_69 May 23 '19 at 11:22
  • 2
    @nglauber have you tried using the sample code? What happens if you clone and run this as-is: https://github.com/android/camera/tree/master/CameraXBasic – Oscar Wahltinez May 29 '19 at 01:43
  • 4
    @OscarWahltinez, the sample code works fine. After comparing both, I noticed that when I remove this call `preview.setOnPreviewOutputUpdateListener` the preview is not stretched anymore. Thanks for the tip. However, the whole preview (a rectangle) is positioned inside of the view (a rectangle), similar of the CENTER_INSIDE scale type for ImageView, and I'd like something similar to CENTER_CROP. This brings the second point of my question which is: it would be nice to have a CameraTextureView where we can set the scale type of the camera preview. – nglauber May 30 '19 at 10:27
  • Absolutely correct! Do note that it worked for me when the TextureView was made to fit the screen and status bar hidden. – cht Jul 09 '19 at 12:34
  • @nglauber did you ever find a way to crop "similar to CENTER_CROP"? I am having the same problem where the entire screen-shaped-rectangle is inside the square texture view. – Jacolack Aug 03 '19 at 16:34
  • 1
    @nglauber Nice point, I lost 5 hours trying to understand why was stretched. Removing setOnPreview made the trick – GMX Aug 07 '19 at 16:48
  • @nglauber my preview in stretched by height and compressed by width. I have made my library for camerax but can't resolve that particular issue. Here is my link to the library https://github.com/shubh261096/camerax. Please help! – Shubham Agrawal Dec 19 '19 at 07:43
  • setTargetAspectRatio requires a *int* of AspectRatio type, not rational, anymore :( – ch271828n Sep 19 '21 at 12:50
2

https://stackoverflow.com/a/49449986/9397052 there is a solution for a similar problem. After you decide on a resolution, don't use setTargetAspectRatio function; instead you should only use setTargetResolution. Then it should work the same.

f.khantsis
  • 3,256
  • 5
  • 50
  • 67
2

According to the official Android documentation: "It is not allowed to set both target aspect ratio and target resolution on the same use case."

Although the compiler does not throw an error if you attempt to do this, unexpected results can occur.

ihniwgo
  • 41
  • 5
0

You can set the aspect ratio of a TextureView with Matrix like this:

Matrix txform = new Matrix();
textureView.getTransform(txform);
txform.setScale((float) = videoWidth / viewWidth, (float) videoHeight / viewHeight);// aspect ratio
textureView.setTransform(txform); // apply matrix
Jack
  • 5,354
  • 2
  • 29
  • 54
  • Have you looked at the codelab I mentioned? Well, if you take a look at step 6, the `updateTransform` is updating the TextureView. I applied your suggestion to this method using `matrix.setScale(960f / 640, 720f / 640)` (960x720 is a valid camera resolution, and the texture size is 640x640) and did not work. The preview stills stretched. – nglauber May 23 '19 at 02:41
  • I think the stretched preview image could be a result of the `FixedSizeSurfaceTexture` which is returned by the `Preview.PreviewOutput`. It has a different aspect ratio than the preview which it is attached to. So I tried to scale it the way you already mentioned: `matrix.setScale((float) = videoWidth / viewWidth, (float) videoHeight / viewHeight)`, which did not solve the stretch effect – jns Jun 03 '19 at 21:22