From ce8c34a5b7d812c8e5f28e09d46235d1ffae52f2 Mon Sep 17 00:00:00 2001
From: tamaina <tamaina@hotmail.co.jp>
Date: Wed, 25 Jan 2023 14:07:58 +0000
Subject: [PATCH] :v:

---
 .../src/core/ImageProcessingService.ts        | 23 +++++++++++++++-
 .../backend/src/server/FileServerService.ts   | 27 ++++++++-----------
 2 files changed, 33 insertions(+), 17 deletions(-)

diff --git a/packages/backend/src/core/ImageProcessingService.ts b/packages/backend/src/core/ImageProcessingService.ts
index ba72facfa6..fbc02f504b 100644
--- a/packages/backend/src/core/ImageProcessingService.ts
+++ b/packages/backend/src/core/ImageProcessingService.ts
@@ -73,7 +73,7 @@ export class ImageProcessingService {
 	 */
 	@bindThis
 	public async convertToWebp(path: string, width: number, height: number, options: sharp.WebpOptions = webpDefault): Promise<IImage> {
-		return this.convertSharpToWebp(await sharp(path), width, height, options);
+		return this.convertSharpToWebp(sharp(path), width, height, options);
 	}
 
 	@bindThis
@@ -94,6 +94,27 @@ export class ImageProcessingService {
 		};
 	}
 
+	@bindThis
+	public convertToWebpStream(path: string, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageStream {
+		return this.convertSharpToWebpStream(sharp(path), width, height, options);
+	}
+
+	@bindThis
+	public convertSharpToWebpStream(sharp: sharp.Sharp, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageStream {
+		const data = sharp
+			.resize(width, height, {
+				fit: 'inside',
+				withoutEnlargement: true,
+			})
+			.rotate()
+			.webp(options)
+
+		return {
+			data,
+			ext: 'webp',
+			type: 'image/webp',
+		};
+	}
 	/**
 	 * Convert to PNG
 	 *   with resize, remove metadata, resolve orientation, stop animation
diff --git a/packages/backend/src/server/FileServerService.ts b/packages/backend/src/server/FileServerService.ts
index 17bb498610..fa6964eac3 100644
--- a/packages/backend/src/server/FileServerService.ts
+++ b/packages/backend/src/server/FileServerService.ts
@@ -139,7 +139,7 @@ export class FileServerService {
 				const convertFile = async () => {
 					if (file.fileRole === 'thumbnail') {
 						if (['image/jpeg', 'image/webp', 'image/avif', 'image/png', 'image/svg+xml'].includes(file.mime)) {
-							return this.imageProcessingService.convertToWebp(
+							return this.imageProcessingService.convertToWebpStream(
 								file.path,
 								498,
 								280
@@ -151,16 +151,12 @@ export class FileServerService {
 
 					if (file.fileRole === 'webpublic') {
 						if (['image/svg+xml'].includes(file.mime)) {
-							return {
-								data: this.imageProcessingService.convertToWebp(
-										file.path,
-										2048,
-										2048,
-										{ ...webpDefault, lossless: true }
-									),
-								ext: 'webp',
-								type: 'image/webp',
-							};
+							return this.imageProcessingService.convertToWebpStream(
+								file.path,
+								2048,
+								2048,
+								{ ...webpDefault, lossless: true }
+							)
 						}
 					}
 
@@ -241,8 +237,7 @@ export class FileServerService {
 								height: 128,
 								withoutEnlargement: true,
 							})
-							.webp(webpDefault)
-							.toBuffer();
+							.webp(webpDefault);
 
 					image = {
 						data,
@@ -251,9 +246,9 @@ export class FileServerService {
 					};
 				}
 			} else if ('static' in request.query && isConvertibleImage) {
-				image = this.imageProcessingService.convertToWebp(file.path, 498, 280);
+				image = this.imageProcessingService.convertToWebpStream(file.path, 498, 280);
 			} else if ('preview' in request.query && isConvertibleImage) {
-				image = this.imageProcessingService.convertToWebp(file.path, 200, 200);
+				image = this.imageProcessingService.convertToWebpStream(file.path, 200, 200);
 			} else if ('badge' in request.query) {
 				if (!isConvertibleImage) {
 					// 画像でないなら404でお茶を濁す
@@ -290,7 +285,7 @@ export class FileServerService {
 					type: 'image/png',
 				};
 			} else if (file.mime === 'image/svg+xml') {
-				image = this.imageProcessingService.convertToWebp(file.path, 2048, 2048);
+				image = this.imageProcessingService.convertToWebpStream(file.path, 2048, 2048);
 			} else if (!file.mime.startsWith('image/') || !FILE_TYPE_BROWSERSAFE.includes(file.mime)) {
 				throw new StatusError('Rejected type', 403, 'Rejected type');
 			}