更新记录

v0.1(2025-10-13)

  • 支持 Android 平台图片压缩
  • 支持 iOS 平台图片压缩
  • 支持单张图片压缩
  • 支持批量图片压缩
  • 支持自定义压缩质量(0-100)
  • 支持自定义最大宽高
  • 支持多种输出格式(JPG、PNG、WebP)
  • 提供图片信息查询功能
  • 返回详细的压缩信息(原始大小、压缩后大小、压缩率等)

平台兼容性

CJ图片智能压缩插件 - 使用示例

本文档提供详细的使用示例,帮助您快速集成和使用插件。

目录

  1. 基础示例
  2. 高级用法
  3. 完整页面示例
  4. 实战场景

基础示例

1. 压缩单张图片

import { compressImage } from '@/uni_modules/cj-image-compress'

// 最简单的用法
const result = compressImage({
  src: '/storage/emulated/0/DCIM/photo.jpg'
})

console.log(result)

2. 自定义压缩参数

import { compressImage } from '@/uni_modules/cj-image-compress'

const result = compressImage({
  src: '/path/to/image.jpg',
  quality: 60,          // 压缩质量
  maxWidth: 1080,       // 最大宽度
  maxHeight: 1080,      // 最大高度
  format: 'webp',       // 输出格式
  dest: '/path/to/output.webp'  // 指定输出路径
})

if (result.success) {
  console.log('压缩成功!')
  console.log('保存位置:', result.tempFilePath)
  console.log('节省空间:', result.compressRate)
}

3. 批量压缩

import { compressImages } from '@/uni_modules/cj-image-compress'

const imageList = [
  { src: '/path/to/image1.jpg', quality: 80 },
  { src: '/path/to/image2.jpg', quality: 70 },
  { src: '/path/to/image3.png', quality: 60, format: 'jpg' }
]

const results = compressImages(imageList)

results.forEach((result, index) => {
  if (result.success) {
    console.log(`第${index + 1}张压缩成功,压缩率:${result.compressRate}`)
  } else {
    console.error(`第${index + 1}张压缩失败:${result.errMsg}`)
  }
})

高级用法

1. 智能压缩策略

根据图片大小自动调整压缩参数:

import { getImageInfo, compressImage } from '@/uni_modules/cj-image-compress'

function smartCompress(imagePath) {
  // 先获取图片信息
  const info = getImageInfo(imagePath)

  if (!info.success) {
    return { success: false, errMsg: '获取图片信息失败' }
  }

  // 根据文件大小决定压缩策略
  let quality = 80
  let maxWidth = 1920

  const sizeInMB = info.originalSize / 1024 / 1024

  if (sizeInMB > 10) {
    quality = 60
    maxWidth = 1080
  } else if (sizeInMB > 5) {
    quality = 70
    maxWidth = 1440
  } else if (sizeInMB < 0.5) {
    // 小于 500KB 不压缩
    return {
      success: true,
      tempFilePath: imagePath,
      originalSize: info.originalSize,
      compressedSize: info.originalSize,
      compressRate: '0%'
    }
  }

  // 执行压缩
  return compressImage({
    src: imagePath,
    quality: quality,
    maxWidth: maxWidth,
    maxHeight: maxWidth,
    format: 'jpg'
  })
}

// 使用
const result = smartCompress('/path/to/image.jpg')
console.log(result)

2. 进度回调(模拟)

import { compressImages } from '@/uni_modules/cj-image-compress'

function compressWithProgress(imageList, ) {
  const results = []
  const total = imageList.length

  imageList.forEach((config, index) => {
    const result = compressImage(config)
    results.push(result)

    // 触发进度回调
    if () {
      ({
        current: index + 1,
        total: total,
        percent: ((index + 1) / total * 100).toFixed(0) + '%'
      })
    }
  })

  return results
}

// 使用
compressWithProgress(
  [
    { src: '/path/1.jpg' },
    { src: '/path/2.jpg' },
    { src: '/path/3.jpg' }
  ],
  (progress) => {
    console.log(`压缩进度:${progress.percent}`)
    uni.showLoading({
      title: `压缩中 ${progress.current}/${progress.total}`
    })
  }
)

3. 压缩前预览

