更新记录

1.0.0(2025-07-07)

初版


平台兼容性

云函数类插件通用教程

使用云函数类插件的前提是:使用HBuilderX 2.9+


使用说明

概述

基于 Sharp 的高性能图片处理库,提供了完整的图片压缩、缩略图生成、水印添加等功能。支持批量处理、并发控制、内存监控、进度追踪等高级特性。

特性

  • 多格式支持:JPEG、PNG、WebP
  • 智能压缩:根据图片尺寸自动调整参数
  • 批量处理:支持并发批量处理
  • 内存监控:防止内存溢出
  • 进度追踪:实时监控处理进度
  • 缓存机制:提升重复处理性能
  • 预设配置:内置多种压缩预设
  • 错误处理:完善的错误处理机制

安装 (在 /uni_modules/x-image-processor/uniCloud/cloudfunctions/common/x-image-processor 目录下)

npm install sharp

基本使用

1. 初始化处理器

const { ImageProcessor } = require('x-image-processor');

// 使用默认配置
const processor = new ImageProcessor();

// 使用自定义配置
const processor = new ImageProcessor({
    concurrency: 8,           // 并发数
    maxMemoryUsage: 512 * 1024 * 1024, // 最大内存使用 512MB
    enableCache: true,        // 启用缓存
    cacheSize: 200,          // 缓存大小
    defaultQuality: 85,      // 默认质量
    preserveExif: false,     // 保留EXIF信息
    progressCallback: (progress) => {
        console.log(`处理进度: ${progress.percentage}%`);
    }
});

2. 单图片压缩

// 压缩到内存
const compressedBuffer = await processor.compress('input.jpg', {
    quality: 80,
    format: 'jpeg',
    resize: {
        width: 1200,
        height: 800,
        fit: 'inside',
        withoutEnlargement: true
    }
});

// 压缩并保存到文件
const result = await processor.compressToFile('input.jpg', 'output.jpg', {
    quality: 80,
    format: 'jpeg'
});

console.log(`压缩率: ${result.compressionRatio}`);
console.log(`节省空间: ${result.savedBytes} bytes`);

3. 批量处理

// 批量压缩到内存
const inputs = [
    'image1.jpg',
    'image2.png',
    { input: 'image3.jpg', options: { quality: 90 } }
];

const results = await processor.batchCompressToBuffer(inputs, {
    quality: 80,
    format: 'jpeg'
});

results.forEach(result => {
    if (result.success) {
        console.log(`${result.input} 压缩成功, 压缩率: ${result.compressionRatio}`);
    } else {
        console.error(`${result.input} 压缩失败: ${result.error}`);
    }
});

// 批量压缩到文件
const fileInputs = [
    { input: 'image1.jpg', output: 'compressed/image1.jpg' },
    { input: 'image2.png', output: 'compressed/image2.jpg', options: { quality: 90 } }
];

const fileResults = await processor.batchCompressToFile(fileInputs, {
    quality: 80,
    format: 'jpeg'
});

4. 使用预设

// 使用内置预设
const thumbnail = await processor.compressWithPreset('input.jpg', 'thumbnail');
const webOptimized = await processor.compressWithPreset('input.jpg', 'web');
const printQuality = await processor.compressWithPreset('input.jpg', 'print');
const mobileOptimized = await processor.compressWithPreset('input.jpg', 'mobile');

// 添加自定义预设
processor.addPreset('custom', {
    quality: 75,
    format: 'webp',
    resize: { width: 800, height: 600, fit: 'cover' }
});

const customResult = await processor.compressWithPreset('input.jpg', 'custom');

5. 智能压缩

// 根据图片尺寸自动调整参数
const smartCompressed = await processor.smartCompress('input.jpg', {
    format: 'jpeg'
});

高级功能

1. 缩略图生成

const thumbnail = await processor.generateThumbnail('input.jpg', {
    width: 200,
    height: 200,
    fit: 'cover',           // 'cover', 'contain', 'fill', 'inside', 'outside'
    position: 'center',     // 'center', 'top', 'bottom', 'left', 'right'
    format: 'jpeg',
    quality: 80
});

2. 添加水印

const watermarked = await processor.addWatermark('input.jpg', 'watermark.png', {
    gravity: 'southeast',   // 'north', 'northeast', 'east', 'southeast', 'south', 'southwest', 'west', 'northwest', 'center'
    opacity: 0.5,          // 透明度 0-1
    blend: 'over'          // 混合模式
});

// 自定义位置
const customWatermark = await processor.addWatermark('input.jpg', 'watermark.png', {
    left: 50,
    top: 50,
    opacity: 0.7
});

3. 获取图片信息

const info = await processor.getImageInfo('input.jpg');
console.log(info);
/*
{
    width: 1920,
    height: 1080,
    format: 'jpeg',
    size: 245760,
    density: 72,
    channels: 3,
    hasAlpha: false,
    space: 'srgb'
}
*/

4. 内存监控

const memoryInfo = processor.getMemoryInfo();
console.log(`内存使用: ${memoryInfo.percentage}%`);
console.log(`已用内存: ${(memoryInfo.used / 1024 / 1024).toFixed(2)}MB`);

配置选项

压缩选项

const options = {
    quality: 80,            // 质量 1-100
    format: 'jpeg',         // 'jpeg', 'png', 'webp'
    progressive: true,      // 渐进式JPEG
    resize: {
        width: 1200,
        height: 800,
        fit: 'inside',      // 'cover', 'contain', 'fill', 'inside', 'outside'
        withoutEnlargement: true  // 不放大图片
    },
    preserveExif: false     // 保留EXIF数据
};

