diff options
| author | tamaina <tamaina@hotmail.co.jp> | 2023-03-11 14:11:40 +0900 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-03-11 14:11:40 +0900 |
| commit | 88e3d3e8cbe26c0280308e819965a64a91491f90 (patch) | |
| tree | 25c9039f6fa6725af4fa5a7de5decb71f2a3150b /packages/backend/src/core/ImageProcessingService.ts | |
| parent | Update CHANGELOG.md (diff) | |
| download | sharkey-88e3d3e8cbe26c0280308e819965a64a91491f90.tar.gz sharkey-88e3d3e8cbe26c0280308e819965a64a91491f90.tar.bz2 sharkey-88e3d3e8cbe26c0280308e819965a64a91491f90.zip | |
enhance(server): 画像圧縮周り(主にサムネイルの仕様)の変更 (#10287)
* DriveService, is-mime-image
* static, previewをavifに, アニメーション画像でもthumbnailを生成
* fallback
* animated: true
* fix
* avatarはwebp
* revert ?? file.url
---------
Co-authored-by: syuilo <Syuilotan@yahoo.co.jp>
Diffstat (limited to 'packages/backend/src/core/ImageProcessingService.ts')
| -rw-r--r-- | packages/backend/src/core/ImageProcessingService.ts | 91 |
1 files changed, 55 insertions, 36 deletions
diff --git a/packages/backend/src/core/ImageProcessingService.ts b/packages/backend/src/core/ImageProcessingService.ts index 7c88f5e9a0..3246475d12 100644 --- a/packages/backend/src/core/ImageProcessingService.ts +++ b/packages/backend/src/core/ImageProcessingService.ts @@ -15,15 +15,28 @@ export type IImageStream = { type: string; }; -export type IImageStreamable = IImage | IImageStream; +export type IImageSharp = { + data: sharp.Sharp; + ext: string | null; + type: string; +}; + +export type IImageStreamable = IImage | IImageStream | IImageSharp; export const webpDefault: sharp.WebpOptions = { - quality: 85, + quality: 77, alphaQuality: 95, lossless: false, nearLossless: false, smartSubsample: true, mixed: true, + effort: 2, +}; + +export const avifDefault: sharp.AvifOptions = { + quality: 60, + lossless: false, + effort: 2, }; import { bindThis } from '@/decorators.js'; @@ -38,90 +51,96 @@ export class ImageProcessingService { } /** - * Convert to JPEG + * Convert to WebP * with resize, remove metadata, resolve orientation, stop animation */ @bindThis - public async convertToJpeg(path: string, width: number, height: number): Promise<IImage> { - return this.convertSharpToJpeg(await sharp(path), width, height); + public async convertToWebp(path: string, width: number, height: number, options: sharp.WebpOptions = webpDefault): Promise<IImage> { + return this.convertSharpToWebp(sharp(path), width, height, options); } @bindThis - public async convertSharpToJpeg(sharp: sharp.Sharp, width: number, height: number): Promise<IImage> { - const data = await sharp + public async convertSharpToWebp(sharp: sharp.Sharp, width: number, height: number, options: sharp.WebpOptions = webpDefault): Promise<IImage> { + const result = this.convertSharpToWebpStream(sharp, width, height, options); + + return { + data: await result.data.toBuffer(), + ext: result.ext, + type: result.type, + }; + } + + @bindThis + public convertToWebpStream(path: string, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageSharp { + return this.convertSharpToWebpStream(sharp(path), width, height, options); + } + + @bindThis + public convertSharpToWebpStream(sharp: sharp.Sharp, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageSharp { + const data = sharp .resize(width, height, { fit: 'inside', withoutEnlargement: true, }) .rotate() - .jpeg({ - quality: 85, - progressive: true, - }) - .toBuffer(); + .webp(options); return { data, - ext: 'jpg', - type: 'image/jpeg', + ext: 'webp', + type: 'image/webp', }; } /** - * Convert to WebP + * Convert to Avif * with resize, remove metadata, resolve orientation, stop animation */ @bindThis - public async convertToWebp(path: string, width: number, height: number, options: sharp.WebpOptions = webpDefault): Promise<IImage> { - return this.convertSharpToWebp(sharp(path), width, height, options); + public async convertToAvif(path: string, width: number, height: number, options: sharp.AvifOptions = avifDefault): Promise<IImage> { + return this.convertSharpToAvif(sharp(path), width, height, options); } @bindThis - public async convertSharpToWebp(sharp: sharp.Sharp, width: number, height: number, options: sharp.WebpOptions = webpDefault): Promise<IImage> { - const data = await sharp - .resize(width, height, { - fit: 'inside', - withoutEnlargement: true, - }) - .rotate() - .webp(options) - .toBuffer(); + public async convertSharpToAvif(sharp: sharp.Sharp, width: number, height: number, options: sharp.AvifOptions = avifDefault): Promise<IImage> { + const result = this.convertSharpToAvifStream(sharp, width, height, options); return { - data, - ext: 'webp', - type: 'image/webp', + data: await result.data.toBuffer(), + ext: result.ext, + type: result.type, }; } @bindThis - public convertToWebpStream(path: string, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageStream { - return this.convertSharpToWebpStream(sharp(path), width, height, options); + public convertToAvifStream(path: string, width: number, height: number, options: sharp.AvifOptions = avifDefault): IImageSharp { + return this.convertSharpToAvifStream(sharp(path), width, height, options); } @bindThis - public convertSharpToWebpStream(sharp: sharp.Sharp, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageStream { + public convertSharpToAvifStream(sharp: sharp.Sharp, width: number, height: number, options: sharp.AvifOptions = avifDefault): IImageSharp { const data = sharp .resize(width, height, { fit: 'inside', withoutEnlargement: true, }) .rotate() - .webp(options); + .avif(options); return { data, - ext: 'webp', - type: 'image/webp', + ext: 'avif', + type: 'image/avif', }; } + /** * Convert to PNG * with resize, remove metadata, resolve orientation, stop animation */ @bindThis public async convertToPng(path: string, width: number, height: number): Promise<IImage> { - return this.convertSharpToPng(await sharp(path), width, height); + return this.convertSharpToPng(sharp(path), width, height); } @bindThis |