本以为解决跨域上传后没有问题了,不成想被测试找出一个问题,那就是在手机上拍照上传后图片会旋转。很头痛,不过没有办法,问题还是需要解决的。在查阅了一系列资料后我找到了相应的解决方案,利用exif.js获取图片旋转的方向,然后再转过来图片,之后再上传。这个方案需要修改前面的脚本,同样的,由于要传base64字符串,后台也要做出相应的修改。下面是我修改后的相应代码:

 (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 >= 50)
{
this.ShowMsg("你的图片超过了50张,不能再上传");
return;
}
if (imgLength + where.files.length > 50)
{
this.ShowMsg("你选择的图片超过了50张,无法上传,请重新选择");
return;
} var _this = this;
var radtime = new Date();
var sid = radtime.getTime();
this.successCount=0;
for (var i = 0; i < where.files.length; i++) {
var formData = new FormData();
var file = where.files[i];
var orientation = 1; if (file.name.indexOf("jpg") > -1) {
EXIF.getData(file, function () {
EXIF.getAllTags(this);
orientation = EXIF.getTag(this, 'Orientation');
if (orientation) {
var reader = new FileReader();
reader.onload = function (e) {
_this.getImgData(e, this.result, orientation, function (data) { var base64String = data;
formData.append("icoimage", base64String);
_this.UploadImg(where, formData, sid, i);
});
}
reader.readAsDataURL(file);
} else {
formData.append("icoimage", file);
_this.UploadImg(where, formData, sid, i);
}
});
} else {
formData.append("icoimage", file);
_this.UploadImg(where, formData, sid, i);
} } },
UploadImg: function (where, formData, sid, i) {
var _this = this;
$.ajax({
url: this.uploadUrl + '?channel=频道&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 + "张图片");
}
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.drawImage(this,0,0,drawWidth,drawHeight);
//返回校正图片
next(canvas.toDataURL("image/jpeg",.8));
}
image.src=img;
} } imgOperate.onload();
window.imgOperate = imgOperate; })();

前端脚本

   public override void ProcessRequest(HttpContext context)
{
//获取目标站点地址
String target = "图片服务器地址";
string sid = context.Request["sid"];
target = string.Format("{0}?city=&channel=频道&sid={1}&backurl=",target,sid);
string imgText = string.Empty;
if (context.Request.Files.Count == && string.IsNullOrEmpty(imgText=context.Request["icoimage"]))
{
Response.Write("");
Response.End();
} Stream stream = new MemoryStream();
string fileName = string.Empty;
byte[] bArr = null;
if (context.Request.Files.Count > )
{
var file = context.Request.Files[];
fileName = file.FileName;
stream = file.InputStream;
bArr = new byte[stream.Length];
stream.Read(bArr, , bArr.Length);
stream.Close();
}
else {
imgText = HttpUtility.UrlDecode(imgText);
imgText = Regex.Match(imgText, "(?<=,).*").Value;
imgText= imgText.Trim().Replace("%", "").Replace(",", "").Replace(" ", "+");
if (imgText.Length % > )
{
imgText = imgText.PadRight(imgText.Length + - imgText.Length % , '=');
}
bArr=Convert.FromBase64String(imgText); fileName = "base64.png"; }
HttpWebRequest request = WebRequest.Create(target) as HttpWebRequest;
CookieContainer cookieContainer = new CookieContainer();
request.CookieContainer = cookieContainer;
request.AllowAutoRedirect = true;
request.Method = "POST";
request.Headers.Add("Origin", "http://" + context.Request.UrlReferrer.Host);
request.Headers.Add("Accept-Encoding", "gzip, deflate");
request.Headers.Add("Accept-Language", "zh-CN,zh;q=0.8");
request.Headers.Add("Upgrade-Insecure-Requests", "");
request.Referer = context.Request.UrlReferrer.OriginalString;
string boundary = DateTime.Now.Ticks.ToString("X"); // 随机分隔线
request.ContentType = "multipart/form-data;charset=utf-8;boundary=" + boundary;
byte[] itemBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "\r\n");
byte[] endBoundaryBytes = Encoding.UTF8.GetBytes("\r\n--" + boundary + "--\r\n"); //请求头部信息
StringBuilder sbHeader = new StringBuilder(string.Format("Content-Disposition:form-data;name=\"file\";filename=\"{0}\"\r\nContent-Type:application/octet-stream\r\n\r\n",fileName));
byte[] postHeaderBytes = Encoding.UTF8.GetBytes(sbHeader.ToString()); Stream postStream = request.GetRequestStream();
postStream.Write(itemBoundaryBytes, , itemBoundaryBytes.Length);
postStream.Write(postHeaderBytes, , postHeaderBytes.Length);
postStream.Write(bArr, , bArr.Length);
postStream.Write(endBoundaryBytes, , endBoundaryBytes.Length);
postStream.Close();
//发送请求并获取相应回应数据
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
SetCookie(response,context); } //response是目标服务器的响应对象,context是返回给浏览器的上下文对象
void SetCookie(HttpWebResponse response, HttpContext context)
{
foreach (Cookie cookie in response.Cookies)
{
if (cookie.Name!=null&&cookie.Name.StartsWith("Picture"))
{
string result=string.Empty;
if (cookie.Value != null && cookie.Value.StartsWith("http://"))
{
Regex r = new Regex(@"^.*?(?=\|)");
result = r.Match(cookie.Value).Value;
}
else {
result = cookie.Value;
}
context.Response.Write(result);
context.Response.End();
} }
}

本次遇到的难题主要是解析base64字符串的问题,总是遇到"输入的不是有效的 Base-64 字符串,因为它包含非 Base-64 字符、两个以上的填充字"。经过反复的调整,终于实现了相应的功能。

