很多时候我们都会遇到图片裁剪的相关需求,比如用户上传头像,然后进行裁剪。
在最近的项目中,就有一个用户更改头像的需求。按一贯的做法,就是用户选择图片进行上传,上传成功后返回预览,用户在页面上进行拖拽“裁剪”,然后将相关参数传给后台,后台进行真正的裁剪,裁剪成功后返回裁剪后的图片url。这一过程相对来说较为繁琐,而且,会使得很多没用的图片上传到服务器上,加重服务器的负担。
html5的canvas可以实现在前端进行图片裁剪,最后只上传裁剪后的图片。虽然技术较为简单,但也记录一下。
先上demo源码:
<html>
<head>
<title>DEMO</title>
</head>
<body>
<input type="file" name="file" id="post_file">
<div id="label">
<canvas id="get_image" width="400" height="400"></canvas>
<canvas id="edit_pic" width="100" height="100"></canvas>
</div>
<p id="show_edit"><img /></p>
<script type="text/javascript">
var postFile = {
init: function() {
var t = this;
t.getImage = document.getElementById('get_image');
t.editPic = document.getElementById('edit_pic');
document.getElementById('post_file').addEventListener("change", t.handleFiles, false);
},
handleFiles: function() {
var fileList = this.files[0];
var oFReader = new FileReader();
oFReader.readAsDataURL(fileList);
oFReader.onload = function () {
postFile.paintImage(oFReader.result);
};
},
paintImage: function(url) {
var t = this;
var createCanvas = t.getImage.getContext("2d");
var img = new Image();
img.src = url;
img.onload = function(){
createCanvas.drawImage(img,0,0);
t.imgUrl = t.getImage.toDataURL();
t.cutImage();
};
},
cutImage: function() {
var t = this;
var ctx = t.editPic.getContext('2d');
var images = new Image();
images.src = t.imgUrl;
images.onload = function(){
ctx.drawImage(images,0, 0, 200, 200, 0, 0, 100, 100); //裁剪图片
document.getElementById('show_edit').getElementsByTagName('img')[0].src = t.editPic.toDataURL();
}
}
}
postFile.init();
</script>
</body>
</html>
分析一下
两个较为关键个方法:
1.
drawImage() 方法
浏览器支持
Internet Explorer 9、Firefox、Opera、Chrome 以及 Safari 支持 drawImage() 方法。
注释:Internet Explorer 8 或更早的浏览器不支持 <canvas> 元素。
定义和用法
drawImage() 方法在画布上绘制图像、画布或视频。
drawImage() 方法也能够绘制图像的某些部分,以及/或者增加或减少图像的尺寸。
JavaScript 语法 1
在画布上定位图像:
context.drawImage(img,x,y);
JavaScript 语法 2
在画布上定位图像,并规定图像的宽度和高度:
context.drawImage(img,x,y,width,height);
JavaScript 语法 3
剪切图像,并在画布上定位被剪切的部分:
context.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
参数值
参数 | 描述 |
---|---|
img | 规定要使用的图像、画布或视频。 |
sx | 可选。开始剪切的 x 坐标位置。 |
sy | 可选。开始剪切的 y 坐标位置。 |
swidth | 可选。被剪切图像的宽度。 |
sheight | 可选。被剪切图像的高度。 |
x | 在画布上放置图像的 x 坐标位置。 |
y | 在画布上放置图像的 y 坐标位置。 |
width | 可选。要使用的图像的宽度。(伸展或缩小图像) |
height | 可选。要使用的图像的高度。(伸展或缩小图像) |
2.toDataURL()
这个方法能把画布里的图案转变成base64编码格式的png,然后返回 Data URL数据。
var strDataURI = oCanvas.toDataURL(); // returns "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACt..."
而且,如果你给toDataURL()传入mine类型的参数,你还可以将画布转变成其它格式的图片。
剪切图像,并在画布上定位被剪切的部分:
var strDataURI = oCanvas.toDataURL("image/jpeg"); // returns "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAA..."
通过这两个关键的方法,我们就可以实现在canvas上进行图片的裁剪,并将裁剪后的canvas图案保存成base64编码的数据,将这些数据传给后端即可。