最近做微信端开发,需要做到的是跟Android和iOS一样的多图上传功能,选完图片后,马上可以预览,然后点击上传可以将所有图片包含文字数据传递到后台服务器。
遇到的坑:图片太大的时候(超过2M),后台接到数据都为null,包括文字数据。 经过一番研究顺利解决这个坑。
解决方法:
1:如果想按照原图发送,并且以ajax去传,那么务必修改tomcat服务器的配置文件,取消post数据的限制,默认是限制2M。
<Connector port="8081"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
debug="0" connectionTimeout="20000"
disableUploadTimeout="true" URIEncoding="GBK"
maxPostSize="0"/> //maxPostSize="0"表示post数据无限制
2:压缩图片:这也是我采取的方式:现在手机一张图片最少3M以上,所以压缩图片成为一种必须
前端方面:
<div class="weui-uploader__bd">
<ul class="weui-uploader__files" id="uploaderFiles">
</ul>
<input type="file" id="file" accept="image/*;" capture="camera" >
</div>
JS:
图片压缩和追加到控件中**/
document.getElementById('file').addEventListener('change', function() {
var reader = new FileReader();
reader.onload = function (e) {
compress(this.result);
};
reader.readAsDataURL(this.files[0]);
}, false);
var compress = function (res) {
var img = new Image(),
maxH = 750;
img.src=res;
img.onload = function () {
var cvs = document.createElement('canvas'),
ctx = cvs.getContext('2d');
if(img.height > maxH) {
img.width *= maxH / img.height;
img.height = maxH;
}
cvs.width = img.width;
cvs.height = img.height;
ctx.clearRect(0, 0, cvs.width, cvs.height);
ctx.drawImage(img, 0, 0, img.width, img.height);
var dataUrl = cvs.toDataURL('image/jpeg', 0.9); //dataUrl就是base64位编码的数据
$("#uploaderFiles").append("<li><img class='weui-uploader__file' src='"+dataUrl+"'></li>");
}
}
上传的时候将所有的图片数据的base64编码用特定格式拼接起来(长字符串)
组装图片的base64位编码*/
function putimg()
{
var arr=$("img");
if(""===phoneImg)
{
for(var i=0;i<arr.length;i++)
{
phoneImg=phoneImg+arr[i].src+";..;"; //phoneImg就是所有的图片数据
}
}
}
然后是ajax上传了:
$.ajax({
type: 'post',
url: '${pageContext.request.contextPath}/WOaWork/save.do', //指明传递到底动作位置
dataType: 'json', //数据类型,
data: obj, //这就是传给面动作的参数
success: function (data) { //传递成功则执行这个函数
if(data.state=="success"){
$.toptip('提交成功', 'success');
history.back(-1);
}
else{
$.toptip('出现错误', 'success');
}
}
});
后端的核心代码是:拿到图片的字符串后,对字符串进行切割,成为图片数组。然后将图片数据解密成图片:
*
*author:cwy
*说明:
*参数:
* @param imgStr-------网页传递过来的图片base64编码一般都会在真正的图片数据前面带上:data:image/png;base64 类似这样的格式
* @return
*/
public static String getImgStr(String imgStr)
{
String img="";
if(imgStr.indexOf("data:image/png;base64")!=-1)
{
img=imgStr.substring("data:image/png;base64".length()+1);
}
if(imgStr.indexOf("data:image/jpeg;base64")!=-1)
{
img=imgStr.substring("data:image/jpeg;base64".length()+1);
}
return img;
}
*
*author:cwy
*说明:
*参数:
* @param imgStr ----base64位图片编码
* @param path ----图片路径
* @return
*/
public static boolean generateImage(String imgStr, String path) {
imgStr=getImgStr(imgStr);
if (StringUtils.isEmpty(imgStr))
{
return false;
}
OutputStream out=null;
try {
BASE64Decoder decoder = new BASE64Decoder();
// 解密
byte[] b= decoder.decodeBuffer(imgStr);
// 处理数据
for (int i = 0; i < b.length; ++i) {
if (b[i] < 0) {
b[i] += 256;
}
}
out = new FileOutputStream(path);
out.write(b);
out.flush();
out.close();
}
catch (IOException e) {
return false;
}
return true;
}
至此:功能完毕。