diff --git a/src/backend/model/threading/MetadataLoader.ts b/src/backend/model/threading/MetadataLoader.ts index c63b4d09..48b22c72 100644 --- a/src/backend/model/threading/MetadataLoader.ts +++ b/src/backend/model/threading/MetadataLoader.ts @@ -166,6 +166,15 @@ export class MetadataLoader { const info = imageSize(fullPath); metadata.size = {width: info.width, height: info.height}; } + if (OrientationTypes.BOTTOM_LEFT < metadata.orientation && + metadata.orientation <= OrientationTypes.LEFT_BOTTOM && + metadata.size.width > metadata.size.height) { + // noinspection JSSuspiciousNameCombination + const height = metadata.size.width; + // noinspection JSSuspiciousNameCombination + metadata.size.width = metadata.size.height; + metadata.size.height = height; + } } catch (err) { Logger.debug(LOG_TAG, 'Error parsing exif', fullPath, err); try { diff --git a/test/backend/assets/broken_orientation_exif.jpg b/test/backend/assets/broken_orientation_exif.jpg new file mode 100644 index 00000000..f535c8e9 Binary files /dev/null and b/test/backend/assets/broken_orientation_exif.jpg differ diff --git a/test/backend/assets/broken_orientation_exif.json b/test/backend/assets/broken_orientation_exif.json new file mode 100644 index 00000000..4db96d0c --- /dev/null +++ b/test/backend/assets/broken_orientation_exif.json @@ -0,0 +1,24 @@ +{ + "size": { + "width": 3024, + "height": 4032 + }, + "orientation": 6, + "creationDate": 1518964712000, + "fileSize": 256001, + "cameraData": { + "model": "Pixel 2", + "make": "Google", + "ISO": 116, + "focalLength": 4.442, + "exposure": 0.008335, + "fStop": 1.8 + }, + "positionData": { + "GPSData": { + "longitude": -73.96425083333334, + "latitude": 40.77845111111111, + "altitude": 2.2 + } + } +} diff --git a/test/backend/assets/broken_orientation_exif2.jpg b/test/backend/assets/broken_orientation_exif2.jpg new file mode 100644 index 00000000..5c70d041 Binary files /dev/null and b/test/backend/assets/broken_orientation_exif2.jpg differ diff --git a/test/backend/assets/broken_orientation_exif2.json b/test/backend/assets/broken_orientation_exif2.json new file mode 100644 index 00000000..d24b6edc --- /dev/null +++ b/test/backend/assets/broken_orientation_exif2.json @@ -0,0 +1,17 @@ +{ + "cameraData": { + "ISO": 100, + "exposure": 0.001, + "fStop": 2.8, + "focalLength": 6.1, + "make": "Panasonic", + "model": "DMC-LZ7" + }, + "creationDate": 1185452882000, + "fileSize": 124036, + "orientation": 8, + "size": { + "height": 3072, + "width": 2304 + } +} diff --git a/test/backend/unit/model/threading/DiskMangerWorker.spec.ts b/test/backend/unit/model/threading/DiskMangerWorker.spec.ts index eb18bc28..0a090480 100644 --- a/test/backend/unit/model/threading/DiskMangerWorker.spec.ts +++ b/test/backend/unit/model/threading/DiskMangerWorker.spec.ts @@ -12,10 +12,11 @@ describe('DiskMangerWorker', () => { ProjectPath.ImageFolder = path.join(__dirname, '/../../../assets'); const dir = await DiskMangerWorker.scanDirectory('/'); // should match the number of media (photo/video) files in the assets folder - expect(dir.media.length).to.be.equals(7); + expect(dir.media.length).to.be.equals(9); const expected = require(path.join(__dirname, '/../../../assets/test image öüóőúéáű-.,.json')); - expect(Utils.clone(dir.media[3].name)).to.be.deep.equal('test image öüóőúéáű-.,.jpg'); - expect(Utils.clone(dir.media[3].metadata)).to.be.deep.equal(expected); + const i = dir.media.findIndex(m => m.name === 'test image öüóőúéáű-.,.jpg'); + expect(Utils.clone(dir.media[i].name)).to.be.deep.equal('test image öüóőúéáű-.,.jpg'); + expect(Utils.clone(dir.media[i].metadata)).to.be.deep.equal(expected); }); }); diff --git a/test/backend/unit/model/threading/MetaDataLoader.spec.ts b/test/backend/unit/model/threading/MetaDataLoader.spec.ts index c65765e9..2082e7c4 100644 --- a/test/backend/unit/model/threading/MetaDataLoader.spec.ts +++ b/test/backend/unit/model/threading/MetaDataLoader.spec.ts @@ -31,6 +31,19 @@ describe('MetadataLoader', () => { expect(Utils.clone(data)).to.be.deep.equal(expected); }); + describe('should load jpg with proper height and orientation', () => { + it('jpg 1', async () => { + const data = await MetadataLoader.loadPhotoMetadata(path.join(__dirname, '/../../../assets/broken_orientation_exif.jpg')); + const expected = require(path.join(__dirname, '/../../../assets/broken_orientation_exif.json')); + expect(Utils.clone(data)).to.be.deep.equal(expected); + }); + it('jpg 2', async () => { + const data = await MetadataLoader.loadPhotoMetadata(path.join(__dirname, '/../../../assets/broken_orientation_exif2.jpg')); + const expected = require(path.join(__dirname, '/../../../assets/broken_orientation_exif2.json')); + expect(Utils.clone(data)).to.be.deep.equal(expected); + }); + }); + it('should load jpg edited with exiftool', async () => { const data = await MetadataLoader.loadPhotoMetadata(path.join(__dirname, '/../../../assets/exiftool.jpg')); @@ -48,6 +61,8 @@ describe('MetadataLoader', () => { it('should respect mp4 rotate transformation', async () => { const data = await MetadataLoader.loadVideoMetadata(path.join(__dirname, '/../../../assets/video_rotate.mp4')); const expected = require(path.join(__dirname, '/../../../assets/video_rotate.json')); + delete data.duration; + delete expected.duration; expect(Utils.clone(data)).to.be.deep.equal(expected); });