diff --git a/CHANGELOG.md b/CHANGELOG.md index 75253c28a..1b463c943 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ All notable changes to this project will be documented in this file. - Collection / Info: edit MP4 metadata (date / location / title / description / rating / tags) - Widget: option to open collection on tap +### Fixed + +- rendering of panoramas with inconsistent metadata + ## [v1.7.1] - 2022-10-09 ### Added diff --git a/lib/model/panorama.dart b/lib/model/panorama.dart index f798c7cf1..981908ecd 100644 --- a/lib/model/panorama.dart +++ b/lib/model/panorama.dart @@ -15,8 +15,8 @@ class PanoramaInfo { factory PanoramaInfo.fromMap(Map map) { var cLeft = map['croppedAreaLeft'] as int?; var cTop = map['croppedAreaTop'] as int?; - final cWidth = map['croppedAreaWidth'] as int?; - final cHeight = map['croppedAreaHeight'] as int?; + var cWidth = map['croppedAreaWidth'] as int?; + var cHeight = map['croppedAreaHeight'] as int?; var fWidth = map['fullPanoWidth'] as int?; var fHeight = map['fullPanoHeight'] as int?; final projectionType = map['projectionType'] as String?; @@ -27,6 +27,41 @@ class PanoramaInfo { cTop = ((fHeight - cHeight) / 2).round(); } + // handle inconsistent sizing (e.g. rotated image taken with OnePlus EB2103) + if (cWidth != null && cHeight != null && fWidth != null && fHeight != null) { + final croppedOrientation = cWidth > cHeight ? Orientation.landscape : Orientation.portrait; + final fullOrientation = fWidth > fHeight ? Orientation.landscape : Orientation.portrait; + var inconsistent = false; + if (croppedOrientation != fullOrientation) { + // inconsistent orientation + inconsistent = true; + final tmp = cHeight; + cHeight = cWidth; + cWidth = tmp; + } + + if (cWidth > fWidth) { + // inconsistent full/cropped width + inconsistent = true; + final tmp = fWidth; + fWidth = cWidth; + cWidth = tmp; + } + + if (cHeight > fHeight) { + // inconsistent full/cropped height + inconsistent = true; + final tmp = cHeight; + cHeight = fHeight; + fHeight = tmp; + } + + if (inconsistent) { + cLeft = (fWidth - cWidth) ~/ 2; + cTop = (fHeight - cHeight) ~/ 2; + } + } + Rect? croppedAreaRect; if (cLeft != null && cTop != null && cWidth != null && cHeight != null) { croppedAreaRect = Rect.fromLTWH(cLeft.toDouble(), cTop.toDouble(), cWidth.toDouble(), cHeight.toDouble()); diff --git a/lib/utils/xmp_utils.dart b/lib/utils/xmp_utils.dart index f594ea82b..481e85c54 100644 --- a/lib/utils/xmp_utils.dart +++ b/lib/utils/xmp_utils.dart @@ -49,6 +49,7 @@ class Namespaces { static const mpreg = 'http://ns.microsoft.com/photo/1.2/t/Region#'; static const mwgrs = 'http://www.metadataworkinggroup.com/schemas/regions/'; static const nga = 'https://standards.nga.gov/metadata/media/image/artobject/1.0'; + static const opMedia = 'http://ns.oneplus.com/media/1.0/'; static const panorama = 'http://ns.adobe.com/photoshop/1.0/panorama-profile'; static const panoStudio = 'http://www.tshsoft.com/xmlns'; static const pdf = 'http://ns.adobe.com/pdf/1.3/'; @@ -113,6 +114,7 @@ class Namespaces { mp: 'Microsoft Photo 1.2', mwgrs: 'Regions', nga: 'National Gallery of Art', + opMedia: 'OnePlus Media', panorama: 'Panorama', panoStudio: 'PanoramaStudio', pdf: 'PDF',