UNPKG

@awesome-compressor/browser-compress-image

Version:

🚀 A powerful, lightweight browser image compression library with TypeScript support. Compress JPEG, PNG, GIF images with multiple output formats (Blob, File, Base64, ArrayBuffer) and zero dependencies.

609 lines 19.1 kB
//#region src/types.d.ts type CompressResultType = 'blob' | 'file' | 'base64' | 'arrayBuffer'; type OutputType = 'avif' | 'jpeg' | 'jxl' | 'png' | 'webp'; type CompressResult<T extends CompressResultType> = T extends 'blob' ? Blob : T extends 'file' ? File : T extends 'base64' ? string : T extends 'arrayBuffer' ? ArrayBuffer : never; /** * 工具配置接口 */ interface ToolConfig { /** * 工具名称 */ name: string; /** * API 密钥或其他配置参数 */ key?: string; /** * 其他自定义配置参数 */ [key: string]: any; } interface CompressOptions { /** * 压缩质量 (0-1) * @default 0.6 */ quality?: number; /** * 压缩模式 * - 'keepSize': 保持图片尺寸不变 (如100x100输入,输出仍为100x100),只改变文件大小 * - 'keepQuality': 保持图片质量不变,但可以改变尺寸 * @default 'keepSize' */ mode?: 'keepSize' | 'keepQuality'; /** * 目标宽度 (仅在 keepQuality 模式下生效) */ targetWidth?: number; /** * 目标高度 (仅在 keepQuality 模式下生效) */ targetHeight?: number; /** * 最大宽度 (仅在 keepQuality 模式下生效) */ maxWidth?: number; /** * 最大高度 (仅在 keepQuality 模式下生效) */ maxHeight?: number; /** * 是否保留 EXIF 信息 * @default false */ preserveExif?: boolean; /** * 是否返回所有工具的压缩结果 * @default false */ returnAllResults?: boolean; /** * 返回结果类型 * @default 'blob' */ type?: CompressResultType; /** * 工具配置数组,用于传入各个工具的特定配置 * @example * [ * { name: 'tinypng', key: 'your-api-key' }, * { name: 'other-tool', customConfig: 'value' } * ] */ toolConfigs?: ToolConfig[]; /** * 可选的 AbortSignal,用于取消压缩操作 */ signal?: AbortSignal; /** * 可选的超时时间(毫秒),到达后压缩调用会被视为超时失败 */ timeoutMs?: number; } interface CropRect { x: number; y: number; width: number; height: number; } interface ResizeOptions { /** 期望输出宽度(可与高度同时设定,若仅设定一项则按等比缩放) */ targetWidth?: number; /** 期望输出高度(可与宽度同时设定,若仅设定一项则按等比缩放) */ targetHeight?: number; /** 最大宽度(仅在未设置 targetWidth/Height 时生效) */ maxWidth?: number; /** 最大高度(仅在未设置 targetWidth/Height 时生效) */ maxHeight?: number; /** 调整策略,默认 contain */ fit?: 'contain' | 'cover' | 'scale-down'; } interface PreprocessOptions { /** 像素坐标系中的裁剪区域(相对于原图 natural 尺寸) */ crop?: CropRect; /** 旋转角度(度),顺时针,支持任意角度 */ rotate?: number; /** 水平翻转 */ flipHorizontal?: boolean; /** 垂直翻转 */ flipVertical?: boolean; /** 缩放/调整大小选项 */ resize?: ResizeOptions; /** 预处理阶段输出 MIME 类型(默认使用原图类型,若不支持则回退 PNG) */ outputType?: 'image/png' | 'image/jpeg' | 'image/webp'; /** 输出质量(仅 jpeg/webp 生效,0-1) */ outputQuality?: number; } interface CompressResultItem<T extends CompressResultType> { tool: string; result: CompressResult<T>; originalSize: number; compressedSize: number; compressionRatio: number; duration: number; success: boolean; error?: string; } interface MultipleCompressResults<T extends CompressResultType> { bestResult: CompressResult<T>; bestTool: string; allResults: CompressResultItem<T>[]; totalDuration: number; } //#endregion //#region src/compress.d.ts declare function compress<T extends CompressResultType = 'blob'>(file: File, options: CompressOptions & { type?: T; returnAllResults: true; }): Promise<MultipleCompressResults<T>>; declare function compress<T extends CompressResultType = 'blob'>(file: File, options: CompressOptions & { type?: T; returnAllResults?: false; }): Promise<CompressResult<T>>; declare function compress<T extends CompressResultType = 'blob'>(file: File, quality?: number, type?: T): Promise<CompressResult<T>>; interface CompressionStats { bestTool: string; compressedFile: Blob; originalSize: number; compressedSize: number; compressionRatio: number; totalDuration: number; toolsUsed: { tool: string; size: number; duration: number; compressionRatio: number; success: boolean; error?: string; }[]; } declare function compressWithStats(file: File, qualityOrOptions?: number | CompressOptions): Promise<CompressionStats>; //#endregion //#region src/utils/compressionQueue.d.ts interface CompressionTask { id: string; file: File; options: any; resolve: (result: Blob) => void; reject: (error: Error) => void; priority?: number; cancelListener?: () => void; } interface QueueStats { pending: number; running: number; completed: number; failed: number; maxConcurrency: number; } declare class PerformanceDetector { private static instance; private deviceInfo; private constructor(); static getInstance(): PerformanceDetector; detectDevice(): { isMobile: boolean; cpuCores: number; memoryGB: number; estimatedPerformance: "low" | "medium" | "high"; }; calculateOptimalConcurrency(): number; } declare class CompressionQueue { private static instance; private queue; private running; private completed; private failed; private maxConcurrency; private performanceDetector; private constructor(); static getInstance(): CompressionQueue; addTask(task: CompressionTask): void; removeTask(taskId: string): boolean; getStats(): QueueStats; setMaxConcurrency(newMax: number): void; clearQueue(): void; private processQueue; private executeTask; compress(file: File, options: any, priority?: number): Promise<Blob>; } declare const compressionQueue: CompressionQueue; //#endregion //#region src/compressEnhanced.d.ts interface EnhancedCompressOptions extends CompressOptions { /** * Whether to use worker for compression (when available) * @default true */ useWorker?: boolean; /** * Priority for queue processing (higher = processed first) * @default calculated based on file size */ priority?: number; /** * Whether to use the compression queue for concurrency control * @default true */ useQueue?: boolean; /** * Maximum time to wait for compression (in ms) * @default 30000 (30 seconds) */ timeout?: number; /** * Optional preprocessing before compression (crop/rotate/flip/resize) */ preprocess?: PreprocessOptions; } /** * Enhanced compression function with queue management and worker support * This is the new recommended way to compress images for better performance */ declare function compressEnhanced<T extends CompressResultType = 'blob'>(file: File, options?: EnhancedCompressOptions): Promise<CompressResult<T>>; /** * Batch compression with enhanced queue management */ declare function compressEnhancedBatch(files: File[], options?: EnhancedCompressOptions): Promise<CompressResult<'blob'>[]>; /** * Wait for compression system initialization to complete */ declare function waitForCompressionInitialization(): Promise<void>; /** * Get compression queue statistics */ declare function getCompressionStats(): { queue: QueueStats; worker: { supported: boolean; domDependentTools: string[]; }; }; /** * Configure compression system */ declare function configureCompression(config: { maxConcurrency?: number; }): void; /** * Clear compression queue (cancel pending tasks) */ declare function clearCompressionQueue(): void; //#endregion //#region src/compressWithTools.d.ts type CompressorTool = 'browser-image-compression' | 'compressorjs' | 'gifsicle' | 'canvas' | 'jsquash' | 'original' | 'tinypng'; type CompressorFunction = (file: File, options: any) => Promise<Blob>; declare class ToolRegistry { private tools; private toolsCollections; registerTool(name: CompressorTool, func: CompressorFunction, formats?: string[]): void; getTool(name: CompressorTool): CompressorFunction | undefined; getRegisteredTools(): CompressorTool[]; getToolsForFileType(fileType: string): CompressorTool[]; setToolPriority(fileType: string, tools: CompressorTool[]): void; isToolRegistered(name: CompressorTool): boolean; } declare const globalToolRegistry: ToolRegistry; interface CompressWithToolsOptions extends CompressOptions { type?: CompressResultType; returnAllResults?: boolean; toolRegistry?: ToolRegistry; } declare function compressWithTools<T extends CompressResultType = 'blob'>(file: File, options: CompressWithToolsOptions & { type?: T; returnAllResults: true; }): Promise<MultipleCompressResults<T>>; declare function compressWithTools<T extends CompressResultType = 'blob'>(file: File, options: CompressWithToolsOptions & { type?: T; returnAllResults?: false; }): Promise<CompressResult<T>>; //#endregion //#region src/tools/compressWithBrowserImageCompression.d.ts declare function compressWithBrowserImageCompression(file: File, options: { quality: number; mode: string; targetWidth?: number; targetHeight?: number; maxWidth?: number; maxHeight?: number; preserveExif?: boolean; }): Promise<Blob>; //#endregion //#region src/tools/compressWithCompressorJS.d.ts declare function compressWithCompressorJS(file: File, options: { quality: number; mode: string; targetWidth?: number; targetHeight?: number; maxWidth?: number; maxHeight?: number; preserveExif?: boolean; }): Promise<Blob>; //#endregion //#region src/tools/compressWithCanvas.d.ts declare function compressWithCanvas(file: File, options: { quality: number; mode: string; targetWidth?: number; targetHeight?: number; maxWidth?: number; maxHeight?: number; preserveExif?: boolean; }): Promise<Blob>; //#endregion //#region src/tools/compressWithGifsicle.d.ts declare function compressWithGifsicle(file: File, options: { quality: number; mode: string; targetWidth?: number; targetHeight?: number; maxWidth?: number; maxHeight?: number; preserveExif?: boolean; }): Promise<Blob>; //#endregion //#region src/tools/compressWithJsquash.d.ts interface WasmConfig { baseUrl?: string; useLocal?: boolean; } declare function configureWasmLoading(config: WasmConfig): void; declare function ensureWasmLoaded(format: OutputType): Promise<void>; declare function diagnoseJsquashAvailability(): Promise<{ wasmSupported: boolean; availableFormats: OutputType[]; errors: { format: OutputType; error: string; }[]; }>; declare function downloadWasmFiles(formats?: OutputType[], targetDir?: string): Promise<{ format: OutputType; success: boolean; error?: string; }[]>; declare function compressWithJsquash(file: File, options: { quality: number; mode: string; targetWidth?: number; targetHeight?: number; maxWidth?: number; maxHeight?: number; preserveExif?: boolean; }): Promise<Blob>; //#endregion //#region src/tools/compressWithTinyPng.d.ts declare function compressWithTinyPng(file: File, options: { quality: number; mode: string; targetWidth?: number; targetHeight?: number; maxWidth?: number; maxHeight?: number; preserveExif?: boolean; key?: string; }): Promise<Blob>; declare function clearTinyPngCache(): void; declare function getTinyPngCacheSize(): number; declare function getTinyPngCacheInfo(): { totalEntries: number; maxSize: number; usageRate: number; entries: { key: string; size: number; type: string; }[]; }; declare function configureTinyPngCache(maxSize?: number): void; //#endregion //#region src/tools.d.ts declare function registerAllTools(): void; declare function registerBrowserImageCompression(): void; declare function registerCompressorJS(): void; declare function registerCanvas(): void; declare function registerGifsicle(): void; declare function registerJsquash(): void; declare function registerTinyPng(): void; //#endregion //#region src/utils/compressionWorker.d.ts interface WorkerMessage { id: string; type: 'compress' | 'result' | 'error'; data?: any; } interface WorkerTask { id: string; file: File; options: any; resolve: (result: Blob) => void; reject: (error: Error) => void; } declare class CompressionWorkerManager { private static instance; private workers; private workerTasks; private workerPool; private isWorkerSupported; private workerScript; private initPromise; private constructor(); static getInstance(): CompressionWorkerManager; private initializeWorkerSupport; private createWorkerScript; private testWorkerSupport; waitForInitialization(): Promise<void>; isSupported(): boolean; isToolWorkerCompatible(toolName: string): boolean; getDOMDependentTools(): string[]; compressInWorker(file: File, options: any): Promise<Blob>; private getAvailableWorker; destroy(): void; } declare const compressionWorkerManager: CompressionWorkerManager; //#endregion //#region src/utils/lruCache.d.ts declare class LRUCache<K, V> { private cache; private maxSize; constructor(maxSize?: number); /** * 获取缓存项,如果存在则将其移到最新位置 */ get(key: K): V | undefined; /** * 设置缓存项,如果超过最大容量则淘汰最久未使用的项 */ set(key: K, value: V): void; /** * 检查缓存中是否存在指定的key */ has(key: K): boolean; /** * 清空所有缓存 */ clear(): void; /** * 获取当前缓存大小 */ get size(): number; /** * 获取最大缓存大小 */ get maxCapacity(): number; /** * 设置新的最大缓存大小 */ setMaxSize(newMaxSize: number): void; /** * 获取所有缓存条目的迭代器 */ entries(): IterableIterator<[K, V]>; /** * 获取所有缓存的key */ keys(): IterableIterator<K>; /** * 获取所有缓存的value */ values(): IterableIterator<V>; /** * 删除指定的缓存项 */ delete(key: K): boolean; /** * 获取缓存统计信息 */ getStats(): { size: number; maxSize: number; usageRate: number; }; } //#endregion //#region src/utils/memoryManager.d.ts interface MemoryStats { usedJSHeapSize: number; totalJSHeapSize: number; jsHeapSizeLimit: number; memoryUsagePercentage: number; } interface MemoryThresholds { warning: number; critical: number; maxFileSize: number; maxTotalSize: number; } declare class MemoryManager { private static instance; private objectUrls; private imageElements; private canvasElements; private thresholds; private constructor(); static getInstance(): MemoryManager; getMemoryStats(): MemoryStats; isMemoryCritical(): boolean; isFileSizeAcceptable(fileSize: number): boolean; isTotalSizeAcceptable(totalSize: number): boolean; registerObjectUrl(url: string): void; registerImageElement(img: HTMLImageElement): void; registerCanvasElement(canvas: HTMLCanvasElement): void; cleanupObjectUrl(url: string): void; cleanupImageElement(img: HTMLImageElement): void; cleanupCanvasElement(canvas: HTMLCanvasElement): void; performCleanup(): void; private setupPeriodicCleanup; private setupMemoryMonitoring; updateThresholds(newThresholds: Partial<MemoryThresholds>): void; getThresholds(): MemoryThresholds; createManagedObjectUrl(file: File | Blob): string; createManagedImage(): HTMLImageElement; createManagedCanvas(): HTMLCanvasElement; destroy(): void; } declare const memoryManager: MemoryManager; declare function checkMemoryBeforeOperation(fileSize?: number): boolean; //#endregion //#region src/utils/logger.d.ts type LoggerLike = { enabled?: boolean; enable?: () => void; disable?: () => void; log?: (...args: any[]) => void; debug?: (...args: any[]) => void; warn?: (...args: any[]) => void; error?: (...args: any[]) => void; table?: (data: any) => void; }; declare const logger: { readonly enabled: boolean; enable(): void; disable(): void; log(...args: any[]): void; debug(...args: any[]): void; warn(...args: any[]): void; error(...args: any[]): void; table(data: any): any; }; declare function setLogger(custom: LoggerLike): void; declare function resetLogger(): void; //#endregion //#region src/utils/preprocessImage.d.ts interface PreprocessOutput { blob: Blob; width: number; height: number; mimeType: string; } declare function preprocessImage(src: Blob | File | string, options: PreprocessOptions): Promise<PreprocessOutput>; //#endregion //#region src/conversion/types.d.ts type TargetFormat = 'png' | 'jpeg' | 'webp' | 'ico'; type SourceFormat = 'png' | 'jpeg' | 'webp' | 'ico' | 'svg' | 'gif' | 'bmp'; interface ImageConvertOptions { targetFormat: TargetFormat; quality?: number; preserveExif?: boolean; width?: number; height?: number; [k: string]: any; } interface ImageConvertResult { blob: Blob; mime: string; duration: number; } //#endregion //#region src/conversion/convertImage.d.ts declare function convertImage(fileOrBlob: File | Blob, options: ImageConvertOptions): Promise<ImageConvertResult>; //#endregion //#region src/conversion/encoders.d.ts declare function renderSvgToCanvas(svgContent: string, width?: number, height?: number): Promise<HTMLCanvasElement>; declare function encodeSvgToFormat(svgContent: string, format: TargetFormat, options?: ImageConvertOptions): Promise<Blob>; declare function isSvgContent(content: string): boolean; declare function detectFileFormat(file: File): SourceFormat; //#endregion export { CompressOptions, CompressResult, CompressResultItem, CompressResultType, CompressWithToolsOptions, CompressionQueue, CompressionStats, CompressionTask, CompressionWorkerManager, CompressorFunction, CompressorTool, CropRect, EnhancedCompressOptions, ImageConvertOptions, ImageConvertResult, LRUCache, MemoryManager, MemoryStats, MemoryThresholds, MultipleCompressResults, OutputType, PerformanceDetector, PreprocessOptions, QueueStats, ResizeOptions, SourceFormat, TargetFormat, ToolConfig, ToolRegistry, WorkerMessage, WorkerTask, checkMemoryBeforeOperation, clearCompressionQueue, clearTinyPngCache, compress, compressEnhanced, compressEnhancedBatch, compressWithBrowserImageCompression, compressWithCanvas, compressWithCompressorJS, compressWithGifsicle, compressWithJsquash, compressWithStats, compressWithTinyPng, compressWithTools, compressionQueue, compressionWorkerManager, configureCompression, configureTinyPngCache, configureWasmLoading, convertImage, detectFileFormat, diagnoseJsquashAvailability, downloadWasmFiles, encodeSvgToFormat, ensureWasmLoaded, getCompressionStats, getTinyPngCacheInfo, getTinyPngCacheSize, globalToolRegistry, isSvgContent, logger, memoryManager, preprocessImage, registerAllTools, registerBrowserImageCompression, registerCanvas, registerCompressorJS, registerGifsicle, registerJsquash, registerTinyPng, renderSvgToCanvas, resetLogger, setLogger, waitForCompressionInitialization };