在经过前面的改进之后本来以为已经没有问题了,但经过我们神通广大的测试的测试,发现相册中的图片在上传时也会发生转向问题。既然前面都解决了拍照转向的问题,那么相册中图片的上传也容易解决。修改一下需要旋转图片的类型判定即可,修改如下:
var type = file.name.match(/\.\w+$/)[0].toLowerCase();
if (type == ".jpg" || type == ".jpeg")
凡是jpg类型的图片都要旋转,经过测试,相册中的单张上传是可以的,但批量上传的功能竟然失效了。用fiddler抓包发现,上传的base64字符串是包含多张图片,以至于后台代码在解析字符串时出错。再次阅读代码可以发现,代码中包还了多个异步操作,如使用FileReader、ajax上传图片、图片信息获取( EXIF.getData)、图片加载(img.onload)等。使用异步可以提高代码的执行效率,但是也往往会带来资源竞争的问题,我决定在一张图片读完之后再读取下一张图片,for循环显然是不可行了,我使用了递归来保证了这一点,修改代码如下:
(function () {
var imgOperate = {
operateUrl: "数据库操作地址",
uploadUrl: "上传图片地址",
DelPicId: '',
ddWidth: 0,
dlWidth: 0,
successCount:0,
onload: function () {
this.initImage();
},
initImage: function () {
var et = $('#entrust dd').length;
this.ddWidth = $('#entrust dd').width() + 17;
this.dlWidth = parseInt(et * this.ddWidth + 160);
$('#entrust').css("width", this.dlWidth);
this.BindEvent();
},
BindEvent: function () {
var _this = this;
$("#pic0").on("change", function () {
_this.uploadFiles(this); }); },
InserImage:function(urls,dd)
{
$.post(this.operateUrl, { houseid: houseid, operateType: 1, picStr: urls }, function (data) {
data = eval("(" + data + ")");
if (data && data.picIds)
{
dd.getElementsByTagName("img")[0].setAttribute("housepicid", data.picIds);
}
});
},
uploadFiles: function (where) {
if (!houseid) {
this.ShowMsg("请回到第一步完善相应的信息");
return;
}
var imgLength = $("#entrust dd").length - 1; if (imgLength >= 20)
{
this.ShowMsg("你的图片超过了20张,不能再上传");
return;
}
if (imgLength + where.files.length > 20)
{
this.ShowMsg("你选择的图片超过了20张,无法上传,请重新选择");
return;
} var _this = this;
var radtime = new Date();
var sid = radtime.getTime();
this.successCount = 0;
this.UploadNext(0, sid, where);
},
UploadNext: function (i, sid, where)
{
if (i >= where.files.length) return;
var file = where.files[i];
var type = file.name.match(/\.\w+$/)[0].toLowerCase();
if (type == ".jpg" || type == ".jpeg") {
this.UploadJpg(i, sid, where);
} else {
var formData = new FormData();
formData.append("icoimage", file);
this.UploadImg(where, formData, sid, i);
i++;
this.UploadNext(i++, sid, where);
} },
UploadJpg:function(i,sid,where)
{
var _this = this;
var file = where.files[i];
EXIF.getData(file, function () {
var formData = new FormData(); EXIF.getAllTags(this);
var orientation = EXIF.getTag(this, 'Orientation'); if (orientation && orientation >= 2 && orientation<=8) {
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
_this.getImgData(e, this.result, orientation, function (data) {
formData.append("icoimage", data);
_this.UploadImg(where, formData, sid, i);
i++;
_this.UploadNext(i, sid, where); });
} } else { formData.append("icoimage", file);
_this.UploadImg(where, formData, sid, i);
i++;
_this.UploadNext(i, sid, where); }
});
},
UploadImg: function (where, formData, sid, i) {
var _this = this;
$.ajax({
url: this.uploadUrl + '?channel=duanzu.houseinfo&sid=' + sid,
type: 'POST',
cache: false,
data: formData,
processData: false,
contentType: false
}).success(function (res) {
var imgsrc = res;
if (imgsrc == "-1" || imgsrc == "302" || imgsrc == -1 || imgsrc == 302) {
_this.ShowMsg("上传失败,照片超过10M");
} else if (imgsrc.indexOf("http") != -1) {
var dd = document.createElement("dd");
if ($("#entrust dd").length == 1) {
dd.innerHTML = "<div class=\"cver\">封面图</div><a class=\"close\"></a><img src=\"" + imgsrc + "\" housepicid=\"\">";
} else {
dd.innerHTML = "<a class=\"close\"></a><img src=\"" + imgsrc + "\" housepicid=\"\">";
}
document.getElementById("entrust").appendChild(dd);
_this.dlWidth += _this.ddWidth + 17;
$('#entrust').css("width", _this.dlWidth);
_this.InserImage(imgsrc, dd);
this.successCount++;
_this.ShowMsg("正在上传第" + (i+1)+ "张图片");
}
if (i == where.files.length) {
if (this.successCount > 0) {
_this.ShowMsg("成功上传" + successCount + ",可继续上传新照片");
}
}
})
},
ShowMsg: function (text, mymethod) {
var radtime = new Date();
var sid = radtime.getTime();
var msg_div = "<div class='zuopenbox' id='div_msg" + sid + "'><div class='opencon_01'><div class='openList'><h3 class='f15' style='margin-bottom: 0; color: #FFFFFF'>" + text + "</h3></div></div></div>"; $(msg_div).appendTo("body");
var _this = this;
setTimeout(function () {
var d = 0.5;
var m = document.getElementById("div_msg"+sid);
m.style.webkitTransition = '-webkit-transform ' + d + 's ease-in, opacity ' + d + 's ease-in';
m.style.opacity = '0';
setTimeout(_this.RemoveNode(m), 500);
}, 500);
},
RemoveNode: function (m) {
m.parentNode.removeChild(m);
},
// @param {string} img 图片的base64
// @param {int} dir exif获取的方向信息
// @param {function} next 回调方法,返回校正方向后的base64
getImgData: function (e,img, dir, next) {
var _this = this;
var image = new Image();
image.src = e.target.result;
image.onload=function(){
var degree=0,drawWidth,drawHeight,width,height;
drawWidth=this.naturalWidth;
drawHeight=this.naturalHeight;
//以下改变一下图片大小
var maxSide = Math.max(drawWidth, drawHeight);
if (maxSide > 1024) {
var minSide = Math.min(drawWidth, drawHeight);
minSide = minSide / maxSide * 1024;
maxSide = 1024;
if (drawWidth > drawHeight) {
drawWidth = maxSide;
drawHeight = minSide;
} else {
drawWidth = minSide;
drawHeight = maxSide;
}
}
var canvas=document.createElement('canvas');
canvas.width=width=drawWidth;
canvas.height=height=drawHeight;
var context = canvas.getContext('2d');
//判断图片方向,重置canvas大小,确定旋转角度,iphone默认的是home键在右方的横屏拍摄方式
switch(dir){
case 2:
context.translate(width, 0);
context.scale(-1, 1);
break;
case 3:
context.translate(width, height);
context.rotate(Math.PI);
break;
case 4:
context.translate(0, height);
context.scale(1, -1);
break;
case 5:
context.rotate(0.5 * Math.PI);
context.scale(1, -1);
break;
case 6:
context.rotate(0.5 * Math.PI);
context.translate(0, -height);
break;
case 7:
context.rotate(0.5 * Math.PI);
context.translate(width, -height);
context.scale(-1, 1);
break;
case 8:
context.rotate(-0.5 * Math.PI);
context.translate(-width, 0);
break; }
context.beginPath();
context.drawImage(this,0,0,drawWidth,drawHeight);
//返回校正图片
next(canvas.toDataURL("image/jpeg",.8));
}
} } imgOperate.onload();
window.imgOperate = imgOperate; })();
在解决了上面问题后又发现了一些型号的手机图片竟然无法上传,我将它们的图片转到电脑上来测试,发现原因是它们的图片太大,已经超过了默认的4M。为此,我修改了一下配置,解决了相关的问题,配置修改如下:
<location path="图片代理服务器地址">
<system.web>
<httpRuntime maxRequestLength="10240"/>
</system.web>
</location>
使用location可以仅让上传图片的页面增加参数最大可传的值,而不会影响其它正常的页面。