当前位置: 首页 > article >正文

前端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 里面的值传入给后端 

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

 


http://www.kler.cn/a/316301.html

相关文章:

  • 基于标签相关性的多标签学习
  • pySpark乱码
  • K8资源之endpoint资源EP资源
  • 低代码集成多方API的简单实现
  • 使用支付宝沙箱完成商品下单
  • PostgreSQL中的COPY命令:高效数据导入与导出
  • Anaconda配置pytorch的基本操作
  • Error when custom data is added to Azure OpenAI Service Deployment
  • Python办公自动化教程(001):PDF内容提取
  • Junit与Spring Test简单使用
  • AI量化交易机器人开发
  • docker挂载宿主机文件run命令启动报错
  • 如何选购笔记本电脑?要看哪些参数?
  • C++重生之我是001
  • Flat File端口更新:如何实现嵌套结构
  • keil安装HAL库
  • 计算机网络32——Linux-文件io-2文件系统
  • 《拿下奇怪的前端报错》:nvm不可用报错`GLIBC_2.27‘‘GLIBCXX_3.4.20‘not Found?+ 使用docker构建多个前端项目实践
  • Linux环境Docker安装Mongodb
  • Electron 安装包 asar 解压定位问题实战
  • 深度学习与大模型第5课:利用 NLTK 中的朴素贝叶斯工具解决实际问题:垃圾邮件过滤
  • Java 速刷复习用极简小抄 P1 - Java 概念
  • C++学习笔记(36)
  • C++--C++11(下)
  • 近几年来说最有效率的编程语言和市场最认可的编程语言分别是什么?
  • Pandas库中pd.to_datetime()函数用法详细介绍