From 1664bc60eb7aa3fa3792b6acff50f9bbabd3d877 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 16 Feb 2021 10:19:09 +0100 Subject: [PATCH] Optimize remote image processing --- server/helpers/image-utils.ts | 40 +++++++++++++--- server/lib/thumbnail.ts | 3 +- server/tests/fixtures/thumbnail-big.jpg | Bin 0 -> 16286 bytes server/tests/fixtures/thumbnail.png | Bin 0 -> 4221 bytes server/tests/helpers/image.ts | 59 ++++++++++++++++++++++++ server/tests/helpers/index.ts | 1 + 6 files changed, 94 insertions(+), 9 deletions(-) create mode 100644 server/tests/fixtures/thumbnail-big.jpg create mode 100644 server/tests/fixtures/thumbnail.png create mode 100644 server/tests/helpers/image.ts diff --git a/server/helpers/image-utils.ts b/server/helpers/image-utils.ts index 3ebf07305..9285c12fc 100644 --- a/server/helpers/image-utils.ts +++ b/server/helpers/image-utils.ts @@ -1,10 +1,9 @@ -import { remove, rename } from 'fs-extra' +import { copy, readFile, remove, rename } from 'fs-extra' +import * as Jimp from 'jimp' import { extname } from 'path' import { convertWebPToJPG, processGIF } from './ffmpeg-utils' import { logger } from './logger' -const Jimp = require('jimp') - async function processImage ( path: string, destination: string, @@ -23,7 +22,7 @@ async function processImage ( if (extension === '.gif') { await processGIF(path, destination, newSize) } else { - await jimpProcessor(path, destination, newSize) + await jimpProcessor(path, destination, newSize, extension) } if (keepOriginal !== true) await remove(path) @@ -37,11 +36,12 @@ export { // --------------------------------------------------------------------------- -async function jimpProcessor (path: string, destination: string, newSize: { width: number, height: number }) { - let jimpInstance: any +async function jimpProcessor (path: string, destination: string, newSize: { width: number, height: number }, inputExt: string) { + let jimpInstance: Jimp + const inputBuffer = await readFile(path) try { - jimpInstance = await Jimp.read(path) + jimpInstance = await Jimp.read(inputBuffer) } catch (err) { logger.debug('Cannot read %s with jimp. Try to convert the image using ffmpeg first.', path, { err }) @@ -54,8 +54,34 @@ async function jimpProcessor (path: string, destination: string, newSize: { widt await remove(destination) + // Optimization if the source file has the appropriate size + if (await skipProcessing({ jimpInstance, newSize, imageBytes: inputBuffer.byteLength, inputExt, outputExt: extname(destination) })) { + return copy(path, destination) + } + await jimpInstance .resize(newSize.width, newSize.height) .quality(80) .writeAsync(destination) } + +function skipProcessing (options: { + jimpInstance: Jimp + newSize: { width: number, height: number } + imageBytes: number + inputExt: string + outputExt: string +}) { + const { jimpInstance, newSize, imageBytes, inputExt, outputExt } = options + const { width, height } = newSize + + if (jimpInstance.getWidth() > width || jimpInstance.getHeight() > height) return false + if (inputExt !== outputExt) return false + + const kB = 1000 + + if (height >= 1000) return imageBytes <= 200 * kB + if (height >= 500) return imageBytes <= 100 * kB + + return imageBytes <= 15 * kB +} diff --git a/server/lib/thumbnail.ts b/server/lib/thumbnail.ts index 5d0c9f742..4bad8d6ca 100644 --- a/server/lib/thumbnail.ts +++ b/server/lib/thumbnail.ts @@ -1,5 +1,4 @@ -import chaiJsonSchema = require('chai-json-schema') -import { copy, move } from 'fs-extra' +import { copy } from 'fs-extra' import { join } from 'path' import { ThumbnailType } from '../../shared/models/videos/thumbnail.type' import { generateImageFromVideoFile } from '../helpers/ffmpeg-utils' diff --git a/server/tests/fixtures/thumbnail-big.jpg b/server/tests/fixtures/thumbnail-big.jpg new file mode 100644 index 0000000000000000000000000000000000000000..537720d2477ffc55cab498b3aa2b72e2260be898 GIT binary patch literal 16286 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 Oz?2iPdPDqt@_zw~DVfm# literal 0 HcmV?d00001 diff --git a/server/tests/fixtures/thumbnail.png b/server/tests/fixtures/thumbnail.png new file mode 100644 index 0000000000000000000000000000000000000000..b331aba3b875653115bb53be293c1f80c26e6fa0 GIT binary patch literal 4221 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 N5ZSbm`*r{IzW^ai_n!a& literal 0 HcmV?d00001 diff --git a/server/tests/helpers/image.ts b/server/tests/helpers/image.ts new file mode 100644 index 000000000..54911697f --- /dev/null +++ b/server/tests/helpers/image.ts @@ -0,0 +1,59 @@ +/* eslint-disable @typescript-eslint/no-unused-expressions,@typescript-eslint/require-await */ + +import 'mocha' +import { readFile, remove } from 'fs-extra' +import { join } from 'path' +import { processImage } from '../../../server/helpers/image-utils' +import { buildAbsoluteFixturePath, root } from '../../../shared/extra-utils' +import { expect } from 'chai' + +async function checkBuffers (path1: string, path2: string, equals: boolean) { + const [ buf1, buf2 ] = await Promise.all([ + readFile(path1), + readFile(path2) + ]) + + if (equals) { + expect(buf1.equals(buf2)).to.be.true + } else { + expect(buf1.equals(buf2)).to.be.false + } +} + +describe('Image helpers', function () { + const imageDestDir = join(root(), 'test-images') + const imageDest = join(imageDestDir, 'test.jpg') + const thumbnailSize = { width: 223, height: 122 } + + it('Should skip processing if the source image is okay', async function () { + const input = buildAbsoluteFixturePath('thumbnail.jpg') + await processImage(input, imageDest, thumbnailSize, true) + + await checkBuffers(input, imageDest, true) + }) + + it('Should not skip processing if the source image does not have the appropriate extension', async function () { + const input = buildAbsoluteFixturePath('thumbnail.png') + await processImage(input, imageDest, thumbnailSize, true) + + await checkBuffers(input, imageDest, false) + }) + + it('Should not skip processing if the source image does not have the appropriate size', async function () { + const input = buildAbsoluteFixturePath('preview.jpg') + await processImage(input, imageDest, thumbnailSize, true) + + await checkBuffers(input, imageDest, false) + }) + + it('Should not skip processing if the source image does not have the appropriate size', async function () { + const input = buildAbsoluteFixturePath('thumbnail-big.jpg') + await processImage(input, imageDest, thumbnailSize, true) + + await checkBuffers(input, imageDest, false) + }) + + after(async function () { + await remove(imageDest) + }) +}) diff --git a/server/tests/helpers/index.ts b/server/tests/helpers/index.ts index 03b971770..66db93c99 100644 --- a/server/tests/helpers/index.ts +++ b/server/tests/helpers/index.ts @@ -1,3 +1,4 @@ +import './image' import './core-utils' import './comment-model' import './request' -- 2.41.0