function compressWithPreview(imagePath) {
  return new Promise((resolve, reject) => {
    // 先获取信息
    const info = getImageInfo(imagePath)

    if (!info.success) {
      reject(info.errMsg)
      return
    }

    // 显示预览
    uni.showModal({
      title: '确认压缩',
      content: `图片大小:${formatSize(info.originalSize)}\n尺寸:${info.width}×${info.height}\n\n确定要压缩吗?`,
      success: (res) => {
        if (res.confirm) {
          const result = compressImage({
            src: imagePath,
            quality: 80
          })
          resolve(result)
        } else {
          reject('用户取消')
        }
      }
    })
  })
}

// 使用
compressWithPreview('/path/to/image.jpg')
  .then(result => {
    console.log('压缩完成', result)
  })
  .catch(err => {
    console.log('取消或失败', err)
  })

完整页面示例

Vue 3 组合式 API

<template>
  <view class="container">
    <button @click="handleCompress" class="btn-compress">
      选择并压缩图片
    </button>

    <view v-if="result" class="result-box">
      <image :src="result.tempFilePath" mode="aspectFit"></image>

      <view class="info">
        <text>原始大小:{{ formatSize(result.originalSize) }}</text>
        <text>压缩后:{{ formatSize(result.compressedSize) }}</text>
        <text>压缩率:{{ result.compressRate }}</text>
        <text>尺寸:{{ result.width }} × {{ result.height }}</text>
      </view>

      <button @click="uploadImage" class="btn-upload">
        上传图片
      </button>
    </view>
  </view>
</template>

<script setup>
import { ref } from 'vue'
import { compressImage } from '@/uni_modules/cj-image-compress'

const result = ref(null)

const handleCompress = () => {
  uni.chooseImage({
    count: 1,
    success: (res) => {
      uni.showLoading({ title: '压缩中...' })

      const compressResult = compressImage({
        src: res.tempFilePaths[0],
        quality: 80,
        maxWidth: 1920,
        maxHeight: 1920
      })

      uni.hideLoading()

      if (compressResult.success) {
        result.value = compressResult
        uni.showToast({ title: '压缩成功' })
      } else {
        uni.showToast({ 
          title: compressResult.errMsg,
          icon: 'none'
        })
      }
    }
  })
}

const uploadImage = () => {
  if (!result.value) return

  uni.uploadFile({
    url: 'https://api.example.com/upload',
    filePath: result.value.tempFilePath,
    name: 'file',
    success: (res) => {
      uni.showToast({ title: '上传成功' })
    },
    fail: (err) => {
      uni.showToast({ 
        title: '上传失败', 
        icon: 'none' 
      })
    }
  })
}

const formatSize = (bytes) => {
  if (bytes < 1024) return bytes + ' B'
  if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(2) + ' KB'
  return (bytes / 1024 / 1024).toFixed(2) + ' MB'
}
</script>

<style scoped>
.container {
  padding: 30rpx;
}

.btn-compress,
.btn-upload {
  width: 100%;
  height: 88rpx;
  line-height: 88rpx;
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
  border: none;
  border-radius: 12rpx;
  font-size: 32rpx;
}

.btn-upload {
  background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
  margin-top: 20rpx;
}

.result-box {
  margin-top: 40rpx;
  background: white;
  border-radius: 16rpx;
  padding: 30rpx;
}

.result-box image {
  width: 100%;
  height: 400rpx;
  border-radius: 12rpx;
}

.info {
  margin-top: 30rpx;
}

.info text {
  display: block;
  padding: 12rpx 0;
  font-size: 28rpx;
  color: #666;
}
</style>

实战场景

场景1:头像上传

// pages/profile/avatar-upload.js
import { compressImage } from '@/uni_modules/cj-image-compress'

export default {
  methods: {
    uploadAvatar() {
      uni.chooseImage({
        count: 1,
        sourceType: ['album', 'camera'],
        success: (res) => {
          // 压缩头像(小尺寸,高质量)
          const result = compressImage({
            src: res.tempFilePaths[0],
            quality: 90,
            maxWidth: 500,
            maxHeight: 500,
            format: 'jpg'
          })

          if (result.success) {
            this.doUpload(result.tempFilePath)
          }
        }
      })
    },

    doUpload(filePath) {
      uni.uploadFile({
        url: 'https://api.example.com/user/avatar',
        filePath: filePath,
        name: 'avatar',
        success: (res) => {
          uni.showToast({ title: '头像更新成功' })
        }
      })
    }
  }
}

场景2:商品图片批量上传

// pages/goods/publish.js
import { compressImages } from '@/uni_modules/cj-image-compress'

