Files
Picsur/backend/src/managers/image/image-processor.service.ts

74 lines
1.9 KiB
TypeScript
Raw Normal View History

import { Injectable } from '@nestjs/common';
import {
FullMime,
ImageMime,
2022-06-05 12:20:16 +02:00
SupportedMimeCategory,
2022-04-16 16:35:28 +02:00
} from 'picsur-shared/dist/dto/mimes.dto';
import { AsyncFailable, Fail } from 'picsur-shared/dist/types';
import { QOIColorSpace, QOIencode } from 'qoi-img';
import { ImageResult } from './imageresult';
import { UniversalSharp } from './universal-sharp';
@Injectable()
export class ImageProcessorService {
public async process(
image: Buffer,
mime: FullMime,
): AsyncFailable<ImageResult> {
if (mime.type === SupportedMimeCategory.Image) {
return await this.processStill(image, mime);
} else if (mime.type === SupportedMimeCategory.Animation) {
return await this.processAnimation(image, mime);
} else {
return Fail('Unsupported mime type');
}
}
private async processStill(
image: Buffer,
mime: FullMime,
): AsyncFailable<ImageResult> {
let processedMime = mime.mime;
let sharpImage = UniversalSharp(image, mime);
processedMime = ImageMime.QOI;
2022-04-16 16:35:28 +02:00
sharpImage = sharpImage.toColorspace('srgb');
2022-05-01 23:29:56 +02:00
const processedImage = await sharpImage.raw().toBuffer({
resolveWithObject: true,
});
2022-04-16 16:35:28 +02:00
if (
2022-05-01 23:29:56 +02:00
processedImage.info.width >= 32768 ||
processedImage.info.height >= 32768
) {
return Fail('Image too large');
}
2022-04-16 16:35:28 +02:00
// Png can be more efficient than QOI, but its just sooooooo slow
2022-05-01 23:29:56 +02:00
const qoiImage = QOIencode(processedImage.data, {
channels: processedImage.info.channels,
colorspace: QOIColorSpace.SRGB,
2022-05-01 23:29:56 +02:00
height: processedImage.info.height,
width: processedImage.info.width,
2022-04-16 16:35:28 +02:00
});
return {
image: qoiImage,
mime: processedMime,
};
}
private async processAnimation(
image: Buffer,
mime: FullMime,
): AsyncFailable<ImageResult> {
// Apng and gif are stored as is for now
return {
image: image,
mime: mime.mime,
};
}
}