7

I want to capture photos with fixed resolution (i.e. 1200x1600) using CameraX library.

So according to documentation I can set target resolution for ImageCaptureConfig:

val imageCaptureConfig = ImageCaptureConfig.Builder()
    .setLensFacing(CameraX.LensFacing.BACK)
    .setCaptureMode(ImageCapture.CaptureMode.MAX_QUALITY)
    .setTargetResolution(Size(1200, 1600))
    .setTargetAspectRatio(Rational(3,4))
    .build()

Documentation describes setTargetResolution method as follows:

Sets the intended output target resolution.

The target resolution attempts to establish a minimum bound for the image resolution. The actual image resolution will be the closest available resolution in size that is not smaller than the target resolution, as determined by the Camera implementation. However, if no resolution exists that is equal to or larger than the target resolution, the nearest available resolution smaller than the target resolution will be chosen.

Correct me if I am wrong, but if device is able to take photos larger than 1200x1600 (e.g. 3024x4032), the output photo will be at least 1200x1600.

Unfortunately in many devices (e.g. Huawei P20 Pro, Samsung A5) the output photo is significantly smaller than 1200x1600, e.g. 480x640. Notice that these devices are able to take really large photos.

Is my ImageCaptureConfig badly configured or this is a bug?

Nominalista
  • 4,632
  • 11
  • 43
  • 102
  • 1
    Any chances that there's a regression of this issue? We are seeing this right now with the front camera of an Alcatel, trying to set up 720 x 1280 with Camera X results in a weird lower resolutions, but the same device with other apps non based on Camera X can use 720 x 1280 with no issues it seems. – Fran Marzoa Aug 06 '21 at 11:00
  • 1
    @FranMarzoa Same issue happens here. Do you find any solutions? – ch271828n Jan 18 '22 at 13:54
  • 1
    @ch271828n sorry, unfortunately no, I didn't. I only needed to capture one frame, so as a workaround I use lower resolution for preview and analysis, but then the last frame is taken with the image capture use case, which does higher resolution. – Fran Marzoa Jan 19 '22 at 16:38

3 Answers3

3

The android documentation say this:

You cannot set both target aspect ratio and target resolution on the same use case. Doing so will throw an IllegalArgumentException when building the config object.

So decide what is mor important for you and choose only one.

Irving Dev
  • 389
  • 2
  • 8
  • 1
    Thanks for response. It turned to be a bug, mentioned here: https://stackoverflow.com/a/57288661/4386668. FYI - at the time of writing this question, it wasn't an issue to set both aspect ratio and target resolution. – Nominalista Jul 30 '20 at 06:43
2

It could be a bug that have been recently fixed at AOSP. refer https://android.googlesource.com/platform/frameworks/support/+/5c1aed8c4c502a74eb4ee6d30fe2089f4afcaf11

Wasim Ansari
  • 305
  • 1
  • 9
  • Thanks! Do you know if this fix will be available in next version? – Nominalista Jul 31 '19 at 11:01
  • @Wasim Ansari will you tell me in which class have solution in this repository? – EAS Jan 18 '22 at 10:34
  • Hi same issue happens here. Is it a regression or is that deployed? – ch271828n Jan 18 '22 at 13:54
  • Why is it so hard/difficult to just crop the image using the specified resolution after taking the picture, instead of ignoring what we pass to `setTargetResolution`? I swear, Google pisses me off sometimes. – TheRealChx101 Sep 21 '22 at 11:03
1

When you use .setTargetResolution(Size), the resolution Size should be expressed in the coordinate frame after rotating the supported sizes by the target rotation.

For example, a device with portrait natural orientation in natural target rotation requesting a portrait image may specify 480x640, and the same device, rotated 90 degrees and targeting landscape orientation may specify 640x480.

So this in Portait:

val imageCaptureConfig = ImageCaptureConfig.Builder()
    .setTargetResolution(Size(1200, 1600))

Became that in Landscape:

val imageCaptureConfig = ImageCaptureConfig.Builder()
    .setTargetResolution(Size(1600, 1200))

Be careful of the orientation of your device:

fun getTargetResolution(): Size {
    return when (resources.configuration.orientation) {
        Configuration.ORIENTATION_PORTRAIT -> Size(1200, 1600)
        Configuration.ORIENTATION_LANDSCAPE -> Size(1600, 1200)
        else -> Size(1600, 1200)
    }
}

fun setupCamera() {
    ...
    val resolution = getTargetResolution()
    val imageCaptureConfig = ImageCaptureConfig.Builder()
        .setTargetResolution(resolution)
    ...
}

It is the same thing with ImageAnalysis and ImagePreview

If you want some documentation, go here

Raph Mrci
  • 11
  • 4