mrousavy / react-native-vision-camera

šŸ“ø A powerful, high-performance React Native Camera library.
https://react-native-vision-camera.com
MIT License
7.28k stars 1.07k forks source link

šŸ› Wrong Orientation on `takePhoto` (`takeSnapshot` is working properly) #3140

Open frodriguez-hu opened 4 weeks ago

frodriguez-hu commented 4 weeks ago

What's happening?

I am doing the processing listed below to the photo taken by takePhoto or takeSnapshot.

When I use takePhoto I have to invert the height and width of the photo in order to make the calculations of the scale factors, that is happening on Android and IOS as well. Then in IOS it works fine, the x represents the X axis and the Y represents the y axis. But in android when I am going to crop the image, the X is modifying the Y axis and the Y modifying the X axis, I think that is an issue on how the photo that is coming from takePhoto.

But let's say it is okey and you handle that axis rotation, the Y axis is coming on a different proportion cause the cropping is cropping it in the middle of the face, which it should not happen like that. (Those are not issues from Image Editor cause it is working fine on other pictures).

The code below it is working since it is using takeSnapshot, shouldn't work the same for takePhoto?

I think it is the same issue detailed here:

https://github.com/mrousavy/react-native-vision-camera/issues/2994

Reproduceable Code

const {x, y, height, width} = FACE_BOUNDS;
    const takenPhoto = await cameraRef?.current?.takeSnapshot({quality: 100});
    if (takenPhoto) {
      const scaleFactorY = takenPhoto.height / windowDimensions.height;
      const scaleFactorX = takenPhoto.width / windowDimensions.width;
      const croppedPhotoResult = await ImageEditor.cropImage(
        `file://${takenPhoto.path}`,
        {
          offset: {
            x: x * scaleFactorX,
            y: y * scaleFactorY,
          },
          size: {
            width: width * scaleFactorX,
            height: height * scaleFactorY,
          },
          displaySize: {
            width: 192,
            height: 192,
          },
        },
      );

### Relevant log output

```shell
i do not have significant logs here.

Camera Device

{
  "formats": [],
  "sensorOrientation": "landscape-right",
  "hardwareLevel": "limited",
  "maxZoom": 4,
  "minZoom": 1,
  "maxExposure": 20,
  "supportsLowLightBoost": true,
  "neutralZoom": 1,
  "physicalDevices": [
    "wide-angle-camera"
  ],
  "supportsFocus": true,
  "supportsRawCapture": false,
  "isMultiCam": false,
  "minFocusDistance": 10,
  "minExposure": -20,
  "name": "1 (FRONT) androidx.camera.camera2",
  "hasFlash": false,
  "hasTorch": false,
  "position": "front",
  "id": "1"
}

Device

Samsung S21 plus

VisionCamera Version

4.5.0

Can you reproduce this issue in the VisionCamera Example app?

No, I cannot reproduce the issue in the Example app

Additional information

maintenance-hans[bot] commented 4 weeks ago

Guten Tag, Hans here! šŸ»

Thanks for raising this issue. I see you have some concerns with the takePhoto function. However, it seems that you did not provide relevant logs or specific reproduction steps that could help mrousavy diagnose the problem. Logs from adb logcat or specific errors will give much better insight.

Please share those logs, and be sure to check if the issue persists when you use the example app. If this issue remains after that and you gather more information, feel free to reopen it!

Also, if you find this project helpful, consider sponsoring mrousavy here to ensure continued support and updates!

Note: If you think I made a mistake, please ping @mrousavy to take a look.

frodriguez-hu commented 4 weeks ago

@mrousavy Sorry to tag you I know it bothers you but the bot is asking me to do it

frodriguez-hu commented 4 weeks ago

Another thing to mention is that when I set isMirrored on false. the crop works but with the image inverted

mrousavy commented 3 weeks ago

The code below it is working since it is using takeSnapshot, shouldn't work the same for takePhoto?

Those two funcs are implemented very differently - takeSnapshot uses the preview stream on Android and the video stream on iOS, and takePhoto uses a photo queue.

Did you examine the EXIF values? Maybe width and height represent physical pixel width/height of the image, and if it is using EXIF flags to rotate the image then the physical pixel width/height is represented before any EXIF orientations are considered.

chandanpradhanin commented 3 weeks ago

@mrousavy I am also getting same issue with the takePhoto function

rsainiWin commented 3 weeks ago

Also facing the same on Android

stewartiee commented 2 weeks ago

I'm having the same issue on Android.

It's a bit strange though as it works correctly on one Android device, but not the other. So on one device (Samsung A54), it is captured in landscape, and the final image is landscape. The other (Pixel 3) is captured in landscape, but the final image is portrait.

Using: outputOrientation: 'preview'

dorakadri commented 1 week ago

any updates im facing the same issue

mannoeu commented 1 week ago

same here