HTML5裁剪图片并上传至服务器实现原理讲解
HTML5裁剪图片并上传至服务器实现原理讲解
第一步:获取文件
HTML5 支持从 input[type=file] 元素中直接获取文件信息,也可以读取文件内容。我们用下面代码就可以实现:
$('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 里,这样本地图片就显示出来了。
$('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 上有详细的说明。
drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight)

因为我们用 canvas 只是用于裁剪图片的,所以需要新建一个 canvas 让它的尺寸和裁剪之后图片的尺寸相等,此时canvas 就相当与我们的裁剪框。运用这个函数还可以将大图缩放成小图,同学们自己研究吧。
// 以下四个参数由第三步获得
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 转换一下。总之这里挺麻烦的。。
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 里请求。
var fd=new FormData();
fd.append('file',blob);
$.ajax({
url:"your.server.com",
type:"POST",
data:fd,
success:function(){}
});
然后你服务器里应该就可以收到这个文件了~
HTML5裁剪图片并上传至服务器实现原理讲解的更多相关文章
- HTML5 本地裁剪图片并上传至服务器(转)
很多情况下用户上传的图片都需要经过裁剪,比如头像啊什么的.但以前实现这类需求都很复杂,往往需要先把图片上传到服务器,然后返回给用户,让用户确定裁剪坐标,发送给服务器,服务器裁剪完再返回给用户,来回需要 ...
- 小程序踩坑记录-上传图片及canvas裁剪图片后上传至服务器
最近在写微信小程序的上传图片功能,趟过了一些坑记录一下. 想要满足的需求是,从手机端上传图片至服务器,为了避免图片过大影响传输效率,需要把图片裁剪至适当大小后再传输 主要思路是,通过wx.choose ...
- 导出HTML5 Canvas图片并上传服务器功能
这篇文章主要介绍了导出HTML5 Canvas图片并上传服务器功能,文中通过实例代码给大家介绍了HTML5 Canvas转化成图片后上传服务器,代码简单易懂非常不错,具有一定的参考借鉴价值,需要的朋友 ...
- HTML5 Canvas前台压缩图片并上传到服务器
1.前台代码: <input id="fileOne" type="file" /> <input id="btnOne" ...
- 深入研究HTML5实现图片压缩上传
上篇文章中提到移动端上传图片,我们知道现在流量还是挺贵的,手机的像素是越来越高,拍个照动不动就是好几M,伤不起.虽然客户端可以轻轻松松实现图片压缩再上传,但是我们的应用还可能在浏览器里面打开,怎么办呢 ...
- js实现图片粘贴上传到服务器并展示
最近看了一些有关于js实现图片粘贴上传的demo,实现如下: (这里只能检测到截图粘贴和图片右键复制之后粘贴) demo1: document.addEventListener('paste', fu ...
- base64字符串转文件,以及ngImgCrop裁剪图片并上传保存到服务器示例
base64字符串是包含文件格式的文件字符串,例如:data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAAgAElE ...
- PHP裁剪图片并上传完整demo
日前根据功能需求,要做一个图片裁剪上传的功能,在网上找了好久,找到了这位仁兄写的demo! 下载压缩包
- 基于HTML5多图片Ajax上传可预览
html5多图控件<input id="fileImage" type="file" size="30" name="fil ...
随机推荐
- 用python代码玩微信
# 安装包 pip install -U wxpy from wxpy import * import time import json bot=Bot() my_friend = bot.frien ...
- Linux中vim编辑器常用命令
移动光标 Ctrl+f:屏幕向下移动一页,相当于[Page Down]按键Ctrl+b:屏幕向上移动一页,相当与[PageUp]按键 0或功能键[Home]:数字‘0’:移动到这一行的最前面的字符处$ ...
- 未能加载文件或程序集“System.ServiceModel, Version=2.0.5.0, ...”解决方法
未能加载文件或程序集“System.ServiceModel, Version=2.0.5.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35”或它 ...
- 大数据学习——hive使用
Hive交互shell bin/hive Hive JDBC服务 hive也可以启动为一个服务器,来对外提供 启动方式,(假如是在itcast01上): 启动为前台:bin/hiveserver2 启 ...
- mysql异常Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95' for column 'region_name'
Incorrect string value: '\xE6\xB5\x8B\xE8\xAF\x95' for column 'region_name' insert语句加的该字段有汉字,乱码造成的 解 ...
- Python+selenium鼠标、键盘事件
鼠标操作 现在的Web产品提供了丰富的鼠标交互方式,例如鼠标右击.双击.悬停.甚至是鼠标拖动等功能,在Webdriver中,将这些关于鼠标操作的方法封装在ActionChains类提供. 1.鼠标右击 ...
- (3)梯度下降法Gradient Descent
梯度下降法 不是一个机器学习算法 是一种基于搜索的最优化方法 作用:最小化一个损失函数 梯度上升法:最大化一个效用函数 举个栗子 直线方程:导数代表斜率 曲线方程:导数代表切线斜率 导数可以代表方向, ...
- bzoj4568 [Scoi2016]幸运数字 线性基+树链剖分
A 国共有 n 座城市,这些城市由 n-1 条道路相连,使得任意两座城市可以互达,且路径唯一.每座城市都有一个 幸运数字,以纪念碑的形式矗立在这座城市的正中心,作为城市的象征.一些旅行者希望游览 A ...
- hdu 4045 Machine scheduling [ dp + 斯特林数]
传送门 Machine scheduling Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- 洛谷—— P1714 切蛋糕
https://www.luogu.org/problem/show?pid=1714 题目描述 今天是小Z的生日,同学们为他带来了一块蛋糕.这块蛋糕是一个长方体,被用不同色彩分成了N个相同的小块,每 ...