HTML5 本地裁剪图片并上传至服务器(老梗)
2015-01-04 12:54
295 查看
很多情况下用户上传的图片都需要经过裁剪,比如头像啊什么的。但以前实现这类需求都很复杂,往往需要先把图片上传到服务器,然后返回给用户,让用户确定裁剪坐标,发送给服务器,服务器裁剪完再返回给用户,来回需要 5 步。步骤繁琐不说,当很多用户上传图片的时候也很影响服务器性能。
HTML5 的出现让我们可以更方便的实现这一需求。虽然这里所说的技术都貌似有点过时了(前端界的“过时”,你懂的),但还是有些许参考价值。在这里我只说一下要点,具体实现同学们慢慢研究。
下面奉上我自己写的一个demo,在输入框中选好自己服务器 url, 生成好图片后点击 Submit 上传,然后自己去服务器里看看效果吧~~
浏览器要求支持以下 Feature:
File API
Blob
atob
canvas
代码直接从现有项目移植过来,没有经过“太多的”测试,写的很乱,也没注释,大家就慢慢看吧。。。重点就在 js 脚本的 28 行,
http://jsfiddle.net/windwhinny/d5qan0q7/
第二部:读取文件,并生成
这一步就需要用到
通过
Y坐标
X坐标
高度
宽度
如下图所示:
将图片放置入
MDN 上有详细的说明。
因为我们用
将
这时候裁剪后的文件就储存在
然后你服务器里应该就可以收到这个文件了~
HTML5 的出现让我们可以更方便的实现这一需求。虽然这里所说的技术都貌似有点过时了(前端界的“过时”,你懂的),但还是有些许参考价值。在这里我只说一下要点,具体实现同学们慢慢研究。
下面奉上我自己写的一个demo,在输入框中选好自己服务器 url, 生成好图片后点击 Submit 上传,然后自己去服务器里看看效果吧~~
浏览器要求支持以下 Feature:
File API
Blob
atob
canvas
代码直接从现有项目移植过来,没有经过“太多的”测试,写的很乱,也没注释,大家就慢慢看吧。。。重点就在 js 脚本的 28 行,
clipImage函数中,同学们可以直接跳过去看。
http://jsfiddle.net/windwhinny/d5qan0q7/
第一步:获取文件
HTML5 支持从input[type=file]元素中直接获取文件信息,也可以读取文件内容。我们用下面代码就可以实现:
javascript
$('input[type=file]').change(function(){ var file=this.files[0]; // continue ... });
第二部:读取文件,并生成 Image
元素
这一步就需要用到 FileReader了,这个类是专门用来读取本地文件的。纯文本或者二进制都可以读取,但是本地文件必须是经过用户允许才能读取,也就是说用户要在
input[type=file]中选择了这个文件,你才能读取到它。
通过
FileReader我们可以将图片文件转化成
DataURL,就是以
data:image/png;base64,开头的一种URL,然后可以直接放在
image.src里,这样本地图片就显示出来了。
javascript
$('input[type=file]').change(function(){ var file=this.files[0]; var reader=new FileReader(); reader.onload=function(){ // 通过 reader.result 来访问生成的 DataURL var url=reader.result; setImageURL(url); }; reader.readAsDataURL(file); }); var image=new Image(); function setImageURL(url){ image.src=url; }
Image就是在
html里的
<img>标签,所以可以直接插入到文档流里。
第三步:获取裁剪坐标
这一步没啥好说的,实现的方法也很多,需要获得下面四个裁剪框的坐标:Y坐标
X坐标
高度
宽度
如下图所示:
第四部:裁剪图片
这是时候我们就需要用到canvas了,
canvas和图片一样,所以新建
canvas时就要确定其高宽。这里我们还运用到
image.naturalHeight和
image.naturalWidth这两个属性来获取图片原始尺寸。
将图片放置入
canvas时需要调用
drawImage,这个接口参数比较多,在
MDN 上有详细的说明。
javascript
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)
因为我们用
canvas只是用于裁剪图片的,所以需要新建一个
canvas让它的尺寸和裁剪之后图片的尺寸相等,此时
canvas就相当与我们的裁剪框。运用这个函数还可以将大图缩放成小图,同学们自己研究吧。
javascript
// 以下四个参数由第三步获得 var x, y, width, height; var canvas=$('<canvas width="'+width+'" height="'+height+'"></canvas>')[0], ctx=canvas.getContext('2d'); ctx.drawImage(image,x,y,width,height,0,0,width,height); $(document.body).append(canvas);
将
canvas加入文档流之后,就可以看到裁剪后的效果了。不过我们还需要将图片上传至服务器里。
第五步:读取裁剪后的图片并上传
这时我们要获取canvas中图片的信息,用
toDataURL就可以转换成上面用到的
DataURL。 然后取出其中 base64 信息,再用
window.atob转换成由二进制字符串。但
window.atob转换后的结果仍然是字符串,直接给
Blob还是会出错。所以又要用
Uint8Array转换一下。总之这里挺麻烦的。。
javascript
var data=canvas.toDataURL(); // dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了 data=data.split(',')[1]; data=window.atob(data); var ia = new Uint8Array(data.length); for (var i = 0; i < data.length; i++) { ia[i] = data.charCodeAt(i); }; // canvas.toDataURL 返回的默认格式就是 image/png var blob=new Blob([ia], {type:"image/png"});
这时候裁剪后的文件就储存在
blob里了,我们可以把它当作是普通文件一样,加入到
FormData里,并上传至服务器了。
FormData顾名思义,就是用来创建表单数据的,用
append以键值的形式将数据加入进去即可。但他最大的特点就是可以手工添加文件或者
Blob类型的数据,
Blob数据也会被当作文件来处理。原生 js 可以直接传递给
xhr.send(fd), jquery 可以放入
data里请求。
javascript
var fd=new FormData(); fd.append('file',blob); $.ajax({ url:"your.server.com", type:"POST", data:fd, success:function(){} });
然后你服务器里应该就可以收到这个文件了~
相关文章推荐
- HTML5 本地裁剪图片并上传至服务器(老梗)
- HTML5 本地裁剪图片并上传至服务器
- HTML5 本地裁剪图片并上传至服务器 canvas图片上传 canvas图片裁剪
- HTML5 本地裁剪图片并上传至服务器(转)
- HTML5 本地裁剪图片并上传至服务器
- HTML5本地图片裁剪并上传
- HTML5本地图片裁剪并上传
- HTML5移动端实现选择裁剪图片并且ajax上传服务器
- thinkphp微信开发之jssdk图片上传并下载到本地服务器
- HTML5本地拖拽上传实现图片预览功能的实践总结
- 使用 html5 FileReader 获取图片, 并异步上传到服务器
- swfupload批量上传图片,测试本地成功服务器出现404或500错误解决方法
- thinkphp微信开发之jssdk图片上传并下载到本地服务器
- HTML5 本地裁剪图片
- struts2 上传本地图片到服务器
- Android:调用系统相机 图库 裁剪-图片上传-客服端-服务器
- 将本地图片或者网上图片用post方式上传到图片服务器
- 使用html5 FileReader获取图片,并异步上传到服务器(不使用iframe)
- 用HTML5获取摄像头图像,并且上传图片到服务器(代码完整可用)
- winform中如何将本地图片上传到服务器