mirror of
				https://github.com/CaramelFur/Picsur.git
				synced 2025-10-31 17:35:48 +01:00 
			
		
		
		
	Store animated images as lossless webp
This commit is contained in:
		| @@ -17,6 +17,13 @@ import { SysPreferenceDbService } from '../../collections/preference-db/sys-pref | ||||
| import { SharpWrapper } from '../../workers/sharp.wrapper.js'; | ||||
| import { ImageResult } from './imageresult.js'; | ||||
|  | ||||
| interface InternalConvertOptions { | ||||
|   lossless?: boolean; | ||||
|   effort?: number; | ||||
| } | ||||
|  | ||||
| export type ConvertOptions = ImageRequestParams & InternalConvertOptions; | ||||
|  | ||||
| @Injectable() | ||||
| export class ImageConverterService { | ||||
|   constructor(private readonly sysPref: SysPreferenceDbService) {} | ||||
| @@ -25,7 +32,7 @@ export class ImageConverterService { | ||||
|     image: Buffer, | ||||
|     sourceFiletype: FileType, | ||||
|     targetFiletype: FileType, | ||||
|     options: ImageRequestParams, | ||||
|     options: ConvertOptions, | ||||
|   ): AsyncFailable<ImageResult> { | ||||
|     if ( | ||||
|       sourceFiletype.identifier === targetFiletype.identifier && | ||||
| @@ -37,23 +44,22 @@ export class ImageConverterService { | ||||
|       }; | ||||
|     } | ||||
|  | ||||
|     if (targetFiletype.category === SupportedFileTypeCategory.Image) { | ||||
|       return this.convertStill(image, sourceFiletype, targetFiletype, options); | ||||
|     } else if ( | ||||
|     if ( | ||||
|       targetFiletype.category === SupportedFileTypeCategory.Image || | ||||
|       targetFiletype.category === SupportedFileTypeCategory.Animation | ||||
|     ) { | ||||
|       return this.convertStill(image, sourceFiletype, targetFiletype, options); | ||||
|       return this.convertImage(image, sourceFiletype, targetFiletype, options); | ||||
|       //return this.convertAnimation(image, targetmime, options); | ||||
|     } else { | ||||
|       return Fail(FT.SysValidation, 'Unsupported mime type'); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   private async convertStill( | ||||
|   private async convertImage( | ||||
|     image: Buffer, | ||||
|     sourceFiletype: FileType, | ||||
|     targetFiletype: FileType, | ||||
|     options: ImageRequestParams, | ||||
|     options: ConvertOptions, | ||||
|   ): AsyncFailable<ImageResult> { | ||||
|     const [memLimit, timeLimit] = await Promise.all([ | ||||
|       this.sysPref.getNumberPreference(SysPreference.ConversionMemoryLimit), | ||||
|   | ||||
| @@ -46,10 +46,12 @@ export class ImageProcessorService { | ||||
|     image: Buffer, | ||||
|     filetype: FileType, | ||||
|   ): AsyncFailable<ImageResult> { | ||||
|     // Webps and gifs are stored as is for now | ||||
|     return { | ||||
|       image: image, | ||||
|       filetype: filetype.identifier, | ||||
|     }; | ||||
|     const outputFileType = ParseFileType(AnimFileType.WEBP); | ||||
|     if (HasFailed(outputFileType)) return outputFileType; | ||||
|  | ||||
|     return this.imageConverter.convert(image, filetype, outputFileType, { | ||||
|       lossless: true, | ||||
|       effort: 0, | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -26,6 +26,10 @@ export type SharpWorkerOperation = | ||||
|  | ||||
| export interface SharpWorkerFinishOptions { | ||||
|   quality?: number; | ||||
|  | ||||
|   // Only for internal use | ||||
|   lossless?: boolean; | ||||
|   effort?: number; | ||||
| } | ||||
|  | ||||
| // Messages | ||||
|   | ||||
| @@ -2,10 +2,11 @@ import { BMPdecode, BMPencode } from 'bmp-img'; | ||||
| import { | ||||
|   AnimFileType, | ||||
|   FileType, | ||||
|   ImageFileType, | ||||
|   ImageFileType | ||||
| } from 'picsur-shared/dist/dto/mimes.dto'; | ||||
| import { QOIdecode, QOIencode } from 'qoi-img'; | ||||
| import sharp, { Sharp, SharpOptions } from 'sharp'; | ||||
| import { SharpWorkerFinishOptions } from './sharp.message'; | ||||
|  | ||||
| export interface SharpResult { | ||||
|   data: Buffer; | ||||
| @@ -72,9 +73,7 @@ function qoiSharpIn(image: Buffer, options?: SharpOptions) { | ||||
| export async function UniversalSharpOut( | ||||
|   image: Sharp, | ||||
|   filetype: FileType, | ||||
|   options?: { | ||||
|     quality?: number; | ||||
|   }, | ||||
|   options?: SharpWorkerFinishOptions, | ||||
| ): Promise<SharpResult> { | ||||
|   let result: SharpResult | undefined; | ||||
|  | ||||
| @@ -103,7 +102,11 @@ export async function UniversalSharpOut( | ||||
|     case ImageFileType.WEBP: | ||||
|     case AnimFileType.WEBP: | ||||
|       result = await image | ||||
|         .webp({ quality: options?.quality }) | ||||
|         .webp({ | ||||
|           quality: options?.quality, | ||||
|           lossless: options?.lossless, | ||||
|           effort: options?.effort, | ||||
|         }) | ||||
|         .toBuffer({ resolveWithObject: true }); | ||||
|       break; | ||||
|     case AnimFileType.GIF: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user