html5上传图片(二)一解决部分手机拍照上传图片转向问题的更多相关文章

  1. 大朋展翅 html5上传图片(三)一解决部分手机拍相册批量上传图片转向问题

    在经过前面的改进之后本来以为已经没有问题了,但经过我们神通广大的测试的测试,发现相册中的图片在上传时也会发生转向问题.既然前面都解决了拍照转向的问题,那么相册中图片的上传也容易解决.修改一下需要旋转图 ...

  2. 解决android有的手机拍照后上传图片被旋转的问题

    转至 http://blog.csdn.net/walker02/article/details/8211628 需求:做仿新浪发微博的项目,能够上传图片还有两外一个项目用到手机拍摄图片,这两个都需要 ...

  3. HTML5+Canvas+jQuery调用手机拍照功能实现图片上传(二)

    上一篇仅仅讲到前台操作,这篇专门涉及到Java后台处理.前台通过Ajax提交将Base64编码过的图片数据信息传到Java后台,然后Java这边进行接收处理.通过对图片数据信息进行Base64解码,之 ...

  4. 利用html5调用本地摄像头拍照上传图片[转]

    利用html5调用本地摄像头拍照上传图片   html5概念啥的就不废话了,不知道的 百度, 谷歌一堆..今天学了学html5中的Canvas结合新增的<video>标签来获取本地摄像头, ...

  5. 结合NGUI做的手机拍照(可自定义相框)

    原地址:http://www.unity蛮牛.com/thread-18220-1-1.html 在次此之前我们先要了解一下下面的我要讲的几个内容: 一.为什么要用NGUI,因为NGUI的可以做屏幕自 ...

  6. atitit.html5 拼图游戏的解决之道.

    atitit.html5 拼图游戏的解决之道. 1. 拼图游戏的操作(点击法and 拖动法) 1 1. 支持键盘上.下.左.右键移动: 1 2. 支持点击空白模块中的上下左右箭头移动: 1 3. 支持 ...

  7. php实现手机拍照上传头像功能

    现在手机拍照很火,那么如何使用手机拍照并上传头像呢?原因很简单,就是数据传递,首先手机传递照片信息,这个就不是post传递 也不是get函数传递, 这个另外一种数据格式传递,使用的是$GLOBALS ...

  8. android 手机拍照返回 Intent==null 以及intent.getData==null

    手机拍照第一种情况:private void takePicture(){ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);Si ...

  9. android手机拍照旋转的问题

    android开发中,遇到过手机拍照,明明是竖着拍的,显示的结果却是横这的,困扰了很久,找了很久找了一种解决方法: ExifInterface exifInterface = new ExifInte ...

随机推荐

  1. 关于asp.net利用mono部署到Linux上的一些说明

    linuxdot.net社区群:102732979(如果你认为你已经在.NET跨平台方面有足够的经验,请参加这个群:103810355). 其中有各种大神,嘿嘿,如果你有问题可以来咨询,完全无偿的免费 ...

  2. 超炫的HTML5粒子效果进度条 VS 如何规范而优雅地code

    最近瞎逛的时候发现了一个超炫的粒子进度效果,有多炫呢?请擦亮眼镜!   // _this.ch){ _this.particles.splice(i, 1); } }; this.Particle.p ...

  3. APP技术演化的路

    谈起APP,大家都太熟悉不过了,今天想谈谈这么多年技术演化的路. 早期一些大公司就开始做一些APP了,例如facebook.google等国外的公司就已经开发这个技术路线,那个时候的APP数量很少,基 ...

  4. CSS3变形记(上):千变万化的Div

    传统上,css就是用来对网页进行布局和渲染网页样式的.然而,css3的出现彻底打破了这一格局.了解过css3的人都知道,css3不但可以对网页进行布局和渲染样式,还可以绘制一些图形.对元素进行2D和3 ...

  5. 提高代码质量系列之二:重构小技巧——if篇

    前言: if,相信是童鞋们使用的最频繁的关键字了,而且很多时候,我们使用的if都是在无意识的状态下随手而为.键入if,两下回车(我使用了resharper,可以自动编排if的格式),再信手写下我们需要 ...

  6. ABP框架 - 数据过滤

    文档目录 本节内容: 简介 预定义过滤 ISoftDelete 何时可用? IMustHaveTenant 何时可用? IMayHaveTenant 何时可用? 禁用过滤 关于using声明 关于多租 ...

  7. Entity Framework 6 Recipes 2nd Edition(13-1)译 -> 优化TPT继承模型的查询

    问题 你想提高在一个TPT继承模型里的查询 解决方案 让我们假设有一个简单的TPT继承模型,如图Figure 13-1 Figure 13-1. A simple Table per Type inh ...

  8. 实现MVC自定义过滤器,自定义Area过滤器,自定义Controller,Action甚至是ViewData过滤器

    MVC开发中几种以AOP方式实现的Filters是非常好用的,默认情况下,我们通过App_Start中的FilterConfig来实现的过滤器注册是全局的,也就是整个应用程序都会使用的,针对单独的Fi ...

  9. Linux下的磁盘分割和文件系统

    一.各硬件装置在Linux下的文件名 1.IDE硬盘机 在Linux内的文件名: /dev/hd[a-d]  (a-d 刚好是四个这个是有原因的具体如下) 解释:以 IDE 接口来说,由于一个 IDE ...

  10. 使用MATLAB对图像处理的几种方法(上)

    实验一图像的滤波处理 一.实验目的 使用MATLAB处理图像,掌握均值滤波器和加权均值滤波器的使用,对比两种滤波器对图像处理结果及系统自带函数和自定义函数性能的比较,体会不同大小的掩模对图像细节的影响 ...