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);

});

 
				
时间: 2024-10-01 07:18:23

H5压缩图片上传(FileReader +canvas)的相关文章

megapix-image插件 使用Canvas压缩图片上传

<!DOCTYPE html > <html> <head> <title>通过Canvas及File API缩放并上传图片</title> <script src="/Scripts/Jquery/jquery-1.8.3.min.js" type="text/javascript"></script> <script src="/Scripts/MegaPixIm

megapix-image插件 使用Canvas压缩图片上传 解决手机端图片上传功能的问题

最近在弄微信端的公众号.订阅号的相关功能,发现原本网页上用的uploadify图片上传功能到手机端有的手机类型上就不能用了,比如iphone,至于为啥我想应该不用多说了吧(uploadify使用flash实现上传的): 经过研究找到了一个手机端比较相对比较好用的插件实现图片上传,那就是megapix-image插件,比uploadify还是好用多了,下面就来上实例吧: html页面: <html> <body> <input type="file" cap

js 压缩图片 上传

感谢,参考了以下作者的绝大部分内容 https://blog.csdn.net/tangxiujiang/article/details/78755292 https://blog.csdn.net/u011415782/article/details/79978608 大概的流程就是 点击file选择图片 js将图片解读出base64编码,然后通过js将base64编码转为压缩后的base64 然后通过ajax或者form把压缩后的base64编码提交到服务器(php) 然后php将base6

H5 实现图片上传预览

1 <!DOCTYPE html> 2 <html> 3 4 <head> 5 <meta charset="utf-8" /> 6 <title>图片上传预览</title> 7 <style> 8 .check_box{ 9 position: relative; 10 width: 100px; 11 height: 100px; 12 margin: 20px; 13 display: flex

前端预览图片和H5canvas压缩图片上传

思路是将图片抽样显示在canvas上,然后用通过canvas.toDataURL方法得到base64字符串来实现压缩. 1.base64转二进制文件 /** * dataURL to blob, ref to https://gist.github.com/fupslot/5015897 * @param dataURI * @returns {Blob} */ function dataURItoBlob(dataURI) { var byteString = atob(dataURI.spl

Thumbnails 压缩图片上传阿里云服务器所遇到的问题

InputStream inputStream = null; inputStream = frontFile.getInputStream();BufferedImage bufImg = Thumbnails.of(inputStream).scale(0.2f).asBufferedImage();ByteArrayOutputStream os = new ByteArrayOutputStream();String frontFileName = frontFile.getOrigin

js压缩图片上传

1.实现,自己看代码去 // 图片压缩 // 接收三个参数: // file:是读取的文件,需要input type="file"获取或者通过js获取 // rate:压缩比例:按照原来图片的百分比 // maxSize: 压缩后的最大文件 // rate有则使用rate,最大限制拦截,会判断rate后是否大于maxSize,如果大于,则剪切,不大于,这rate // fileType:返回内容的类型:file即压缩后的第一个参数,blob是blob文件,base64是base64文件

html5+js压缩图片上传

最近在折腾移动站的开发,涉及到了一个手机里面上传图片.于是经过N久的折腾,找到一个插件,用法如下: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 <!DOCTYPE HTML> <html lang="zh-C

vuejs开发组件分享之H5图片上传、压缩及拍照旋转的问题处理

一.前言 三年.net开发转前端已经四个月了,前端主要用webpack+vue,由于后端转过来的,前端不够系统,希望分享下开发心得与园友一起学习. 图片的上传之前都是用的插件(ajaxupload),或者传统上传图片的方式,各有利弊:插件的问题是依赖jq并且会使系统比较臃肿,还有传统的web开发模式 前后端偶尔在一起及对用户体验要求低,现在公司采用webpack+vue+restfullApi开发模式 前后端完全分离,遵从高内聚,低偶尔的原则,开发人员各司其职,一则提升开发效率(从长期来看,短期