最近在做一个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方法实现图片压缩详解
# 多张
# 上传
# 传至
# 的是
# 我在
# 放在
# 不需要
# 图片上传
# 这段
# 即是
# 转换成
# 表单
# 小编
# 上传图片
# 值为
# 宋体
# 是为了
# 后端
# 这是
# 他们的
相关文章:
西安制作网站公司有哪些,西安货运司机用的最多的app或者网站是什么?
linux top下的 minerd 木马清除方法
深圳网站制作的公司有哪些,dido官方网站?
如何基于云服务器快速搭建个人网站?
北京网站制作公司哪家好一点,北京租房网站有哪些?
如何在阿里云完成域名注册与建站?
如何快速生成高效建站系统源代码?
在线制作视频的网站有哪些,电脑如何制作视频短片?
建站主机类型有哪些?如何正确选型
胶州企业网站制作公司,青岛石头网络科技有限公司怎么样?
道歉网站制作流程,世纪佳缘致歉小吴事件,相亲网站身份信息伪造该如何稽查?
制作ppt免费网站有哪些,有哪些比较好的ppt模板下载网站?
建站主机助手选型指南:2025年热门推荐与高效部署技巧
如何在Tomcat中配置并部署网站项目?
无锡营销型网站制作公司,无锡网选车牌流程?
如何规划企业建站流程的关键步骤?
专业的网站制作设计是什么,如何制作一个企业网站,建设网站的基本步骤有哪些?
湖南网站制作公司,湖南上善若水科技有限公司做什么的?
重庆市网站制作公司,重庆招聘网站哪个好?
高防服务器租用指南:配置选择与快速部署攻略
c++怎么实现高并发下的无锁队列_c++ std::atomic原子变量与CAS操作【详解】
魔方云NAT建站如何实现端口转发?
定制建站方案优化指南:企业官网开发与建站费用解析
青浦网站制作公司有哪些,苹果官网发货地是哪里?
如何选择建站程序?包含哪些必备功能与类型?
如何高效利用200m空间完成建站?
如何通过多用户协作模板快速搭建高效企业网站?
专业制作网站的公司哪家好,建立一个公司网站的费用.有哪些部分,分别要多少钱?
如何在IIS服务器上快速部署高效网站?
美食网站链接制作教程视频,哪个教做美食的网站比较专业点?
活动邀请函制作网站有哪些,活动邀请函文案?
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
如何做网站制作流程,*游戏网站怎么搭建?
建站之星如何快速更换网站模板?
建站主机功能解析:服务器选择与快速搭建指南
红河网站制作公司,红河事业单位身份证如何上传?
制作充值网站的软件,做人力招聘为什么要自己交端口钱?
官网建站费用明细查询_企业建站套餐价格及收费标准指南
电视网站制作tvbox接口,云海电视怎样自定义添加电视源?
如何获取PHP WAP自助建站系统源码?
制作网站的过程怎么写,用凡科建站如何制作自己的网站?
如何零基础在云服务器搭建WordPress站点?
洛阳网站制作公司有哪些,洛阳的招聘网站都有哪些?
建站之星伪静态规则如何设置?
常州自助建站:操作简便模板丰富,企业个人快速搭建网站
详解一款开源免费的.NET文档操作组件DocX(.NET组件介绍之一)
如何在服务器上三步完成建站并提升流量?
娃派WAP自助建站:免费模板+移动优化,快速打造专业网站
韩国网站服务器搭建指南:VPS选购、域名解析与DNS配置推荐
如何制作算命网站,怎么注册算命网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。