summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartlomiej Moskal <bartlomiej.moskal@qt.io>2023-05-09 14:25:28 +0200
committerBartlomiej Moskal <bartlomiej.moskal@qt.io>2023-05-12 07:59:53 +0200
commit2bcc7235c0f09b93782dd0ed0f91e648a2b32eaa (patch)
treebbddf359f64af98386eab191c310d5e870a26e1f
parent0e059191ad63873a5c4664249495cec99baf77ab (diff)
downloadqtmultimedia-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.java70
-rw-r--r--src/plugins/multimedia/android/mediacapture/qandroidcamerasession.cpp16
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,