前端vue压缩静态图片,压缩gif动态图片

一、压缩静态图片

/**
 * 压缩图片方法
 * @param {file} file 文件
 * @param {Number} quality 图片质量(取值 0-1 之间默认 0.52)
 */
export function compressImg(file, quality) {
  let qualitys = 0.52
  if (parseInt((file.size / 1024).toFixed(2)) < 1024) {
    qualitys = 0.85
  }
  if (5 * 1024 < parseInt((file.size / 1024).toFixed(2))) {
    qualitys = 0.92
  }
  if (quality) {
    qualitys = quality
  }
  if (file[0]) {
    return Promise.all(Array.from(file).map(e => this.compressImg(e, qualitys))) // 如果是 file 数组返回 Promise 数组
  } else {
    return new Promise((resolve) => {
      if ((file.size / 1024).toFixed(2) < 300) {
        resolve({
          file: file
        })
      } else {
        const reader = new FileReader() // 创建 FileReader
        reader.readAsDataURL(file)
        reader.onload = ({
          target: {
            result: src
          }
        }) => {
          const image = new Image() // 创建 img 元素
          image.onload = async () => {
            const canvas = document.createElement('canvas') // 创建 canvas 元素
            const context = canvas.getContext('2d')
            const originWidth = image.width
            const originHeight = image.height
            let targetWidth = image.width
            let targetHeight = image.height
            if (1 * 1024 <= parseInt((file.size / 1024).toFixed(2)) && parseInt((file.size / 1024).toFixed(2)) <= 10 * 1024) {
              var maxWidth = 1600
              var maxHeight = 1600
              targetWidth = originWidth
              targetHeight = originHeight
              // 图片尺寸超过的限制
              if (originWidth > maxWidth || originHeight > maxHeight) {
                if (originWidth / originHeight > maxWidth / maxHeight) {
                  // 更宽,按照宽度限定尺寸
                  targetWidth = maxWidth
                  targetHeight = Math.round(maxWidth * (originHeight / originWidth))
                } else {
                  targetHeight = maxHeight
                  targetWidth = Math.round(maxHeight * (originWidth / originHeight))
                }
              }
            }
            if (10 * 1024 <= parseInt((file.size / 1024).toFixed(2)) && parseInt((file.size / 1024).toFixed(2)) <= 20 * 1024) {
              maxWidth = 1400
              maxHeight = 1400
              targetWidth = originWidth
              targetHeight = originHeight
              // 图片尺寸超过的限制
              if (originWidth > maxWidth || originHeight > maxHeight) {
                if (originWidth / originHeight > maxWidth / maxHeight) {
                  // 更宽,按照宽度限定尺寸
                  targetWidth = maxWidth
                  targetHeight = Math.round(maxWidth * (originHeight / originWidth))
                } else {
                  targetHeight = maxHeight
                  targetWidth = Math.round(maxHeight * (originWidth / originHeight))
                }
              }
            }
            canvas.width = targetWidth
            canvas.height = targetHeight
            context.clearRect(0, 0, targetWidth, targetHeight)
            context.drawImage(image, 0, 0, targetWidth, targetHeight) // 绘制 canvas
            console.log('typetypetypetype',file.type);
            const canvasURL = canvas.toDataURL(file.type, qualitys)
            const buffer = atob(canvasURL.split(',')[1])
            let length = buffer.length
            const bufferArray = new Uint8Array(new ArrayBuffer(length))
            while (length--) {
              bufferArray[length] = buffer.charCodeAt(length)
            }
            const miniFile = new File([bufferArray], file.name, {
              type: file.type
            })
            resolve({
              origin: file,
              file: miniFile,
              beforeSrc: src,
              afterSrc: canvasURL,
              beforeKB: Number((file.size / 1024).toFixed(2)),
              afterKB: Number((miniFile.size / 1024).toFixed(2)),
              qualitys: qualitys
            })
          }
          image.src = src
        }
      }
    })
  }
}

使用方式:

import { compressImg } from '@/utils/index'

// 第一个参数是file对象,第二个参数是压缩倍数,不传默认0.52
compressImg(file.raw)

二、gif动态图片压缩

参考网址:GitCode - 全球开发者的开源社区,开源代码托管平台

1.下载  npm i gifsicle-wasm-browser --save  包

npm i gifsicle-wasm-browser --save

2.在需要的页面或组件引入

import gifsicle from "gifsicle-wasm-browser";

3.使用方式

// 可以使用 async await 模式,也可以使用.then
gifsicle.run({
  input: [{
      file: file.raw, 
      name: 'input.gif',
  }],
  command: [`-O2 --lossy=160 input.gif  -o /out/out.gif`],
}).then(outGifFiles => {
  console.log(outGifFiles);
  // [File,File,File ...]
});

 博主压缩案例:可能是因为插件的原因,4mb以上进行压缩时间比较合适,小于4mb就不建议压缩了

//原图大小: 3320733    3.16MB
-O1 --lossy=20 1.gif  -o /out/out.gif   压缩:19028574    20秒
-O1 --lossy=160 1.gif  -o /out/out.gif  压缩:14047276    20秒
-O2 --lossy=40 1.gif  -o /out/out.gif   压缩:3285702     34秒		
-O2 --lossy=160 1.gif  -o /out/out.gif  压缩:2957546     30秒	
-O3 --lossy=160 1.gif  -o /out/out.gif  压缩:2940185     83秒


//原图大小: 4883735    4.65MB
-O1 --lossy=20 1.gif  -o /out/out.gif   压缩:4353783    6秒
-O1 --lossy=160 1.gif  -o /out/out.gif  压缩:2324117    5秒
-O2 --lossy=40 1.gif  -o /out/out.gif   压缩:3463351    9秒		
-O2 --lossy=160 1.gif  -o /out/out.gif  压缩:2479152    8秒	
-O3 --lossy=160 1.gif  -o /out/out.gif  压缩:2479108    20秒


//原图大小: 15482425    14.76MB
-O1 --lossy=20 1.gif  -o /out/out.gif   压缩:15162166   11秒
-O1 --lossy=160 1.gif  -o /out/out.gif  压缩:7987047    9秒
-O2 --lossy=40 1.gif  -o /out/out.gif   压缩:10409003   20秒		
-O2 --lossy=160 1.gif  -o /out/out.gif  压缩:7233579    15秒	
-O3 --lossy=160 1.gif  -o /out/out.gif  压缩:7164005    45秒
const limit10M = file.size /1024/1024 < 10;
if(!limit10M) {
  return this.$message.warning('上传文件不能超过10M!');
}

let newfile;
if( file.raw.type !=='image/gif'){
  // 图片压缩
  let res = await compressImg(file.raw)
  newfile = res.file
}else{
  // gif压缩  4MB以下不需要压缩
  const limit4M = file.size /1024/1024 < 4;
  if(!limit4M) {
    let res = await gifsicle.run({
      input: [{
          file: file.raw, 
          name: 'input.gif',
      }],
      command: [`-O1 --lossy=20 input.gif  -o /out/out.gif`],
    })
    console.log('resres',res);
    newfile = res[0]
  }else{
    newfile = file.raw
  }
}

// 使用 newfile 里面的值传入给后端 

压缩案例对比图:查看下图 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值