mirror of
https://github.com/immich-app/immich.git
synced 2025-11-25 15:55:17 -05:00
fix(server): copy relevant panorama tags to preview image (#23953)
This commit is contained in:
parent
4462952564
commit
271a42ac7f
@ -121,6 +121,23 @@ export class MediaRepository {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async copyTagGroup(tagGroup: string, source: string, target: string): Promise<boolean> {
|
||||||
|
try {
|
||||||
|
await exiftool.write(
|
||||||
|
target,
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
ignoreMinorErrors: true,
|
||||||
|
writeArgs: ['-TagsFromFile', source, `-${tagGroup}:all>${tagGroup}:all`, '-overwrite_original'],
|
||||||
|
},
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
} catch (error: any) {
|
||||||
|
this.logger.warn(`Could not copy tag data to image: ${error.message}`);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
decodeImage(input: string | Buffer, options: DecodeToBufferOptions) {
|
decodeImage(input: string | Buffer, options: DecodeToBufferOptions) {
|
||||||
return this.getImageDecodingPipeline(input, options).raw().toBuffer({ resolveWithObject: true });
|
return this.getImageDecodingPipeline(input, options).raw().toBuffer({ resolveWithObject: true });
|
||||||
}
|
}
|
||||||
|
|||||||
@ -865,6 +865,7 @@ describe(MediaService.name, () => {
|
|||||||
mocks.systemMetadata.get.mockResolvedValue({ image: { fullsize: { enabled: false } } });
|
mocks.systemMetadata.get.mockResolvedValue({ image: { fullsize: { enabled: false } } });
|
||||||
mocks.media.extract.mockResolvedValue({ buffer: extractedBuffer, format: RawExtractedFormat.Jpeg });
|
mocks.media.extract.mockResolvedValue({ buffer: extractedBuffer, format: RawExtractedFormat.Jpeg });
|
||||||
mocks.media.getImageDimensions.mockResolvedValue({ width: 3840, height: 2160 });
|
mocks.media.getImageDimensions.mockResolvedValue({ width: 3840, height: 2160 });
|
||||||
|
mocks.media.copyTagGroup.mockResolvedValue(true);
|
||||||
|
|
||||||
mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.panoramaTif);
|
mocks.assetJob.getForGenerateThumbnailJob.mockResolvedValue(assetStub.panoramaTif);
|
||||||
|
|
||||||
@ -890,6 +891,13 @@ describe(MediaService.name, () => {
|
|||||||
},
|
},
|
||||||
expect.any(String),
|
expect.any(String),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
expect(mocks.media.copyTagGroup).toHaveBeenCalledTimes(2);
|
||||||
|
expect(mocks.media.copyTagGroup).toHaveBeenCalledWith(
|
||||||
|
'XMP-GPano',
|
||||||
|
assetStub.panoramaTif.originalPath,
|
||||||
|
expect.any(String),
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should respect encoding options when generating full-size preview', async () => {
|
it('should respect encoding options when generating full-size preview', async () => {
|
||||||
|
|||||||
@ -316,6 +316,16 @@ export class MediaService extends BaseService {
|
|||||||
|
|
||||||
const outputs = await Promise.all(promises);
|
const outputs = await Promise.all(promises);
|
||||||
|
|
||||||
|
if (asset.exifInfo.projectionType === 'EQUIRECTANGULAR') {
|
||||||
|
const promises = [
|
||||||
|
this.mediaRepository.copyTagGroup('XMP-GPano', asset.originalPath, previewPath),
|
||||||
|
fullsizePath
|
||||||
|
? this.mediaRepository.copyTagGroup('XMP-GPano', asset.originalPath, fullsizePath)
|
||||||
|
: Promise.resolve(),
|
||||||
|
];
|
||||||
|
await Promise.all(promises);
|
||||||
|
}
|
||||||
|
|
||||||
return { previewPath, thumbnailPath, fullsizePath, thumbhash: outputs[0] as Buffer };
|
return { previewPath, thumbnailPath, fullsizePath, thumbhash: outputs[0] as Buffer };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,7 @@ export const newMediaRepositoryMock = (): Mocked<RepositoryInterface<MediaReposi
|
|||||||
return {
|
return {
|
||||||
generateThumbnail: vitest.fn().mockImplementation(() => Promise.resolve()),
|
generateThumbnail: vitest.fn().mockImplementation(() => Promise.resolve()),
|
||||||
writeExif: vitest.fn().mockImplementation(() => Promise.resolve()),
|
writeExif: vitest.fn().mockImplementation(() => Promise.resolve()),
|
||||||
|
copyTagGroup: vitest.fn().mockImplementation(() => Promise.resolve()),
|
||||||
generateThumbhash: vitest.fn().mockResolvedValue(Buffer.from('')),
|
generateThumbhash: vitest.fn().mockResolvedValue(Buffer.from('')),
|
||||||
decodeImage: vitest.fn().mockResolvedValue({ data: Buffer.from(''), info: {} }),
|
decodeImage: vitest.fn().mockResolvedValue({ data: Buffer.from(''), info: {} }),
|
||||||
extract: vitest.fn().mockResolvedValue(null),
|
extract: vitest.fn().mockResolvedValue(null),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user