zoukankan      html  css  js  c++  java
  • H5压缩图片上传(FileReader +canvas)

    因为最近项目做一个webApp的页面,需要上传图片,总结了一下,思路如下:

    一、监听一个 input (type='file') 的 change 事件,然后拿到文件的 file;

    <input id="img-input" class="upload-input" type="file" accept="image/*" id="imgbox" multiple/>

    二、把 file 转成 dataURL;

    /**
     * file 转成 dataURL
     * @param file 文件
     * @param callback 回调函数
     */
    function fileToDataURL (file, callback) {
      const reader = new window.FileReader();
      reader.onload = function (e) {
        callback(e.target.result);
      };
      reader.readAsDataURL(file);
    }

    三、然后用 canvas 绘制图片,绘制的时候经过算法按比例裁剪,然后再把 canvas 转成 dataURL;

    /**
     * 使用 canvas 压缩 dataURL
     * @param dataURL
     * @param ratio
     * @param callback
     */
    function compressDataURL (dataURL, ratio, callback) {
      const img = new window.Image();
      img.src = dataURL;
      // onload
      img.onload = function () {
        const canvas = document.createElement('canvas');
        const ctx = canvas.getContext('2d');
        canvas.width = 100 * ratio.w;
        canvas.height = 100 * ratio.h;
        const RATIO = canvas.width / canvas.height;
        let cutx = 0;
        let cuty = 0;
        let cutw = img.width;
        let cuth = img.height;
        if (cutw / cuth > RATIO) {
          // 宽超过比例了]]
          let realw = cuth * RATIO;
          cutx = (cutw - realw) / 2;
          cutw = realw;
        } else if (cutw / cuth < RATIO) {
          // 长超过比例了]]
          let realh = cutw / RATIO;
          cuty = (cuth - realh) / 2;
          cuth = realh;
        }
        ctx.drawImage(img, cutx, cuty, cutw, cuth, 0, 0, canvas.width, canvas.height);
        const ndata = canvas.toDataURL('image/jpeg', 1);
        callback(ndata);
      };
    }

    四、 dataURL 转成 blob;

    /**
     * dataURL 转成 blob
     * @param dataURL
     * @return blob
     */
    function dataURLtoBlob (dataURL) {
      let binaryString = atob(dataURL.split(',')[1]);
      let arrayBuffer = new ArrayBuffer(binaryString.length);
      let intArray = new Uint8Array(arrayBuffer);
      let mime = dataURL.split(',')[0].match(/:(.*?);/)[1]
      for (let i = 0, j = binaryString.length; i < j; i++) {
        intArray[i] = binaryString.charCodeAt(i);
      }
      let data = [intArray];
      let result;
      try {
        result = new Blob(data, { type: mime });
      } catch (error) {
        window.BlobBuilder = window.BlobBuilder ||
          window.WebKitBlobBuilder ||
          window.MozBlobBuilder ||
          window.MSBlobBuilder;
        if (error.name === 'TypeError' && window.BlobBuilder){
          var builder = new BlobBuilder();
          builder.append(arrayBuffer);
          result = builder.getBlob(type);
        } else {
          throw new Error('暂不支持');
        }
      }
      return result;
    }

    五、把 blob append 到 FormData 的实例对象,然后上传。

    var imgBox =document.getElementById("imgbox");
    var blobArr = []; //参数可以传给后台 imgBox.change
    = function(e){ var file=this.files; for(var i=0;i<event.target.files.length;i++){ fileToDataURL(file[i], function(dataURL){ compressDataURL(dataURL,function (newDataURL) {             const newBlob = this.dataURLtoBlob(newDataURL,file[i]); //const fileOfBlob = new File([newBlob], file[i].name); //可将blob转换成file格式 blobArr.push(newBlob); }); }); } }

    //上传
    var
    formData = new FormData();
    for (var i = 0, len = blobArr.file.length; i < len; i++) {
      formData.append("file" + i, options.file[i]);
    }

    let xhr = new XMLHttpRequest();
     
    // 进度监听
    // xhr.upload.addEventListener('progress', progFoo, false);
    // 加载监听
    // xhr.addEventListener('load', loadFoo, false);
    // 错误监听
    // xhr.addEventListener('error', errorFoo, false);
     
    xhr.onreadystatechange = function () {
      if (xhr.readyState === 4) {
        if (xhr.status === 200) {
        // 上传成功,获取到结果 results
        let results = JSON.parse(xhr.responseText);
        // ......
        }
        } else {
        // 上传失败
        }
      }
    };
      xhr.open('POST', '/api/upload', true);
      xhr.send(formData);
    });
     
    
    
  • 相关阅读:
    python学习(20) 网络编程
    MySQL与mongodb数据库备份与恢复
    Java(一)——Ubuntu18.04下Java环境配置
    安全服务——CVE中CVSS相关指标介绍
    爬虫(十一)—— 请求库(三)pypeteer请求库
    爬虫(十)—— scrapy框架
    抓包工具Fiddler
    爬虫(九)—— 爬虫高性能
    爬虫(八)—— 存储库(三)MySQL存储库
    爬虫(七)—— 存储库(二)Redis存储库
  • 原文地址:https://www.cnblogs.com/dakini/p/7454592.html
Copyright © 2011-2022 走看看