From c181bd5fb5eaef90fa359556bf6034391ac550d7 Mon Sep 17 00:00:00 2001 From: "Patrik J. Braun" Date: Wed, 29 Mar 2023 00:28:43 +0200 Subject: [PATCH] Enabling high quality chroma subsampling for webp by default in the hope of slightly nicer thumbnail quality #558 --- src/backend/model/fileprocessing/PhotoProcessing.ts | 9 +++------ src/backend/model/threading/PhotoWorker.ts | 3 ++- src/common/config/private/PrivateConfig.ts | 10 ++++++++++ 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/backend/model/fileprocessing/PhotoProcessing.ts b/src/backend/model/fileprocessing/PhotoProcessing.ts index 0ce86cb5..624b74f7 100644 --- a/src/backend/model/fileprocessing/PhotoProcessing.ts +++ b/src/backend/model/fileprocessing/PhotoProcessing.ts @@ -4,11 +4,7 @@ import * as os from 'os'; import * as crypto from 'crypto'; import {ProjectPath} from '../../ProjectPath'; import {Config} from '../../../common/config/private/Config'; -import { - PhotoWorker, - RendererInput, - ThumbnailSourceType, -} from '../threading/PhotoWorker'; +import {PhotoWorker, RendererInput, ThumbnailSourceType,} from '../threading/PhotoWorker'; import {ITaskExecuter, TaskExecuter} from '../threading/TaskExecuter'; import {FaceRegion, PhotoDTO} from '../../../common/entities/PhotoDTO'; import {SupportedFormats} from '../../../common/SupportedFormats'; @@ -124,7 +120,7 @@ export class PhotoProcessing { return path.join( ProjectPath.TranscodedFolder, ProjectPath.getRelativePathToImages(path.dirname(mediaPath)), - file + '_' + size + 'q' + Config.Media.Thumbnail.quality + PhotoProcessing.CONVERTED_EXTENSION + file + '_' + size + 'q' + Config.Media.Thumbnail.quality + (Config.Media.Thumbnail.smartSubsample ? 'cs' : '') + PhotoProcessing.CONVERTED_EXTENSION ); } @@ -257,6 +253,7 @@ export class PhotoProcessing { makeSquare, useLanczos3: Config.Media.Thumbnail.useLanczos3, quality: Config.Media.Thumbnail.quality, + smartSubsample: Config.Media.Thumbnail.smartSubsample, } as RendererInput; const outDir = path.dirname(input.outPath); diff --git a/src/backend/model/threading/PhotoWorker.ts b/src/backend/model/threading/PhotoWorker.ts index ef42226f..0c0be92d 100644 --- a/src/backend/model/threading/PhotoWorker.ts +++ b/src/backend/model/threading/PhotoWorker.ts @@ -46,6 +46,7 @@ export interface RendererInput { outPath: string; quality: number; useLanczos3: boolean; + smartSubsample: boolean; cut?: { left: number; top: number; @@ -162,7 +163,7 @@ export class ImageRendererFactory { fit: 'cover', }); } - await image.rotate().webp({effort: 6, quality: input.quality}).toFile(input.outPath); + await image.rotate().webp({effort: 6, quality: input.quality, smartSubsample: input.smartSubsample}).toFile(input.outPath); }; } } diff --git a/src/common/config/private/PrivateConfig.ts b/src/common/config/private/PrivateConfig.ts index b179471b..1e4302c3 100644 --- a/src/common/config/private/PrivateConfig.ts +++ b/src/common/config/private/PrivateConfig.ts @@ -313,6 +313,16 @@ export class ServerThumbnailConfig extends ClientThumbnailConfig { description: $localize`Between 0-100.` }) quality = 80; + @ConfigProperty({ + type: 'boolean', + tags: + { + name: $localize`Use chroma subsampling.`, + priority: ConfigPriority.underTheHood + }, + description: $localize`Use high quality chroma subsampling in webp. See: https://sharp.pixelplumbing.com/api-output#webp.` + }) + smartSubsample = true; @ConfigProperty({ type: 'ratio', tags: