diff --git a/ElementX/Sources/Services/Media/MediaUploadingPreprocessor.swift b/ElementX/Sources/Services/Media/MediaUploadingPreprocessor.swift index 0f967d8a5d..9a9b0bcefc 100644 --- a/ElementX/Sources/Services/Media/MediaUploadingPreprocessor.swift +++ b/ElementX/Sources/Services/Media/MediaUploadingPreprocessor.swift @@ -449,10 +449,22 @@ struct MediaUploadingPreprocessor { private extension CGImageSource { var size: CGSize? { guard let properties = CGImageSourceCopyPropertiesAtIndex(self, 0, nil) as? [NSString: Any], - let width = properties[kCGImagePropertyPixelWidth] as? Int, - let height = properties[kCGImagePropertyPixelHeight] as? Int else { + var width = properties[kCGImagePropertyPixelWidth] as? Int, + var height = properties[kCGImagePropertyPixelHeight] as? Int else { return nil } + + // Make sure the width and height are the correct way around if an orientation is set. + if let orientationValue = properties[kCGImagePropertyOrientation] as? UInt32, + let orientation = CGImagePropertyOrientation(rawValue: orientationValue) { + switch orientation { + case .up, .down, .upMirrored, .downMirrored: + break + case .left, .right, .leftMirrored, .rightMirrored: + swap(&width, &height) + } + } + return CGSize(width: width, height: height) } } diff --git a/UnitTests/Resources/Media/test_rotated_image.jpg b/UnitTests/Resources/Media/test_rotated_image.jpg new file mode 100644 index 0000000000..6169c3717d --- /dev/null +++ b/UnitTests/Resources/Media/test_rotated_image.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:094ceac734f4461ae9f1c47eae58c13270da6f407718b12e3142cac3dc0b38a7 +size 1735894 diff --git a/UnitTests/Sources/MediaUploadingPreprocessorTests.swift b/UnitTests/Sources/MediaUploadingPreprocessorTests.swift index 7438c3a84c..a9aa74bd59 100644 --- a/UnitTests/Sources/MediaUploadingPreprocessorTests.swift +++ b/UnitTests/Sources/MediaUploadingPreprocessorTests.swift @@ -422,6 +422,46 @@ final class MediaUploadingPreprocessorTests: XCTestCase { XCTAssertEqual(optimizedImageInfo.height, 498) } + func testRotatedImageProcessing() async { + guard let url = Bundle(for: Self.self).url(forResource: "test_rotated_image.jpg", withExtension: nil) else { + XCTFail("Failed retrieving test asset") + return + } + + guard case let .success(result) = await mediaUploadingPreprocessor.processMedia(at: url), + case let .image(convertedImageURL, thumbnailURL, imageInfo) = result else { + XCTFail("Failed processing asset") + return + } + + compare(originalImageAt: url, toConvertedImageAt: convertedImageURL, withThumbnailAt: thumbnailURL) + + // Check resulting image info + XCTAssertEqual(imageInfo.mimetype, "image/jpeg") + XCTAssertEqual(imageInfo.width, 2848) + XCTAssertEqual(imageInfo.height, 4272) + + XCTAssertNotNil(imageInfo.thumbnailInfo) + XCTAssertEqual(imageInfo.thumbnailInfo?.width, 533) + XCTAssertEqual(imageInfo.thumbnailInfo?.height, 800) + + // Repeat with optimised media setting + appSettings.optimizeMediaUploads = true + + guard case let .success(optimizedResult) = await mediaUploadingPreprocessor.processMedia(at: url), + case let .image(optimizedImageURL, thumbnailURL, optimizedImageInfo) = optimizedResult else { + XCTFail("Failed processing asset") + return + } + + compare(originalImageAt: url, toConvertedImageAt: optimizedImageURL, withThumbnailAt: thumbnailURL) + + // Check optimised image info + XCTAssertEqual(optimizedImageInfo.mimetype, "image/jpeg") + XCTAssertEqual(optimizedImageInfo.width, 1365) + XCTAssertEqual(optimizedImageInfo.height, 2048) + } + // MARK: - Private private func compare(originalImageAt originalImageURL: URL, toConvertedImageAt convertedImageURL: URL, withThumbnailAt thumbnailURL: URL) {