@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
TypeScript
//#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 };