内置预设

预设名称 用途 配置
thumbnail 缩略图 200x200, 质量80, JPEG
web 网页优化 1200x800, 质量85, WebP
print 打印质量 3000x2000, 质量95, JPEG
mobile 移动端优化 750x500, 质量70, JPEG

处理器配置

const config = {
    concurrency: 4,         // 并发数量
    maxMemoryUsage: 256 * 1024 * 1024, // 最大内存使用
    tempDir: './temp',      // 临时目录
    enableCache: true,      // 启用缓存
    cacheSize: 100,         // 缓存大小
    defaultQuality: 80,     // 默认质量
    preserveExif: false,    // 保留EXIF
    progressCallback: null  // 进度回调
};

错误处理

const { ImageProcessingError, ERROR_CODES } = require('x-image-processor');

try {
    const result = await processor.compress('input.jpg');
} catch (error) {
    if (error instanceof ImageProcessingError) {
        console.error(`处理错误: ${error.message}`);
        console.error(`错误代码: ${error.code}`);
        console.error(`发生时间: ${error.timestamp}`);

        switch (error.code) {
            case ERROR_CODES.FILE_NOT_FOUND:
                console.error('文件不存在');
                break;
            case ERROR_CODES.INVALID_FORMAT:
                console.error('不支持的格式');
                break;
            case ERROR_CODES.MEMORY_LIMIT_EXCEEDED:
                console.error('内存使用超限');
                break;
            // 其他错误处理...
        }
    }
}

最佳实践

1. 并发控制

// 根据系统性能调整并发数
const processor = new ImageProcessor({
    concurrency: require('os').cpus().length
});

2. 内存管理

// 定期检查内存使用
setInterval(() => {
    const memInfo = processor.getMemoryInfo();
    if (parseFloat(memInfo.percentage) > 80) {
        console.warn('内存使用过高:', memInfo.percentage + '%');
        processor.clearCache(); // 清理缓存
    }
}, 30000);

3. 批量处理优化

// 大批量处理时分批进行
const chunkSize = 50;
const allFiles = [...]; // 所有文件

for (let i = 0; i < allFiles.length; i += chunkSize) {
    const chunk = allFiles.slice(i, i + chunkSize);
    const results = await processor.batchCompressToFile(chunk);

    // 处理结果
    results.forEach(result => {
        if (!result.success) {
            console.error(`处理失败: ${result.input} - ${result.error}`);
        }
    });

    // 短暂等待,避免内存压力
    await new Promise(resolve => setTimeout(resolve, 100));
}

4. 资源清理

// 应用退出时清理资源
process.on('exit', async () => {
    await processor.cleanup();
});

process.on('SIGINT', async () => {
    await processor.cleanup();
    process.exit(0);
});

性能优化建议

  1. 合理设置并发数:通常设置为 CPU 核心数的 1-2 倍
  2. 启用缓存:对于重复处理的图片,缓存可以显著提升性能
  3. 监控内存使用:定期检查并清理内存,防止内存泄漏
  4. 选择合适的格式:WebP 通常比 JPEG 有更好的压缩率
  5. 批量处理:尽量使用批量处理 API,减少单次调用开销

注意事项

  1. 文件大小限制:单个文件最大 50MB
  2. 图片尺寸限制:最大 8192x8192 像素
  3. 内存使用:处理大图片时会消耗较多内存
  4. 格式支持:目前支持 JPEG、PNG、WebP 格式
  5. 水印透明度:水印功能需要 PNG 格式的透明图片效果更佳

示例代码

完整的图片处理流程

const { ImageProcessor } = require('x-image-processor');
const path = require('path');

async function processImages() {
    const processor = new ImageProcessor({
        concurrency: 4,
        enableCache: true,
        progressCallback: (progress) => {
            console.log(`处理进度: ${progress.completed}/${progress.total} (${progress.percentage}%)`);
        }
    });

    try {
        // 1. 单图片处理
        const singleResult = await processor.compressToFile(
            'input/large-image.jpg',
            'output/compressed-image.jpg',
            { quality: 80, format: 'jpeg' }
        );
        console.log('单图片压缩完成:', singleResult.compressionRatio);

        // 2. 批量处理
        const batchInputs = [
            { input: 'input/image1.jpg', output: 'output/image1.jpg' },
            { input: 'input/image2.png', output: 'output/image2.jpg' },
            { input: 'input/image3.jpg', output: 'output/image3.webp', options: { format: 'webp' } }
        ];

        const batchResults = await processor.batchCompressToFile(batchInputs, {
            quality: 85,
            format: 'jpeg'
        });

        // 3. 生成缩略图
        const thumbnailBuffer = await processor.generateThumbnail('input/large-image.jpg', {
            width: 300,
            height: 300,
            fit: 'cover'
        });

        // 4. 添加水印
        const watermarkedBuffer = await processor.addWatermark(
            'input/photo.jpg',
            'assets/watermark.png',
            { gravity: 'southeast', opacity: 0.4 }
        );

        // 5. 智能压缩
        const smartCompressed = await processor.smartCompress('input/huge-image.jpg');

        console.log('所有处理完成');
        console.log('内存使用:', processor.getMemoryInfo());

    } catch (error) {
        console.error('处理失败:', error.message);
    } finally {
        await processor.cleanup();
    }
}

processImages();

隐私、权限声明

1. 本插件需要申请的系统权限列表:

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。

使用中有什么不明白的地方,就向插件作者提问吧~ 我要提问