Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🐛 Android- frame processor alway return wrong width/height of frame #746

Closed
3 of 4 tasks
vanhungoz opened this issue Jan 17, 2022 · 24 comments · Fixed by #1466
Closed
3 of 4 tasks

🐛 Android- frame processor alway return wrong width/height of frame #746

vanhungoz opened this issue Jan 17, 2022 · 24 comments · Fixed by #1466
Labels
🤖 android Issue affects the Android platform 🐛 bug Something isn't working

Comments

@vanhungoz
Copy link

What were you trying to do?

i try to use frame to recognize face

Reproduceable Code

const frameProcessor = useFrameProcessor(frame => {
    'worklet';
    console.log('frame.width', frame.width);
    console.log('frame.height', frame.height);
  }, []);

What happened instead?

frame data alway wrong.
camera's orientation is portrait
device's orientation is portrait.

Relevant log output

LOG  frame.width 1280
LOG  frame.height 720

Device

pixel 3L. Android 12

VisionCamera Version

2.12.0

Additional information

@vanhungoz vanhungoz added the 🐛 bug Something isn't working label Jan 17, 2022
@vanhungoz
Copy link
Author

1
frame preview is showing correctly. But frame data may be wrong
it is only happening on Android. iOS is working correctly

@mrousavy mrousavy added the 🤖 android Issue affects the Android platform label Jan 17, 2022
@vanhungoz
Copy link
Author

it failed on both front and back camera.

@mrousavy
Copy link
Owner

Okay, maybe this commit broke something: 48da181

@vanhungoz
Copy link
Author

@mrousavy thank you for your quick response.

i have checked "react-native-vision-camera": "2.11.1",
i still got the same error

@vanhungoz
Copy link
Author

i checked release history, orientation is added from version 2.11.2

@mrousavy
Copy link
Owner

I mean technically it would be correct. The width is always the physical sensor width. But I agree that we can use the logical term width and height instead, just like on iOS

@mrousavy
Copy link
Owner

I just wonder where it goes wrong, here we set the target rotation:

val imageAnalysisBuilder = ImageAnalysis.Builder()
.setTargetRotation(outputRotation)

Could you maybe check here what image.width is?

setAnalyzer(cameraExecutor, { image ->
val now = System.currentTimeMillis()
val intervalMs = (1.0 / actualFrameProcessorFps) * 1000.0
if (now - lastFrameProcessorCall > intervalMs) {
lastFrameProcessorCall = now
val perfSample = frameProcessorPerformanceDataCollector.beginPerformanceSampleCollection()
frameProcessorCallback(image)
perfSample.endPerformanceSampleCollection()
}
image.close()
if (isReadyForNewEvaluation) {
// last evaluation was more than a second ago, evaluate again
evaluateNewPerformanceSamples()
}
})

@vanhungoz
Copy link
Author

ok, thank you, i'll check it and tell you

@vanhungoz
Copy link
Author

@mrousavy it alway log 1280 as same as frame.width

@bkidai
Copy link

bkidai commented Jan 17, 2022

@vanhungoz @mrousavy isn't the wrong with/height It's because on Android the frame it's rotated by 90° degree (i'm having the same issue) even before the last commit #715

Btw, i have the same output when i use orientation="portrait"
console.log(frame.toString());
1280 x 720 Frame // output

@vanhungoz
Copy link
Author

vanhungoz commented Jan 18, 2022

@bkidai have you tested with older version. Which version could we use to check frame processor with correct frame?

@vanhungoz
Copy link
Author

@vanhungoz @mrousavy isn't the wrong with/height It's because on Android the frame it's rotated by 90° degree (i'm having the same issue) even before the last commit #715

Btw, i have the same output when i use orientation="portrait" console.log(frame.toString()); 1280 x 720 Frame // output

@bkidai have you found any workaround?

@bkidai
Copy link

bkidai commented Jan 19, 2022

@vanhungoz i rotate the image based on the ImageProxy.imageInfo.rotationDegrees natively in Android before using it

@vanhungoz
Copy link
Author

@mrousavy do you have any suggest to find out this bug?

@vanhungoz
Copy link
Author

vanhungoz commented Jan 24, 2022

matrix.setRotate((360- image.imageInfo.rotationDegrees).toFloat())
val rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix,true)

@bkidai could you share your code.
i'm rotating the image by this function

@bkidai
Copy link

bkidai commented Jan 24, 2022

@vanhungoz here's my code
Btw, it take a "long" time to rotate the images

matrix.postRotate(rotationDegrees.toFloat())
val rotatedBitmap = Bitmap.createBitmap(bitmap, 0, 0, image.width, image.height, matrix, true)

@vanhungoz
Copy link
Author

thank you, the same as me

@xulihang
Copy link
Contributor

If we rotated the image on the Android side, the frame.width is still wrong on the JavaScript side. Maybe frame should have a rotationDegrees prop.

@xulihang
Copy link
Contributor

xulihang commented Feb 11, 2022

In order to show barcode overlays, I rotated the image on the Android side using the yuv2bitmap converting code from here: https://blog.minhazav.dev/how-to-convert-yuv-420-sp-android.media.Image-to-Bitmap-or-jpeg/#pure-java-approach

I then use Dimensions to infer whether I should switch frame width and frame height:

    if (frameWidth>frameHeight && Dimensions.get('window').width>Dimensions.get('window').height){
      viewBox = "0 0 "+frameWidth+" "+frameHeight;
    }else {
      console.log("Has rotation");
      viewBox = "0 0 "+frameHeight+" "+frameWidth;
    }    

Full example: https://github.com/xulihang/vision-camera-dynamsoft-barcode-reader/tree/main/example

@mrousavy
Copy link
Owner

Maybe this fixes the problem: #816

@xulihang
Copy link
Contributor

The new setOutputImageRotationEnabled API used in the pr seems the correct way.

@yachaka
Copy link

yachaka commented Feb 22, 2022

I had the same issue
So I did

// If frame is inverted  
// This happens on Pixel 2, width and height are inverted
        if (screenWidth < screenHeight && frameWidth > frameHeight
            || ( screenWidth > screenHeight && frameWidth < frameHeight)) {
            const tmp = frameWidth;
            frameWidth = frameHeight;
            frameHeight = tmp;
        }

@mrousavy
Copy link
Owner

Hey! I've rewritten the entire Android codebase of VisionCamera from CameraX to Camera2 in the efforts of ✨ VisionCamera V3.

I just now completed the Camera2 rewrite and I believe the core structure is running, but there might be some edge cases to iron out. Can you try and test the PR #1674 for me to see if you can still reproduce this issue here?

Here's an instruction on how you can test that: #1674 (comment)

If the issue cannot be reproduced with that version/PR anymore, then hoorayy, I fixed it! 🎉
Otherwise please let me know and I'll keep this issue open to keep track of it.

Thank you!

@mrousavy
Copy link
Owner

Hey - I'm tracking Orientation in this feature request/issue now: #1891

Make sure to upvote or sponsor to support this feature, and leave a comment if you have any additional thoughts/ideas.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
🤖 android Issue affects the Android platform 🐛 bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants