美文网首页视觉艺术前端
前端(JavaScript)实现图片压缩

前端(JavaScript)实现图片压缩

作者: LM林慕 | 来源:发表于2019-12-06 16:55 被阅读0次

    业务场景

    场景描述:前端使用<input type="file">标签进行上传图片时,当图片过大时,会造成接口响应速度过慢,影响用户体验。
    解决方案:前端先对图片进行压缩,然后将压缩后的图片传给后端。

    技术实现

    我在项目里使用的是localResizeIMG(lrz)这个库,不过这个库已经很久没有维护了,介意者勿用。

    1. 基本使用localResizeIMG(lrz)

    2. localResizeIMG(lrz)插件的使用方法及属性:

    lrz(file,{
        width:800,    //设置图片压缩后的最大宽度,默认为原图宽度
        height:600,    //同上
        quality:0.7,    //图片压缩质量,取值 0 - 1,默认为 0.7
        fieldName:"aijquery"    //后端接收的字段名,默认:file,一般不用这项,我们要上传数据的话,可以自定义FormData对象      
    }).then(function(rst){
        rst.formData //后端可处理的数据
        rst.file     //压缩后的file对象,如果压缩率太低,将会是原始file对象
        rst.fileLen //压缩后的图片的大小,
        rst.base64     //生成后的图片base64,后端可以处理此字符串为图片,也可以直接用于 img.src = base64
        rst.base64Len     //生成后的base64的大小,后端可以通过此值来校验是否传输完整
        rst.origin //原始的file对象,里面存放了一些原始文件的信息,例如大小、日期等
    }).catch(function(err){    //处理失败后执行
         
    }).always(function(){    //必然执行
     
    });
    
    1. 项目中使用情况:
      HTML部分
    <input type="file" @change="chooseFile">
    

    JS部分

    后端限传1M图片,所以针对压缩比例根据不同大小的图片做了对比,如代码。

    async chooseFile (e) {
          let file = e.target.files[0]
          if (file) {
            let size
            let formData = new FormData()
            if (file.type.indexOf('image') !== -1) {  // 图片压缩
              size = file.size
              let quality
              if (size > 1048576 && size < 8388608) {   // 1-8M
                quality = 0.9
              } else if (size >= 8388608 && size < 16777216) {  // 8-16M
                quality = 0.8
              } else {
                quality = 0.5
              }
              // 压缩比例每减小0.1,约等于压缩8.5倍
              await lrz(file, {
                quality: quality    // 自定义使用压缩方式
              })
                .then(function (rst) {
                  // 成功时执行
                  let _name = rst.origin.name
                  let _type = rst.origin.type
                  let _file = rst.file
                  file = new window.File([_file], _name, { type: _type })
                  formData.append('file', file)
                }).catch(function (e) {
                  // 失败时执行
                  console.log(e)
                }).always(function () {
                  // 不管成功或失败,都会执行
                })
            } 
            // 界面需展示文件大小,不需要展示可删除
            size = (file.size / 1024).toFixed(2) + 'KB'
            if (size === '0.00KB') {
              // 使用的mint-ui
              Toast('不支持传空文件')
              return
            }
            // 上传的接口
            await uploadFile(formData).then(res => {
              if (res.data.success) {
                // 页面需渲染的一些东西
                id = res.data.data.fileId
                url = res.data.data.url
              } 
            }).catch(e => {
            })
            const windowURL = window.URL || window.webkitURL
            let src
            if (file.type.indexOf('image') !== -1) {
              src = windowURL.createObjectURL(file)
            }  else if (file.type.indexOf('spreadsheetml.sheet') !== -1) { // excel表
              src = require('../../assets/log/excl.png')  // 需展示的图片
            } else if (...) {
              ... // 其他类型
            }
            // 页面需渲染的数组
            this.fileArr.push({ id: id, img: src, name: file.name, size: size, url: url })
          }
        },
    

    【注】:

    • 如果后端可以直接接收blob类型的文件,就不需要这行代码了:
    new window.File([_file], _name, { type: _type })
    

    因为这个插件是将用户选择的file类型文件转为了blob类型,接口接收的是file类型,所以自己做了个转换。

    • lrz压缩后不支持传空文件了,所以做了非空判断:
    if (size === '0.00KB') {
     // 使用的mint-ui
     Toast('不支持传空文件')
     return
    }
    
    • 需展示用户选择的图片的话:
     const windowURL = window.URL || window.webkitURL
     src = windowURL.createObjectURL(file)  // src是img标签的属性
    

    以上就是项目中前端压缩图片上传的所有功能,希望能帮到你。

    总结

    实际上,插件还有很多,但是lrznpm上的weekly downloads相对比较多,还是值得一用的。
    有时间了在项目中尝试使用canvas进行压缩。
    脚本之家:JS和Canvas实现图片的预览压缩和上传功能
    博客园:H5页面利用CANVAS压缩图片并上传

    相关文章

      网友评论

        本文标题:前端(JavaScript)实现图片压缩

        本文链接:https://www.haomeiwen.com/subject/mofjgctx.html