@H_403_0@最近在做一个H5的项目,里边涉及到拍照上传图片的功能以及识别图片的功能,这里对识别图片的功能不做赘述,不属本文范畴。我在做完并上线项目后,同事跟我提了一个要求是可不可以同时选择多张图片上传,我做的时候的想法是如果给file表单加了 multiple 属性就没有办法调用手机的摄像头拍照了,如果不加,就无法同时选择多张图片,于是我就照实跟同事说了这个情况。但回头一想,单张图片可以上传,那多张图片呢?于是就有了本文的内容。
@H_403_0@HTML5定义了 FileReader 作为文件 API 的重要成员用于读取文件,根据 W3C 的定义,FileReader接口提供了读取文件的方法和包含读取结果的事件模型。
@H_403_0@FileReader的实例拥有 4 个方法,其中 3 个用以读取文件,另一个用来中断读取。下面的表格列出了这些方法以及他们的参数和功能,需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result 属性中。
@H_403_0@
<table style="border-top: silver 1px solid; border-right: silver 1px solid; white-space: normal; word-spacing: 0px; border-collapse: collapse; border-bottom: silver 1px solid; text-transform: none; color: rgb(0,0); padding-bottom: 0px; padding-top: 0px; font: 14px/25px 宋体,Arial,Helvetica,sans-serif; padding-left: 0px; margin: 0px; border-left: silver 1px solid; widows: 1; letter-spacing: normal; padding-right: 0px; background-color: rgb(255,255,255); text-indent: 0px; -webkit-text-stroke-width: 0px">
<thead style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px">
<tr class="header" style="padding-bottom: 0px; padding-top: 0px; padding-left: 0px; margin: 0px; padding-right: 0px">
<th style="border-top: silver 1px solid; border-right: silver 1px solid; border-collapse: collapse; border-bottom: silver 1px solid; padding-bottom: 3px; padding-top: 3px; padding-left: 3px; margin: 0px; border-left: silver 1px solid; padding-right: 3px">方法名
<th style="border-top: silver 1px solid; border-right: silver 1px solid; border-collapse: collapse; border-bottom: silver 1px solid; padding-bottom: 3px; padding-top: 3px; padding-left: 3px; margin: 0px; border-left: silver 1px solid; padding-right: 3px">参数
<th style="border-top: silver 1px solid; border-right: silver 1px solid; border-collapse: collapse; border-bottom: silver 1px solid; padding-bottom: 3px; padding-top: 3px; padding-left: 3px; margin: 0px; border-left: silver 1px solid; padding-right: 3px">描述
</tr> 文件读取为二进制码文件读取为 DataURL文件读取为文本 @H_403_0@readAsText:该方法有两个参数,其中第二个参数是文本的编码方式,默认值为 UTF-8。这个方法非常容易理解,将文件以文本方式读取,读取的结果即是这个文本文件中的内容。 @H_403_0@readAsBinaryString:该方法将文件读取为二进制字符串,通常我们将它传送到后端,后端可以通过这段字符串存储文件。 @H_403_0@readAsDataURL:这是例子程序中用到的方法,该方法将文件读取为一段以 data: 开头的字符串,这段字符串的实质就是 Data URL,Data URL是一种将小文件直接嵌入文档的方案。这里的小文件通常是指图像与 html 等格式的文件。 @H_403_0@FileReader还包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。 @H_403_0@
文件读取成功完成时触发 |
---|
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,w,h);
ctx.restore();
}
else {
ctx.drawImage(this,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();
@H_403_0@由于在通过post向服务器上传时采用了同步的方式,所以我在写项目的过程中,老是无法实现加载中的动画效果,并且把加载中的动画效果放在 reader.onloadstart方法中依旧不起作用,最后只能放在了$("#upload").change(function (e) {})方法中,代码如下:
图片流的图片通过后台转换成普通的图片路径并上传至服务器
if (res.success) {
$(".loading").hide();
var result = '
';
var div = document.createElement('div');
div.innerHTML = result;
document.body.appendChild(div);
} else {
alert(res.message);
}
},"json");
}
@H_403_0@以上在预览图片时由于不需要跳转,不需要传入返回的所有图片的路径作为参数,所以也就不需要将ajax的异步设置为同步了。
@H_403_0@以上所述是小编给大家介绍的JS移动端/H5同时选择多张图片上传并使用canvas压缩图片。编程之家 jb51.cc 收集整理的教程希望能对你有所帮助,如果觉得编程之家不错,可分享给好友!感谢支持。