diff --git a/server/src/services/media.service.spec.ts b/server/src/services/media.service.spec.ts index 08606731a0..ad52b0e8b0 100644 --- a/server/src/services/media.service.spec.ts +++ b/server/src/services/media.service.spec.ts @@ -861,6 +861,37 @@ describe(MediaService.name, () => { ); }); + it('should always generate full-size preview from non-web-friendly panoramas', async () => { + mocks.systemMetadata.get.mockResolvedValue({ image: { fullsize: { enabled: false } } }); + mocks.media.extract.mockResolvedValue({ buffer: extractedBuffer, format: RawExtractedFormat.Jpeg }); + mocks.media.getImageDimensions.mockResolvedValue({ width: 3840, height: 2160 }); + + mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.panoramaTif); + + await sut.handleGenerateThumbnails({ id: assetStub.image.id }); + + expect(mocks.media.decodeImage).toHaveBeenCalledOnce(); + expect(mocks.media.decodeImage).toHaveBeenCalledWith(assetStub.panoramaTif.originalPath, { + colorspace: Colorspace.Srgb, + orientation: undefined, + processInvalidImages: false, + size: undefined, + }); + + expect(mocks.media.generateThumbnail).toHaveBeenCalledTimes(3); + expect(mocks.media.generateThumbnail).toHaveBeenCalledWith( + rawBuffer, + { + colorspace: Colorspace.Srgb, + format: ImageFormat.Jpeg, + quality: 80, + processInvalidImages: false, + raw: rawInfo, + }, + expect.any(String), + ); + }); + it('should respect encoding options when generating full-size preview', async () => { mocks.systemMetadata.get.mockResolvedValue({ image: { fullsize: { enabled: true, format: ImageFormat.Webp, quality: 90 } }, diff --git a/server/src/services/media.service.ts b/server/src/services/media.service.ts index a2c3c5ed42..6caa682f5e 100644 --- a/server/src/services/media.service.ts +++ b/server/src/services/media.service.ts @@ -271,7 +271,9 @@ export class MediaService extends BaseService { // Handle embedded preview extraction for RAW files const extractEmbedded = image.extractEmbedded && mimeTypes.isRaw(asset.originalFileName); const extracted = extractEmbedded ? await this.extractImage(asset.originalPath, image.preview.size) : null; - const generateFullsize = image.fullsize.enabled && !mimeTypes.isWebSupportedImage(asset.originalPath); + const generateFullsize = + (image.fullsize.enabled || asset.exifInfo.projectionType == 'EQUIRECTANGULAR') && + !mimeTypes.isWebSupportedImage(asset.originalPath); const convertFullsize = generateFullsize && (!extracted || !mimeTypes.isWebSupportedImage(` .${extracted.format}`)); const { info, data, colorspace } = await this.decodeImage( diff --git a/server/test/fixtures/asset.stub.ts b/server/test/fixtures/asset.stub.ts index dd1f98d6eb..0fd2189268 100644 --- a/server/test/fixtures/asset.stub.ts +++ b/server/test/fixtures/asset.stub.ts @@ -866,4 +866,43 @@ export const assetStub = { stackId: null, visibility: AssetVisibility.Timeline, }), + panoramaTif: Object.freeze({ + id: 'asset-id', + status: AssetStatus.Active, + deviceAssetId: 'device-asset-id', + fileModifiedAt: new Date('2023-02-23T05:06:29.716Z'), + fileCreatedAt: new Date('2023-02-23T05:06:29.716Z'), + owner: userStub.user1, + ownerId: 'user-id', + deviceId: 'device-id', + originalPath: '/original/path.tif', + checksum: Buffer.from('file hash', 'utf8'), + type: AssetType.Image, + files, + thumbhash: Buffer.from('blablabla', 'base64'), + encodedVideoPath: null, + createdAt: new Date('2023-02-23T05:06:29.716Z'), + updatedAt: new Date('2023-02-23T05:06:29.716Z'), + localDateTime: new Date('2023-02-23T05:06:29.716Z'), + isFavorite: true, + duration: null, + isExternal: false, + livePhotoVideo: null, + livePhotoVideoId: null, + sharedLinks: [], + originalFileName: 'asset-id.tif', + faces: [], + deletedAt: null, + sidecarPath: null, + exifInfo: { + fileSizeInByte: 5000, + projectionType: 'EQUIRECTANGULAR', + } as Exif, + duplicateId: null, + isOffline: false, + updateId: '42', + libraryId: null, + stackId: null, + visibility: AssetVisibility.Timeline, + }), }; diff --git a/web/src/lib/components/asset-viewer/image-panorama-viewer.svelte b/web/src/lib/components/asset-viewer/image-panorama-viewer.svelte index 3e7f869e7c..7334aab4d4 100644 --- a/web/src/lib/components/asset-viewer/image-panorama-viewer.svelte +++ b/web/src/lib/components/asset-viewer/image-panorama-viewer.svelte @@ -1,6 +1,6 @@