全网整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:400-708-3566

JS移动端/H5同时选择多张图片上传并使用canvas压缩图片

最近在做一个H5的项目,里边涉及到拍照上传图片的功能以及识别图片的功能,这里对识别图片的功能不做赘述,不属本文范畴。我在做完并上线项目后,同事跟我提了一个要求是可不可以同时选择多张图片上传,我做的时候的想法是如果给file表单加了 multiple 属性就没有办法调用手机的摄像头拍照了,如果不加,就无法同时选择多张图片,于是我就照实跟同事说了这个情况。但回头一想,单张图片可以上传,那多张图片呢?于是就有了本文的内容。

HTML5定义了 FileReader 作为文件 API 的重要成员用于读取文件,根据 W3C 的定义,FileReader接口提供了读取文件的方法和包含读取结果的事件模型。

FileReader的实例拥有 4 个方法,其中 3 个用以读取文件,另一个用来中断读取。下面的表格列出了这些方法以及他们的参数和功能,需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result 属性中。

方法名 参数 描述
abort none 中断读取
readAsBinaryString file 将文件读取为二进制码
readAsDataURL file 将文件读取为 DataURL
readAsText file, [encoding] 将文件读取为文本

readAsText:该方法有两个参数,其中第二个参数是文本的编码方式,默认值为 UTF-8。这个方法非常容易理解,将文件以文本方式读取,读取的结果即是这个文本文件中的内容。

readAsBinaryString:该方法将文件读取为二进制字符串,通常我们将它传送到后端,后端可以通过这段字符串存储文件。

readAsDataURL:这是例子程序中用到的方法,该方法将文件读取为一段以 data: 开头的字符串,这段字符串的实质就是 Data URL,Data URL是一种将小文件直接嵌入文档的方案。这里的小文件通常是指图像与 html 等格式的文件。

FileReader还包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。

事件 描述
onabort 中断时触发
onerror 出错时触发
onload 文件读取成功完成时触发
onloadend 读取完成触发,无论成功或失败
onloadstart 读取开始时触发
onprogress 读取中

文件一旦开始读取,无论成功或失败,实例的 result 属性都会被填充。如果读取失败,则 result 的值为 null ,否则即是读取的结果,绝大多数的程序都会在成功读取文件的时候,抓取这个值。

了解了H5提供的 FileReader 后,我们就使用 FileReader 来实现同事选择多张图片并上传。

首先,在 HTML 加入一个file表单,并设置其为 multiple(浏览器在对multiple、disabled、checked、selected等这类属性进行解析时,只要这些属性存在,默认的就会被解析成true,甭管你设置的是disabled=true或者disabled=false亦或是disabled="",如果不想这些属性起作用,唯有用js来remove掉这些属性,除非你不设置这些属性。),并设置accept="image/*"用以只能选择图片类型的文件,代码如下:

<input type="file" accept="image/*" name="upload" id="upload" multiple>
<input type="hidden" id="hiddenImgUrl" />  <!--设置这个隐藏域是为了便于存放上传至服务器后返回的图片地址-->

接下来就到了js上场了:

//图片上传
var file = {
  upload: function (e) {
    var self = this;
    var files = e.target.files;
    var type = files[0].type.split('/')[0];
    if (type != 'image') {
      alertMsg('请上传图片');
      return;
    }
    //var size = Math.floor(file.size / 1024 / 1024);
    //if (size > 3) {
    //  alert('图片大小不得超过3M');
    //  return;
    //};
    for (var i = 0; i < files.length; i++) {
      var reader = new FileReader();
      reader.readAsDataURL(files[i]);
      reader.onloadstart = function () {
        //用以在上传前加入一些事件或效果,如载入中...的动画效果
      };
      reader.onloadend = function (e) {
        var dataURL = this.result;
        var imaged = new Image();
        imaged.src = dataURL;
        imaged.onload = function () {  //利用canvas对图片进行压缩
          var canvas = document.createElement('canvas');
          var ctx = canvas.getContext('2d');
          var w = 0;
          var h = 0;
          if (this.width > this.height) {
            h = 1000;
            var scale = this.width / this.height;
            h = h > this.height ? this.height : h;
            w = h * scale;
          }
          else {
            w = 1000;
            var scale = this.width / this.height;
            w = w > this.width ? this.width : w
            h = w / scale;
          }
          var anw = document.createAttribute("width");
          var anh = document.createAttribute("height");
          if (this.width > this.height) {
            anw.value = h;
            anh.value = w;
          }
          else {
            anw.value = w;
            anh.value = h;
          }
          canvas.setAttributeNode(anw);
          canvas.setAttributeNode(anh);
          if (this.width > this.height) {
            ctx.translate(h, 0);
            ctx.rotate(90 * Math.PI / 180)
            ctx.drawImage(this, 0, 0, w, h);
            ctx.restore();
          }
          else {
            ctx.drawImage(this, 0, 0, w, h);
          }
          dataURL = canvas.toDataURL('image/jpeg');
          //回调函数用以向数据库提交数据
          self.callback(dataURL);
        };
      };
    }
  },
  event: function () {
    $("#upload").change(function (e) {      
      file.upload(e);
    });
  },
  callback: function (dataURL) {
    $.ajaxSettings.async = false;  //这里必须将ajax的异步改为同步才可以把返回并保存在隐藏域中的图片地址取出同时加在地址栏中作为参数一并传入下一个页面,这样做的目的是因为返回的图片地址不是一个json数组,而是单个的json字符串,所以只能将返回的图片地址json字符串拼接在一起作为参数传到下一个页面
    $.post(url, dataURL, function (res) {  //将base64图片流的图片通过后台转换成普通的图片路径并上传至服务器
      var imgUrl = $("#hiddenImgUrl").val();
      if (res.success) {
        $(".loading").hide();
        if (imgUrl != "") {
          $("#hiddenImgUrl").val(imgUrl + "|" + res.imgUrl);  //中间加一个 | 是为了到下一个页面便于将传过去的图片地址参数转换为数组
        } else {
          $("#hiddenImgUrl").val(res.imgUrl);
        }
        var imgUrl = $("#hiddenImgUrl").val();
        window.location.href = "apply.html?imgUrl=" + imgUrl;
      } else {
        alert(res.message);
      }
    }, "json");
  },
  init: function () {
    this.event();
  }
}
file.init();

