From b778b86eae44776c7802e976300d9c2181f5d0ed Mon Sep 17 00:00:00 2001 From: rubikscraft Date: Fri, 15 Apr 2022 13:28:25 +0200 Subject: [PATCH] fix bmp support --- backend/package.json | 1 + .../imagemanager/imageprocessor.service.ts | 50 +++++++++++-------- yarn.lock | 12 +++++ 3 files changed, 41 insertions(+), 22 deletions(-) diff --git a/backend/package.json b/backend/package.json index 86da220..b524fa7 100644 --- a/backend/package.json +++ b/backend/package.json @@ -28,6 +28,7 @@ "@nestjs/platform-fastify": "^8.4.4", "@nestjs/serve-static": "^2.2.2", "@nestjs/typeorm": "^8.0.3", + "@vingle/bmp-js": "^0.2.5", "bcrypt": "^5.0.1", "cors": "^2.8.5", "fastify-helmet": "^7.0.1", diff --git a/backend/src/managers/imagemanager/imageprocessor.service.ts b/backend/src/managers/imagemanager/imageprocessor.service.ts index ba67e57..8e36b0a 100644 --- a/backend/src/managers/imagemanager/imageprocessor.service.ts +++ b/backend/src/managers/imagemanager/imageprocessor.service.ts @@ -1,4 +1,5 @@ import { Injectable } from '@nestjs/common'; +import * as bmp from '@vingle/bmp-js'; import icoToPng from 'ico-to-png'; import { AsyncFailable, Fail } from 'picsur-shared/dist/types'; import sharp from 'sharp'; @@ -11,6 +12,11 @@ import { @Injectable() export class ImageProcessorService { + private readonly PngOptions = { + compressionLevel: 9, + effort: 10, + }; + constructor(private readonly userPref: UsrPreferenceService) {} public async process( @@ -44,29 +50,18 @@ export class ImageProcessorService { ): AsyncFailable { let processedImage = image; - switch (mime.mime) { - case ImageMime.ICO: - processedImage = await icoToPng(processedImage, 512); - mime.mime = ImageMime.PNG; - break; - - case ImageMime.BMP: - case ImageMime.TIFF: - case ImageMime.WEBP: - case ImageMime.PNG: - case ImageMime.JPEG: - processedImage = await sharp(processedImage) - .png({ - compressionLevel: 9, - effort: 10, - }) - .toBuffer(); - mime.mime = ImageMime.PNG; - break; - - default: - return Fail('Unsupported mime type'); + if (mime.mime === ImageMime.ICO) { + processedImage = await icoToPng(processedImage, 512); + } else if (mime.mime === ImageMime.BMP) { + processedImage = await this.bmpSharp(processedImage) + .png(this.PngOptions) + .toBuffer(); + } else { + processedImage = await sharp(processedImage) + .png(this.PngOptions) + .toBuffer(); } + mime.mime = ImageMime.PNG; return processedImage; } @@ -79,4 +74,15 @@ export class ImageProcessorService { // Apng and gif are stored as is for now return image; } + + private bmpSharp(image: Buffer) { + const bitmap = bmp.decode(image, true); + return sharp(bitmap.data, { + raw: { + width: bitmap.width, + height: bitmap.height, + channels: 4, + }, + }); + } } diff --git a/yarn.lock b/yarn.lock index aba9e04..8606024 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1755,6 +1755,11 @@ resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.24.tgz#20ba1bf69c1b4ab405c7a01e950c4f446b05029f" integrity sha512-aveCYRQbgTH9Pssp1voEP7HiuWlD2jW2BO56w+bVrJn04i61yh6mRfoKO6hEYQD9vF+W8Chkwc6j1M36uPkx4g== +"@types/node@^8.10.29": + version "8.10.66" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.66.tgz#dd035d409df322acc83dff62a602f12a5783bbb3" + integrity sha512-tktOkFUA4kXx2hhhrB8bIFb5TbwzS4uOhKEmwiD+NoiL0qtP2OQ9mFldbgD4dV1djrlBYP6eBuQZiWjuHUpqFw== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" @@ -1944,6 +1949,13 @@ "@typescript-eslint/types" "5.19.0" eslint-visitor-keys "^3.0.0" +"@vingle/bmp-js@^0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@vingle/bmp-js/-/bmp-js-0.2.5.tgz#a333166f42ff879b84443cc5fb1bbe93d234d294" + integrity sha512-tiY69wMrXgIVcdpkjQybXTyQw+P2rKzUfA6b+biM6BD1utr5QeeEj9fzs0fFHVf+3siTsYwzI6zltV9+i6ehEA== + dependencies: + "@types/node" "^8.10.29" + "@webassemblyjs/ast@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.1.tgz#2bfd767eae1a6996f432ff7e8d7fc75679c0b6a7"