zoukankan      html  css  js  c++  java
  • 前端图片压缩与 zip 压缩

      在项目中,为了节约网络消耗,需要将文件进行压缩后上传服务端。

      最开始考虑的是将文件压缩为 zip ,由服务端返回后前端 zip 再进行解压。但 zip 对小文件、图片、视频的压缩效果很差。所以需要多种压缩方式配合使用。

      图像采用 canvas 有损压缩:

     utils.dealImage = (base64, rate) => {
        return new Promise((resolve, reject) => {
          try {
            let newImage = new Image();
            let quality = rate || rate > 1 || rate <= 0 ? rate : 0.6; //压缩系数0-1之间
            // newImage.setAttribute("crossOrigin", 'Anonymous'); //url为外域时需要
            let imgWidth, imgHeight;
            newImage.onload = function () {
              imgWidth = this.width;
              imgHeight = this.height;
              let canvas = document.createElement("canvas");
              let ctx = canvas.getContext("2d");
              canvas.width = imgWidth;
              canvas.height = imgHeight;
              ctx.clearRect(0, 0, canvas.width, canvas.height);
              ctx.drawImage(this, 0, 0, canvas.width, canvas.height);
              let base64 = canvas.toDataURL("image/jpeg", quality); //压缩语句
              resolve(base64);
            }
            newImage.src = base64;
          } catch (err) {
            reject(err);
          }
        })
      }

      其余文件采用 zip 方式无损压缩,这里使用的是 jszip :

    // 文件 base64 压缩为 zip
    utils.zip = (base64, fileName) => {
        let inputBlob = utils.dataURItoBlob(base64);
        let JSZip = require("jszip");
        let zip = new JSZip();
        zip.file(fileName, inputBlob, {
          type: "blob"
        });
        // return a promise
        return zip.generateAsync({
          type: "blob",
          compression: "DEFLATE", // force a compression for this file
          compressionOptions: {
            level: 9,
          },
        });
      }
    
      //blob to base64
      utils.blobToDataURI = (blob) => {
        return new Promise((resolve, reject) => {
          try {
            var reader = new FileReader();
            reader.readAsDataURL(blob);
            reader.onload = function (e) {
              resolve(e.target.result);
            };
          } catch (err) {
            reject(err);
          }
        });
      }
    
      // base64 to blob
      utils.dataURItoBlob = (dataURI) => {
        let mimeString = dataURI.split(",")[0].split(":")[1].split(";")[0]; // mime类型
        let byteString = atob(dataURI.split(",")[1]); //base64 解码
        let arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
        let intArray = new Uint8Array(arrayBuffer); //创建视图
        for (let i = 0; i < byteString.length; i++) {
          intArray[i] = byteString.charCodeAt(i);
        }
        return new Blob([intArray], {
          type: mimeString,
        });
      }

      对于视频和小文件,暂时没有找到合适的压缩方式。且因为 zip 的压缩率不稳定,对于压缩后文件还需要进行二次判断大小才可上传服务端,目前测试综合压缩率在 60% 左右。

      另,因项目中,源文件也可能被客户下载,因此采用了 zip 的压缩方式方便用户解压。仅就压缩率看,snappy 与 7z 也是很好的选择。

    当你看清人们的真相,于是你知道了,你可以忍受孤独
  • 相关阅读:
    设计模式系列之中介者模式(Mediator Pattern)——协调多个对象之间的交互
    设计模式系列之外观模式(Facade Pattern)——提供统一的入口
    设计模式系列之装饰模式(Decorator Pattern)——扩展系统功能
    设计模式系列之组合模式(Composite Pattern)——树形结构的处理
    设计模式系列之工厂模式三兄弟(Factory Pattern)
    设计模式系列之建造者模式(Builder Pattern)——复杂对象的组装与创建
    设计模式系列之原型模式(Prototype Pattern)——对象的克隆
    动态追踪技术之SystemTap
    一次内核 crash 的排查记录
    LLVM Coding Standards
  • 原文地址:https://www.cnblogs.com/niuyourou/p/15439325.html
Copyright © 2011-2022 走看看