export default {
  data() {
    return {
      goodsImages: []
    }
  },
  methods: {
    selectGoodsImages() {
      uni.chooseImage({
        count: 9,
        success: (res) => {
          uni.showLoading({ title: '处理中...' })

          // 批量压缩商品图
          const configs = res.tempFilePaths.map(path => ({
            src: path,
            quality: 85,
            maxWidth: 1200,
            maxHeight: 1200,
            format: 'jpg'
          }))

          const results = compressImages(configs)

          // 过滤成功的结果
          const successResults = results.filter(r => r.success)

          this.goodsImages = successResults.map(r => r.tempFilePath)

          uni.hideLoading()
          uni.showToast({ 
            title: `已添加 ${successResults.length} 张图片`
          })
        }
      })
    },

    publishGoods() {
      // 上传所有商品图片
      const uploadTasks = this.goodsImages.map(imagePath => {
        return this.uploadSingleImage(imagePath)
      })

      Promise.all(uploadTasks)
        .then(urls => {
          // 提交商品信息
          this.submitGoods(urls)
        })
    },

    uploadSingleImage(filePath) {
      return new Promise((resolve, reject) => {
        uni.uploadFile({
          url: 'https://api.example.com/goods/image',
          filePath: filePath,
          name: 'file',
          success: (res) => {
            const data = JSON.parse(res.data)
            resolve(data.url)
          },
          fail: reject
        })
      })
    }
  }
}

场景3:图片编辑器

// utils/image-editor.js
import { compressImage } from '@/uni_modules/cj-image-compress'

class ImageEditor {
  constructor() {
    this.originalImage = null
    this.editedImage = null
  }

  // 加载图片
  loadImage(imagePath) {
    this.originalImage = imagePath
    return this
  }

  // 应用滤镜后压缩保存
  async applyFilterAndCompress(filterType) {
    // 1. 应用滤镜(假设有滤镜处理函数)
    const filteredImage = await this.applyFilter(filterType)

    // 2. 压缩图片
    const result = compressImage({
      src: filteredImage,
      quality: 90,
      maxWidth: 1920,
      maxHeight: 1920,
      format: 'jpg'
    })

    if (result.success) {
      this.editedImage = result.tempFilePath
      return result
    }

    throw new Error(result.errMsg)
  }

  // 调整大小
  resize(width, height) {
    const result = compressImage({
      src: this.originalImage,
      quality: 100,
      maxWidth: width,
      maxHeight: height
    })

    return result
  }

  // 格式转换
  convertFormat(format) {
    const result = compressImage({
      src: this.originalImage,
      quality: 100,
      format: format
    })

    return result
  }
}

export default ImageEditor

工具函数

文件大小格式化

export function formatSize(bytes) {
  if (!bytes || bytes === 0) return '0 B'

  const units = ['B', 'KB', 'MB', 'GB']
  let index = 0
  let size = bytes

  while (size >= 1024 && index < units.length - 1) {
    size /= 1024
    index++
  }

  return size.toFixed(2) + ' ' + units[index]
}

图片质量评估

import { getImageInfo } from '@/uni_modules/cj-image-compress'

export function assessImageQuality(imagePath) {
  const info = getImageInfo(imagePath)

  if (!info.success) {
    return null
  }

  const sizeInMB = info.originalSize / 1024 / 1024
  const pixels = info.width * info.height / 1000000 // 百万像素

  // 计算每百万像素的文件大小
  const mbPerMP = sizeInMB / pixels

  let quality = 'unknown'

  if (mbPerMP > 2) {
    quality = 'excellent'  // 优秀
  } else if (mbPerMP > 1) {
    quality = 'good'       // 良好
  } else if (mbPerMP > 0.5) {
    quality = 'fair'       // 一般
  } else {
    quality = 'poor'       // 较差,可能已压缩
  }

  return {
    size: sizeInMB,
    pixels: pixels,
    quality: quality,
    needCompress: quality === 'excellent' || quality === 'good'
  }
}

常见问题

如何选择压缩参数?

使用场景 推荐quality 推荐maxWidth 推荐格式
头像 90 500 jpg
商品图 85 1200 jpg
相册分享 80 1920 jpg
背景图 75 1920 jpg/webp
图标素材 100 原始 png

建议压缩的图片

  • 大于 500KB 的图片
  • 分辨率超过 2000px 的图片
  • 需要上传到服务器的图片
  • 需要在应用内展示的图片

不建议压缩的图片

  • 小于 100KB 的图片
  • PNG 透明图标
  • 需要保持原始质量的图片
  • 已经过压缩的图片

更多示例和最佳实践,请查看插件文档或联系技术支持。

隐私、权限声明

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

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

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

暂无用户评论。