summaryrefslogtreecommitdiff
path: root/packages/backend/src/core/ImageProcessingService.ts
diff options
context:
space:
mode:
authortamaina <tamaina@hotmail.co.jp>2023-03-11 14:11:40 +0900
committerGitHub <noreply@github.com>2023-03-11 14:11:40 +0900
commit88e3d3e8cbe26c0280308e819965a64a91491f90 (patch)
tree25c9039f6fa6725af4fa5a7de5decb71f2a3150b /packages/backend/src/core/ImageProcessingService.ts
parentUpdate CHANGELOG.md (diff)
downloadsharkey-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.ts91
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