diff options
author | Bartlomiej Moskal <bartlomiej.moskal@qt.io> | 2023-05-09 14:25:28 +0200 |
---|---|---|
committer | Bartlomiej Moskal <bartlomiej.moskal@qt.io> | 2023-05-12 07:59:53 +0200 |
commit | 2bcc7235c0f09b93782dd0ed0f91e648a2b32eaa (patch) | |
tree | bbddf359f64af98386eab191c310d5e870a26e1f | |
parent | 0e059191ad63873a5c4664249495cec99baf77ab (diff) | |
download | qtmultimedia-2bcc7235c0f09b93782dd0ed0f91e648a2b32eaa.tar.gz |
Android-backend: Fix for Captured Image rotation
When using android-camera backend, the result photo was not correctly
rotated for landscape orientation.
Preview rotation is handled by [0]setDisplayOrientation method, but it
does not affect taking pictures and recording. Recording is handled by
[1]setOrientationHint.
Both mentioned methods use QAndroidCameraSession::currentCameraRotation
for rotate correction. It is reasonable to handle photo rotation in the
same way.
This commit removes a special rotation handling from onPictureTaken java
method and move it to QAndroidCameraSession. That allows to handle photo
rotation in the same way as preview rotation and recording rotation.
https://developer.android.com/reference/android/hardware/Camera#setDisplayOrientation(int)
https://developer.android.com/reference/android/media/MediaRecorder#setOrientationHint(int)
Fixes: QTBUG-113029
Pick-to: 6.5 6.2
Change-Id: I2d08fef43fbd78faeafc7e20e100329e75019679
Reviewed-by: Lars Knoll <lars@knoll.priv.no>
-rw-r--r-- | src/android/jar/src/org/qtproject/qt/android/multimedia/QtCameraListener.java | 70 | ||||
-rw-r--r-- | src/plugins/multimedia/android/mediacapture/qandroidcamerasession.cpp | 16 |
2 files changed, 16 insertions, 70 deletions
diff --git a/src/android/jar/src/org/qtproject/qt/android/multimedia/QtCameraListener.java b/src/android/jar/src/org/qtproject/qt/android/multimedia/QtCameraListener.java index e1391142c..cb0fcfa0e 100644 --- a/src/android/jar/src/org/qtproject/qt/android/multimedia/QtCameraListener.java +++ b/src/android/jar/src/org/qtproject/qt/android/multimedia/QtCameraListener.java @@ -9,15 +9,7 @@ import android.hardware.Camera.CameraInfo; import android.graphics.ImageFormat; import android.graphics.SurfaceTexture; import android.util.Log; -import java.io.File; -import java.io.FileOutputStream; import java.lang.Math; -import android.media.ExifInterface; -import java.io.ByteArrayOutputStream; -import java.lang.String; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.graphics.Matrix; public class QtCameraListener implements Camera.ShutterCallback, Camera.PictureCallback, @@ -172,68 +164,6 @@ public class QtCameraListener implements Camera.ShutterCallback, @Override public void onPictureTaken(byte[] data, Camera camera) { - File outputFile = null; - try { - outputFile = File.createTempFile("pic_", ".jpg", QtMultimediaUtils.getCacheDirectory()); - FileOutputStream out = new FileOutputStream(outputFile); - - // we just want to read the exif... - BitmapFactory.decodeByteArray(data, 0, data.length) - .compress(Bitmap.CompressFormat.JPEG, 10, out); - - ExifInterface exif = new ExifInterface(outputFile.getAbsolutePath()); - int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, - ExifInterface.ORIENTATION_UNDEFINED); - - int degree = 0; - - switch (orientation) { - case ExifInterface.ORIENTATION_ROTATE_90: - degree = 90; - break; - case ExifInterface.ORIENTATION_ROTATE_180: - degree = 180; - break; - case ExifInterface.ORIENTATION_ROTATE_270: - degree = 270; - break; - } - - Camera.CameraInfo info = new Camera.CameraInfo(); - Camera.getCameraInfo(m_cameraId, info); - - int rotation = (info.orientation - degree + 360) % 360; - - Bitmap source = BitmapFactory.decodeByteArray(data, 0, data.length); - Matrix matrix = new Matrix(); - matrix.postRotate(rotation); - - if (info.facing == CameraInfo.CAMERA_FACING_FRONT) { - matrix.postScale(-1, 1, source.getWidth() / 2.0f, source.getHeight() / 2.0f); - } - - Bitmap rotatedBitmap = Bitmap.createBitmap(source, 0, 0, source.getWidth(), - source.getHeight(), matrix, true); - - ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); - rotatedBitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); - byte[] byteArray = outputStream.toByteArray(); - - rotatedBitmap.recycle(); - source.recycle(); - - notifyPictureCaptured(m_cameraId, byteArray); - - return; - - } catch (Exception e) { - Log.w(TAG, "Error fixing bitmap orientation."); - e.printStackTrace(); - } finally { - if (outputFile != null && outputFile.exists()) - outputFile.delete(); - } - notifyPictureCaptured(m_cameraId, data); } diff --git a/src/plugins/multimedia/android/mediacapture/qandroidcamerasession.cpp b/src/plugins/multimedia/android/mediacapture/qandroidcamerasession.cpp index d6aee3aff..c1f661d28 100644 --- a/src/plugins/multimedia/android/mediacapture/qandroidcamerasession.cpp +++ b/src/plugins/multimedia/android/mediacapture/qandroidcamerasession.cpp @@ -660,6 +660,22 @@ void QAndroidCameraSession::onNewPreviewFrame(const QVideoFrame &frame) void QAndroidCameraSession::onCameraPictureCaptured(const QVideoFrame &frame) { + // Frame needs to be correctly rotated before image proccessing. We are using + // the same rotation angle that was used for preview with setDisplayOrientation + auto rotation = QVideoFrame::Rotation0; + switch (currentCameraRotation()) { + case 90: + rotation = QVideoFrame::Rotation90; + break; + case 180: + rotation = QVideoFrame::Rotation180; + break; + case 270: + rotation = QVideoFrame::Rotation270; + break; + } + const_cast<QVideoFrame&>(frame).setRotationAngle(rotation); + // Loading and saving the captured image can be slow, do it in a separate thread (void)QtConcurrent::run(&QAndroidCameraSession::processCapturedImage, this, m_currentImageCaptureId, frame, m_imageCaptureToBuffer, |