This commit is contained in:
tamaina 2023-01-15 15:16:36 +00:00
parent 474c72d32d
commit e8c196d1c6
3 changed files with 17 additions and 12 deletions

View File

@ -2,6 +2,8 @@ import { Inject, Injectable } from '@nestjs/common';
import sharp from 'sharp'; import sharp from 'sharp';
import { DI } from '@/di-symbols.js'; import { DI } from '@/di-symbols.js';
import type { Config } from '@/config.js'; import type { Config } from '@/config.js';
import { ReadableStream } from 'node:stream/web';
import { Readable } from 'node:stream';
export type IImage = { export type IImage = {
data: Buffer; data: Buffer;
@ -90,6 +92,12 @@ export class ImageProcessingService {
} }
} }
@bindThis
public convertToWebpFromWebReadable(readable: ReadableStream | null, width: number, height: number, options: sharp.WebpOptions = webpDefault): IImageStream {
if (readable == null) throw new Error('Input is null');
return this.convertSharpToWebpStreamObj(Readable.fromWeb(readable).pipe(sharp()), width, height, options);
}
@bindThis @bindThis
public async convertToWebp(path: string, width: number, height: number, options: sharp.WebpOptions = webpDefault): Promise<IImage> { 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(await sharp(path), width, height, options);

View File

@ -20,9 +20,7 @@ import { FileInfoService, TYPE_SVG } from '@/core/FileInfoService.js';
import { LoggerService } from '@/core/LoggerService.js'; import { LoggerService } from '@/core/LoggerService.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify'; import type { FastifyInstance, FastifyRequest, FastifyReply, FastifyPluginOptions } from 'fastify';
import { PassThrough, Readable } from 'node:stream'; import { Readable } from 'node:stream';
import sharp from 'sharp';
import { Request } from 'got';
const _filename = fileURLToPath(import.meta.url); const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename); const _dirname = dirname(_filename);
@ -126,8 +124,8 @@ export class FileServerService {
const convertFile = async () => { const convertFile = async () => {
if (isThumbnail) { if (isThumbnail) {
if (['image/jpeg', 'image/webp', 'image/avif', 'image/png', 'image/svg+xml'].includes(mime)) { if (['image/jpeg', 'image/webp', 'image/avif', 'image/png', 'image/svg+xml'].includes(mime)) {
return this.imageProcessingService.convertSharpToWebpStreamObj( return this.imageProcessingService.convertToWebpFromWebReadable(
Readable.fromWeb(response.body).pipe(sharp()), response.body,
498, 498,
280 280
); );
@ -140,8 +138,8 @@ export class FileServerService {
if (isWebpublic) { if (isWebpublic) {
if (['image/svg+xml'].includes(mime)) { if (['image/svg+xml'].includes(mime)) {
return { return {
data: this.imageProcessingService.convertSharpToWebpStream( data: this.imageProcessingService.convertToWebpFromWebReadable(
Readable.fromWeb(response.body).pipe(sharp()), response.body,
2048, 2048,
2048, 2048,
{ ...webpDefault, lossless: true } { ...webpDefault, lossless: true }

View File

@ -18,8 +18,7 @@ import { FileInfoService, TYPE_SVG } from '@/core/FileInfoService.js';
import { LoggerService } from '@/core/LoggerService.js'; import { LoggerService } from '@/core/LoggerService.js';
import { bindThis } from '@/decorators.js'; import { bindThis } from '@/decorators.js';
import type { FastifyInstance, FastifyPluginOptions, FastifyReply, FastifyRequest } from 'fastify'; import type { FastifyInstance, FastifyPluginOptions, FastifyReply, FastifyRequest } from 'fastify';
import { PassThrough, Readable, pipeline } from 'node:stream'; import { Readable, pipeline } from 'node:stream';
import { Request } from 'got';
const _filename = fileURLToPath(import.meta.url); const _filename = fileURLToPath(import.meta.url);
const _dirname = dirname(_filename); const _dirname = dirname(_filename);
@ -123,9 +122,9 @@ export class MediaProxyServerService {
}; };
} }
} else if ('static' in request.query && isConvertibleImage) { } else if ('static' in request.query && isConvertibleImage) {
image = this.imageProcessingService.convertSharpToWebpStreamObj(Readable.fromWeb(response.body).pipe(sharp()), 498, 280); image = this.imageProcessingService.convertToWebpFromWebReadable(response.body, 498, 280);
} else if ('preview' in request.query && isConvertibleImage) { } else if ('preview' in request.query && isConvertibleImage) {
image = this.imageProcessingService.convertSharpToWebpStreamObj(Readable.fromWeb(response.body).pipe(sharp()), 200, 200); image = this.imageProcessingService.convertToWebpFromWebReadable(response.body, 200, 200);
} else if ('badge' in request.query) { } else if ('badge' in request.query) {
if (!isConvertibleImage) { if (!isConvertibleImage) {
// 画像でないなら404でお茶を濁す // 画像でないなら404でお茶を濁す
@ -164,7 +163,7 @@ export class MediaProxyServerService {
type: 'image/png', type: 'image/png',
}; };
} else if (mime === 'image/svg+xml') { } else if (mime === 'image/svg+xml') {
image = this.imageProcessingService.convertSharpToWebpStreamObj(Readable.fromWeb(response.body).pipe(sharp()), 2048, 2048); image = this.imageProcessingService.convertToWebpFromWebReadable(response.body, 2048, 2048);
} else if (!mime.startsWith('image/') || !FILE_TYPE_BROWSERSAFE.includes(mime)) { } else if (!mime.startsWith('image/') || !FILE_TYPE_BROWSERSAFE.includes(mime)) {
throw new StatusError('Rejected type', 403, 'Rejected type'); throw new StatusError('Rejected type', 403, 'Rejected type');
} }