How do we detect the Orientation of Image captured using CameraX if Application's default orientation is set to Portrait Mode

有些话、适合烂在心里 提交于 2020-07-09 13:01:04

问题


Basically, My camera app is set to Portrait Mode. However, user can take photos in Potrait or landscape by rotating the phone accordingly (The app doesnt rotate).

So my question is, how can we find the captured image orientation?

I tried using DisplayManager.DisplayListener, however, it works only when orientation of app happens. Since I have blocked the orientation of app to portrait mode, it doesnt get any callbacks here.

I even tried using ExifInterface, however, it always gives 6 as rotation.

I am looking for solution using CameraX apis.


回答1:


I had this problem also. What solved it is by using the device sensor data to get the correct orientation, then set it in my imageCapture object. See snippet below.

        orientationEventListener = object : OrientationEventListener(context) {
            override fun onOrientationChanged(orientation: Int) {
                // Monitors orientation values to determine the target rotation value
                val rotation = if (orientation >= 45 && orientation < 135) {
                    Surface.ROTATION_270
                } else if (orientation >= 135 && orientation < 225) {
                    Surface.ROTATION_180
                } else if (orientation >= 225 && orientation < 315) {
                    Surface.ROTATION_90
                } else {
                    Surface.ROTATION_0
                }

                imageCapture?.setTargetRotation(rotation)
            }
        }

This is also the recommended approach from a similar issue in the Google Issue Tracker: https://issuetracker.google.com/issues/144944155




回答2:


Please follow the Official documentation of camerax:

By default, the camera rotation is set to match the default display's rotation during the creation of the use case. In this default case, CameraX produces outputs to allow the app to easily match what you would expect to see in the preview. You can change the rotation to a custom value to support multi-display devices by passing in the current display orientation when configuring use case objects or dynamically after they have been created.

You can use the default display rotation and/or the camerax metadata output combinations from Preview.PreviewOutput() to create transforms for GLSurfaceView display.

val previewConfig = PreviewConfig.Builder()
        .setTargetRotation(windowManager.defaultDisplay.rotation)
        .build()

Based on the set rotation, each use case will either rotate the image data directly or provide rotation metadata to the consumers of the non-rotated image data.

  • Preview: Metadata output is provided to create the right transforms for a GLSurfaceView display using Preview.PreviewOutput.getRotationDegrees().

  • ImageAnalysis: Metadata output is provided so that image buffer coordinates are known relative to display coordinates. The analyze() method provides a rotationDegrees parameter representing the rotation that needs to be applied to the image analysis data to match the viewfinder.

  • ImageCapture: The image Exif metadata will be altered to note the rotation setting.




回答3:


Try out this same in our case ExifInterface did't work.

private int getImgimageOrientation(){
final String[] imageColumns = { MediaStore.Images.Media._ID, MediaStore.Images.ImageColumns.ORIENTATION };
final String imageOrderBy = MediaStore.Images.Media._ID+" DESC";
Cursor cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
        imageColumns, null, null, imageOrderBy);

if(cursor.moveToFirst()){
    int orientation = cursor.getInt(cursor.getColumnIndex(MediaStore.Images.ImageColumns.ORIENTATION));
    cursor.close();
    return orientation;
} else {
    return 0;
}
}


来源:https://stackoverflow.com/questions/59572176/how-do-we-detect-the-orientation-of-image-captured-using-camerax-if-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!