forked from Cutlery/immich
rename to image settings
This commit is contained in:
parent
a9b90787b2
commit
d451abd96c
@ -113,7 +113,7 @@ export const defaults = Object.freeze<SystemConfig>({
|
||||
hashVerificationEnabled: true,
|
||||
template: '{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}',
|
||||
},
|
||||
thumbnail: {
|
||||
image: {
|
||||
thumbnailFormat: ImageFormat.WEBP,
|
||||
thumbnailSize: 250,
|
||||
previewFormat: ImageFormat.JPEG,
|
||||
|
@ -492,7 +492,7 @@ export class SystemConfigDto implements SystemConfig {
|
||||
@Type(() => SystemConfigThumbnailDto)
|
||||
@ValidateNested()
|
||||
@IsObject()
|
||||
thumbnail!: SystemConfigThumbnailDto;
|
||||
image!: SystemConfigThumbnailDto;
|
||||
|
||||
@Type(() => SystemConfigTrashDto)
|
||||
@ValidateNested()
|
||||
|
@ -254,7 +254,7 @@ export interface SystemConfig {
|
||||
hashVerificationEnabled: boolean;
|
||||
template: string;
|
||||
};
|
||||
thumbnail: {
|
||||
image: {
|
||||
thumbnailFormat: ImageFormat;
|
||||
thumbnailSize: number;
|
||||
previewFormat: ImageFormat;
|
||||
|
@ -6,11 +6,11 @@ export class RenameWebpJpegPaths1711257900274 implements MigrationInterface {
|
||||
await queryRunner.renameColumn('assets', 'resizePath', 'previewPath');
|
||||
await queryRunner.query(`
|
||||
UPDATE system_config
|
||||
SET key = 'thumbnail.previewSize'
|
||||
SET key = 'image.previewSize'
|
||||
WHERE key = 'thumbnail.jpegSize'`);
|
||||
await queryRunner.query(
|
||||
`UPDATE system_config
|
||||
SET key = 'thumbnail.thumbnailSize'
|
||||
SET key = 'image.thumbnailSize'
|
||||
WHERE key = 'thumbnail.webpSize'`,
|
||||
);
|
||||
}
|
||||
@ -21,11 +21,11 @@ export class RenameWebpJpegPaths1711257900274 implements MigrationInterface {
|
||||
await queryRunner.query(`
|
||||
UPDATE system_config
|
||||
SET key = 'thumbnail.jpegSize'
|
||||
WHERE key = 'thumbnail.previewSize'`);
|
||||
WHERE key = 'image.previewSize'`);
|
||||
await queryRunner.query(
|
||||
`UPDATE system_config
|
||||
SET key = 'thumbnail.webpSize'
|
||||
WHERE key = 'thumbnail.thumbnailSize'`,
|
||||
WHERE key = 'image.thumbnailSize'`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -153,14 +153,14 @@ export class MediaService {
|
||||
}
|
||||
|
||||
async handleAssetMigration({ id }: IEntityJob): Promise<JobStatus> {
|
||||
const { thumbnail } = await this.configCore.getConfig();
|
||||
const { image } = await this.configCore.getConfig();
|
||||
const [asset] = await this.assetRepository.getByIds([id]);
|
||||
if (!asset) {
|
||||
return JobStatus.FAILED;
|
||||
}
|
||||
|
||||
await this.storageCore.moveAssetImage(asset, AssetPathType.PREVIEW, thumbnail.previewFormat);
|
||||
await this.storageCore.moveAssetImage(asset, AssetPathType.THUMBNAIL, thumbnail.thumbnailFormat);
|
||||
await this.storageCore.moveAssetImage(asset, AssetPathType.PREVIEW, image.previewFormat);
|
||||
await this.storageCore.moveAssetImage(asset, AssetPathType.THUMBNAIL, image.thumbnailFormat);
|
||||
await this.storageCore.moveAssetVideo(asset);
|
||||
|
||||
return JobStatus.SUCCESS;
|
||||
@ -178,16 +178,16 @@ export class MediaService {
|
||||
}
|
||||
|
||||
private async generateThumbnail(asset: AssetEntity, type: GeneratedImageType, format: ImageFormat) {
|
||||
const { thumbnail, ffmpeg } = await this.configCore.getConfig();
|
||||
const size = type === AssetPathType.PREVIEW ? thumbnail.previewSize : thumbnail.thumbnailSize;
|
||||
const { image, ffmpeg } = await this.configCore.getConfig();
|
||||
const size = type === AssetPathType.PREVIEW ? image.previewSize : image.thumbnailSize;
|
||||
const path = StorageCore.getImagePath(asset, type, format);
|
||||
this.storageCore.ensureFolders(path);
|
||||
|
||||
switch (asset.type) {
|
||||
case AssetType.IMAGE: {
|
||||
const colorspace = this.isSRGB(asset) ? Colorspace.SRGB : thumbnail.colorspace;
|
||||
const thumbnailOptions = { format, size, colorspace, quality: thumbnail.quality };
|
||||
await this.mediaRepository.resize(asset.originalPath, path, thumbnailOptions);
|
||||
const colorspace = this.isSRGB(asset) ? Colorspace.SRGB : image.colorspace;
|
||||
const imageOptions = { format, size, colorspace, quality: image.quality };
|
||||
await this.mediaRepository.resize(asset.originalPath, path, imageOptions);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -471,7 +471,7 @@ export class PersonService {
|
||||
}
|
||||
|
||||
async handleGeneratePersonThumbnail(data: IEntityJob): Promise<JobStatus> {
|
||||
const { machineLearning, thumbnail } = await this.configCore.getConfig();
|
||||
const { machineLearning, image } = await this.configCore.getConfig();
|
||||
if (!machineLearning.enabled || !machineLearning.facialRecognition.enabled) {
|
||||
return JobStatus.SKIPPED;
|
||||
}
|
||||
@ -532,8 +532,8 @@ export class PersonService {
|
||||
const thumbnailOptions = {
|
||||
format: ImageFormat.JPEG,
|
||||
size: FACE_THUMBNAIL_SIZE,
|
||||
colorspace: thumbnail.colorspace,
|
||||
quality: thumbnail.quality,
|
||||
colorspace: image.colorspace,
|
||||
quality: image.quality,
|
||||
} as const;
|
||||
|
||||
await this.mediaRepository.resize(croppedOutput, thumbnailPath, thumbnailOptions);
|
||||
|
@ -120,7 +120,7 @@ const updatedConfig = Object.freeze<SystemConfig>({
|
||||
hashVerificationEnabled: true,
|
||||
template: '{{y}}/{{y}}-{{MM}}-{{dd}}/{{filename}}',
|
||||
},
|
||||
thumbnail: {
|
||||
image: {
|
||||
thumbnailFormat: ImageFormat.WEBP,
|
||||
thumbnailSize: 250,
|
||||
previewFormat: ImageFormat.JPEG,
|
||||
|
@ -1,5 +1,5 @@
|
||||
<script lang="ts">
|
||||
import { Colorspace, type SystemConfigDto } from '@immich/sdk';
|
||||
import { Colorspace, ImageFormat, type SystemConfigDto } from '@immich/sdk';
|
||||
import { isEqual } from 'lodash-es';
|
||||
import { createEventDispatcher } from 'svelte';
|
||||
import { fade } from 'svelte/transition';
|
||||
@ -24,6 +24,20 @@
|
||||
<div in:fade={{ duration: 500 }}>
|
||||
<form autocomplete="off" on:submit|preventDefault>
|
||||
<div class="ml-4 mt-4 flex flex-col gap-4">
|
||||
<SettingSelect
|
||||
label="THUMBNAIL FORMAT"
|
||||
desc="Format used for generated thumbnail images. WebP produces smaller files at the same quality."
|
||||
number
|
||||
bind:value={config.thumbnail.thumbnailFormat}
|
||||
options={[
|
||||
{ value: ImageFormat.Jpeg, text: 'JPEG' },
|
||||
{ value: ImageFormat.Webp, text: 'WEBP' },
|
||||
]}
|
||||
name="resolution"
|
||||
isEdited={config.thumbnail.thumbnailFormat !== savedConfig.thumbnail.thumbnailFormat}
|
||||
{disabled}
|
||||
/>
|
||||
|
||||
<SettingSelect
|
||||
label="THUMBNAIL RESOLUTION"
|
||||
desc="Used when viewing groups of photos (main timeline, album view, etc.). Higher resolutions can preserve more detail but take longer to encode, have larger file sizes, and can reduce app responsiveness."
|
||||
@ -41,6 +55,20 @@
|
||||
{disabled}
|
||||
/>
|
||||
|
||||
<SettingSelect
|
||||
label="PREVIEW FORMAT"
|
||||
desc="Format used for generated preview images. WebP produces smaller files at the same quality."
|
||||
number
|
||||
bind:value={config.thumbnail.thumbnailFormat}
|
||||
options={[
|
||||
{ value: ImageFormat.Jpeg, text: 'JPEG' },
|
||||
{ value: ImageFormat.Webp, text: 'WEBP' },
|
||||
]}
|
||||
name="resolution"
|
||||
isEdited={config.thumbnail.thumbnailFormat !== savedConfig.thumbnail.thumbnailFormat}
|
||||
{disabled}
|
||||
/>
|
||||
|
||||
<SettingSelect
|
||||
label="PREVIEW RESOLUTION"
|
||||
desc="Used when viewing a single photo and for machine learning. Higher resolutions can preserve more detail but take longer to encode, have larger file sizes, and can reduce app responsiveness."
|
@ -13,7 +13,7 @@
|
||||
import SettingAccordion from '$lib/components/shared-components/settings/setting-accordion.svelte';
|
||||
import StorageTemplateSettings from '$lib/components/admin-page/settings/storage-template/storage-template-settings.svelte';
|
||||
import ThemeSettings from '$lib/components/admin-page/settings/theme/theme-settings.svelte';
|
||||
import ThumbnailSettings from '$lib/components/admin-page/settings/thumbnail/thumbnail-settings.svelte';
|
||||
import ImageSettings from '$lib/components/admin-page/settings/image/image-settings.svelte';
|
||||
import TrashSettings from '$lib/components/admin-page/settings/trash-settings/trash-settings.svelte';
|
||||
import UserSettings from '$lib/components/admin-page/settings/user-settings/user-settings.svelte';
|
||||
import LinkButton from '$lib/components/elements/buttons/link-button.svelte';
|
||||
@ -43,7 +43,7 @@
|
||||
| typeof ServerSettings
|
||||
| typeof StorageTemplateSettings
|
||||
| typeof ThemeSettings
|
||||
| typeof ThumbnailSettings
|
||||
| typeof ImageSettings
|
||||
| typeof TrashSettings
|
||||
| typeof NewVersionCheckSettings
|
||||
| typeof FFmpegSettings
|
||||
@ -64,6 +64,12 @@
|
||||
subtitle: string;
|
||||
key: string;
|
||||
}> = [
|
||||
{
|
||||
item: ImageSettings,
|
||||
title: 'Image Settings',
|
||||
subtitle: 'Manage the format, quality and resolution of generated images',
|
||||
key: 'image',
|
||||
},
|
||||
{
|
||||
item: JobSettings,
|
||||
title: 'Job Settings',
|
||||
@ -124,12 +130,6 @@
|
||||
subtitle: 'Manage customization of the Immich web interface',
|
||||
key: 'theme',
|
||||
},
|
||||
{
|
||||
item: ThumbnailSettings,
|
||||
title: 'Thumbnail Settings',
|
||||
subtitle: 'Manage the resolution of thumbnail sizes',
|
||||
key: 'thumbnail',
|
||||
},
|
||||
{
|
||||
item: TrashSettings,
|
||||
title: 'Trash Settings',
|
||||
|
Loading…
x
Reference in New Issue
Block a user