由于在通过post向服务器上传时采用了同步的方式,所以我在写项目的过程中,老是无法实现加载中的动画效果,并且把加载中的动画效果放在 reader.onloadstart方法中依旧不起作用,最后只能放在了$("#upload").change(function (e) {})方法中,代码如下:

event: function () {
    $("#upload").change(function (e) {
      $(".loading").show();     
      file.upload(e);
    });
  }

以上是同时上传多张图片并将图片传入下一个页面继续进行后续操作,那么如何在同时上传完多张图片后在本页再预览这些图片呢?其实方法也是很简单的,上边callback函数里边的$.post的返回值里就包含了上传至服务器后的图片路径,将这些路径赋给img标签的src,然后再插入到页面中就OK了,代码如下:

callback: function (dataURL) {    
    $.post(url, dataURL, function (res) {  //将base64图片流的图片通过后台转换成普通的图片路径并上传至服务器
      if (res.success) {
        $(".loading").hide();
        var result = '<div class="result"><img src="'+res.imgUrl+'" alt=""/></div>';
        var div = document.createElement('div');
        div.innerHTML = result;
        document.body.appendChild(div);        
      } else {
        alert(res.message);
      }
    }, "json");
  }

以上在预览图片时由于不需要跳转,不需要传入返回的所有图片的路径作为参数,所以也就不需要将ajax的异步设置为同步了。

以上所述是小编给大家介绍的JS移动端/H5同时选择多张图片上传并使用canvas压缩图片,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!


# js  # 移动端多张图片上传  # h5  # canvas  # 压缩  # 小程序中canvas的drawImage方法参数使用详解  # 微信小程序canvas.drawImage完全显示图片问题的解决  # canvas压缩图片转换成base64格式输出文件流  # Vue使用canvas实现图片压缩上传  # JS和Canvas实现图片的预览压缩和上传功能  # Js利用Canvas实现图片压缩功能  # Canvas drawImage方法实现图片压缩详解  # 多张  # 上传  # 传至  # 的是  # 我在  # 放在  # 不需要  # 图片上传  # 这段  # 即是  # 转换成  # 表单  # 小编  # 上传图片  # 值为  # 宋体  # 是为了  # 后端  # 这是  # 他们的 


相关文章: 历史网站制作软件,华为如何找回被删除的网站?  建站主机服务器选型指南与性能优化方案解析  教程网站设计制作软件,怎么创建自己的一个网站?  如何选择长沙网站建站模板?H5响应式与品牌定制哪个更优?  建站主机助手选型指南:2025年热门推荐与高效部署技巧  小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?  动图在线制作网站有哪些,滑动动图图集怎么做?  如何规划企业建站流程的关键步骤?  官网网站制作腾讯审核要多久,联想路由器newifi官网  大连企业网站制作公司,大连2025企业社保缴费网上缴费流程?  h5在线制作网站电脑版下载,h5网页制作软件?  平台云上自助建站如何快速打造专业网站?  湖北网站制作公司有哪些,湖北清能集团官网?  建站VPS推荐:2025年高性能服务器配置指南  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  建站之星如何快速更换网站模板?  南平网站制作公司,2025年南平市事业单位报名时间?  微信推文制作网站有哪些,怎么做微信推文,急?  XML的“混合内容”是什么 怎么用DTD或XSD定义  如何通过云梦建站系统实现SEO快速优化?  建站之星导航菜单设置与功能模块配置全攻略  攀枝花网站建设,攀枝花营业执照网上怎么年审?  如何配置IIS站点权限与局域网访问?  ,巨量百应是干嘛的?  javascript中的try catch异常捕获机制用法分析  c# Task.ConfigureAwait(true) 在什么场景下是必须的  表情包在线制作网站免费,表情包怎么弄?  如何快速打造个性化非模板自助建站?  网站专业制作公司有哪些,做一个公司网站要多少钱?  天河区网站制作公司,广州天河区如何办理身份证?需要什么资料有预约的网站吗?  广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?  图片制作网站免费软件,有没有免费的网站或软件可以将图片批量转为A4大小的pdf?  教学论文网站制作软件有哪些,写论文用什么软件 ?  如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?  成都品牌网站制作公司,成都营业执照年报网上怎么办理?  郑州企业网站制作公司,郑州招聘网站有哪些?  如何在沈阳梯子盘古建站优化SEO排名与功能模块?  如何快速上传自定义模板至建站之星?  建站之星图片链接生成指南:自助建站与智能设计教程  网站设计制作公司地址,网站建设比较好的公司都有哪些?  实例解析Array和String方法  如何在Golang中处理模块冲突_解决依赖版本不兼容问题  广州商城建站系统开发成本与周期如何控制?  建站主机选购指南:核心配置与性价比推荐解析  网站企业制作流程,用什么语言做企业网站比较好?  如何在Golang中实现微服务服务拆分_Golang微服务拆分与接口管理方法  如何通过二级域名建站提升品牌影响力?  清单制作人网站有哪些,近日“兴风作浪的姑奶奶”引起很多人的关注这是什么事情?  网站制作公司排行榜,四大门户网站排名? 

您的项目需求

*请认真填写需求信息,我们会在24小时内与您取得联系。