基于Canvas实现对图片的旋转和裁切

大家都知道,HTML5的canvas就是一张画布,提供给了较强的绘图能力,也可以载入图片,那么本文就主要实现一个基于Canvas对图片进行旋转和裁切的功能。

基于Canvas实现对图片的旋转和裁切

Canvas提供的drawImage方法参数列表:

参数 描述
img 规定要使用的图像、画布或视频。
sx 可选。开始剪切的 x 坐标位置。
sy 可选。开始剪切的 y 坐标位置。
swidth 可选。被剪切图像的宽度。
sheight 可选。被剪切图像的高度。
x 在画布上放置图像的 x 坐标位置。
y 在画布上放置图像的 y 坐标位置。
width 可选。要使用的图像的宽度。(伸展或缩小图像)
height 可选。要使用的图像的高度。(伸展或缩小图像)

图片旋转

CSS3的Transform也可以很方便的为元素做旋转,但这里我们采用Canvas的方法。Canvas提供了rotate方法让我们来做旋转。

您的浏览器不支持Canvas

<canvas width="300" height="300" id="my-canvas-1" style="border:1px solid #ddd;"> 您的浏览器不支持Canvas </canvas> <p> <input type="button" value="逆时针旋转" onclick="rotateLeft()" /> <input type="button" value="顺时针旋转" onclick="rotateRight()" /> </p> <script type="text/javascript"> (function() { window.rotateRight = function() { ctx.clearRect(0, 0, canvas.width, canvas.height); degreeOffset += 0.5; degree = degreeOffset * 90 * Math.PI / 180; ctx.translate(cx, cy); ctx.rotate(degree); ctx.translate(-cx, -cy); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); } window.rotateLeft = function() { ctx.clearRect(0, 0, canvas.width, canvas.height); degreeOffset -= 0.5; degree = degreeOffset * 90 * Math.PI / 180; ctx.translate(cx, cy); ctx.rotate(degree); ctx.translate(-cx, -cy); ctx.drawImage(img, 0, 0, canvas.width, canvas.height); } var canvas = document.getElementById("my-canvas-1"); var ctx = canvas.getContext('2d'); var img = new Image(); img.width = canvas.width; img.height = canvas.height; img.src = "http://www.jshacker.com/pull/4/834918483.jpg"; var degreeOffset = 0; var degree = 0; var cx = canvas.width / 2; var cy = canvas.height / 2; img.onload = function() { ctx.drawImage(img, 0, 0, canvas.width, canvas.height); }; })(); </script>

图片裁切

之前我们做用户上传头像裁切功能,都是用js让用户选好坐标和区域传输到后端,让Java或者C#等后端语言来完成裁切,那么有了Canvas之后,妈妈说裁切再也不叫事儿了。我们可以使用

您的浏览器不支持Canvas

<canvas width="300" height="300" id="my-canvas-2" style="border:1px solid #ddd;"> 您的浏览器不支持Canvas </canvas> <p> <input type="button" value="裁切看效果" onclick="cropDone()" /> </p> <p style="width:300px;height:300px;border:1px solid #ddd;" id="crop-result"></p> <script src='http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js'></script> <script type="text/javascript"> (function() { function CropSelection(x, y, w, h) { this.x = x; this.y = y; this.w = w; this.h = h; this.px = x; this.py = y; this.csize = 6; this.csizeh = 10; this.bHow = [false, false, false, false]; this.iCSize = [this.csize, this.csize, this.csize, this.csize]; this.bDrag = [false, false, false, false]; this.bDragAll = false; } CropSelection.prototype.draw = function() { ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.strokeRect(this.x, this.y, this.w, this.h); if (this.w > 0 && this.h > 0) { ctx.drawImage(img, this.x, this.y, this.w, this.h, this.x, this.y, this.w, this.h); } ctx.fillStyle = '#fff'; ctx.fillRect(this.x - this.iCSize[0], this.y - this.iCSize[0], this.iCSize[0] * 2, this.iCSize[0] * 2); ctx.fillRect(this.x + this.w - this.iCSize[1], this.y - this.iCSize[1], this.iCSize[1] * 2, this.iCSize[1] * 2); ctx.fillRect(this.x + this.w - this.iCSize[2], this.y + this.h - this.iCSize[2], this.iCSize[2] * 2, this.iCSize[2] * 2); ctx.fillRect(this.x - this.iCSize[3], this.y + this.h - this.iCSize[3], this.iCSize[3] * 2, this.iCSize[3] * 2); }; function drawScene() { ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height); ctx.drawImage(img, 0, 0); ctx.fillStyle = 'rgba(0, 0, 0, 0.5)'; ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); theSelection.draw(); } window.cropDone = function() { var tempCanvas = document.createElement('canvas'); var tempCtx = tempCanvas.getContext('2d'); tempCanvas.width = theSelection.w; tempCanvas.height = theSelection.h; tempCtx.drawImage(img, theSelection.x, theSelection.y, theSelection.w, theSelection.h, 0, 0, theSelection.w, theSelection.h); var cropData = tempCanvas.toDataURL(); var tempImg = $("<img />"); tempImg.attr("src", cropData); $('#crop-result').html(tempImg); }; // init the canvas and img var theSelection = new CropSelection(60, 60, 60, 60); var canvas = document.getElementById("my-canvas-2"); var ctx = canvas.getContext('2d'); var img = new Image(); img.src = "http://www.jshacker.com/pull/4/834918483.jpg"; img.onload = function() { drawScene(); }; $(canvas).mousemove(function(e) { var canvasOffset = $(canvas).offset(); iMouseX = Math.floor(e.pageX - canvasOffset.left); iMouseY = Math.floor(e.pageY - canvasOffset.top); // in case of drag of whole selector if (theSelection.bDragAll) { theSelection.x = iMouseX - theSelection.px; theSelection.y = iMouseY - theSelection.py; } for (i = 0; i < 4; i++) { theSelection.bHow[i] = false; theSelection.iCSize[i] = theSelection.csize; } // hovering over resize cubes if (iMouseX > theSelection.x - theSelection.csizeh && iMouseX < theSelection.x + theSelection.csizeh && iMouseY > theSelection.y - theSelection.csizeh && iMouseY < theSelection.y + theSelection.csizeh) { theSelection.bHow[0] = true; theSelection.iCSize[0] = theSelection.csizeh; } if (iMouseX > theSelection.x + theSelection.w-theSelection.csizeh && iMouseX < theSelection.x + theSelection.w + theSelection.csizeh && iMouseY > theSelection.y - theSelection.csizeh && iMouseY < theSelection.y + theSelection.csizeh) { theSelection.bHow[1] = true; theSelection.iCSize[1] = theSelection.csizeh; } if (iMouseX > theSelection.x + theSelection.w-theSelection.csizeh && iMouseX < theSelection.x + theSelection.w + theSelection.csizeh && iMouseY > theSelection.y + theSelection.h-theSelection.csizeh && iMouseY < theSelection.y + theSelection.h + theSelection.csizeh) { theSelection.bHow[2] = true; theSelection.iCSize[2] = theSelection.csizeh; } if (iMouseX > theSelection.x - theSelection.csizeh && iMouseX < theSelection.x + theSelection.csizeh && iMouseY > theSelection.y + theSelection.h-theSelection.csizeh && iMouseY < theSelection.y + theSelection.h + theSelection.csizeh) { theSelection.bHow[3] = true; theSelection.iCSize[3] = theSelection.csizeh; } // in case of dragging of resize cubes var iFW, iFH; if (theSelection.bDrag[0]) { var iFX = iMouseX - theSelection.px; var iFY = iMouseY - theSelection.py; iFW = theSelection.w + theSelection.x - iFX; iFH = theSelection.h + theSelection.y - iFY; } if (theSelection.bDrag[1]) { var iFX = theSelection.x; var iFY = iMouseY - theSelection.py; iFW = iMouseX - theSelection.px - iFX; iFH = theSelection.h + theSelection.y - iFY; } if (theSelection.bDrag[2]) { var iFX = theSelection.x; var iFY = theSelection.y; iFW = iMouseX - theSelection.px - iFX; iFH = iMouseY - theSelection.py - iFY; } if (theSelection.bDrag[3]) { var iFX = iMouseX - theSelection.px; var iFY = theSelection.y; iFW = theSelection.w + theSelection.x - iFX; iFH = iMouseY - theSelection.py - iFY; } if (iFW > theSelection.csizeh * 2 && iFH > theSelection.csizeh * 2) { theSelection.w = iFW; theSelection.h = iFH; theSelection.x = iFX; theSelection.y = iFY; } drawScene(); }); $(canvas).mousedown(function(e) { var canvasOffset = $(canvas).offset(); iMouseX = Math.floor(e.pageX - canvasOffset.left); iMouseY = Math.floor(e.pageY - canvasOffset.top); theSelection.px = iMouseX - theSelection.x; theSelection.py = iMouseY - theSelection.y; if (theSelection.bHow[0]) { theSelection.px = iMouseX - theSelection.x; theSelection.py = iMouseY - theSelection.y; } if (theSelection.bHow[1]) { theSelection.px = iMouseX - theSelection.x - theSelection.w; theSelection.py = iMouseY - theSelection.y; } if (theSelection.bHow[2]) { theSelection.px = iMouseX - theSelection.x - theSelection.w; theSelection.py = iMouseY - theSelection.y - theSelection.h; } if (theSelection.bHow[3]) { theSelection.px = iMouseX - theSelection.x; theSelection.py = iMouseY - theSelection.y - theSelection.h; } if (iMouseX > theSelection.x + theSelection.csizeh && iMouseX < theSelection.x+theSelection.w - theSelection.csizeh && iMouseY > theSelection.y + theSelection.csizeh && iMouseY < theSelection.y+theSelection.h - theSelection.csizeh) { theSelection.bDragAll = true; } for (i = 0; i < 4; i++) { if (theSelection.bHow[i]) { theSelection.bDrag[i] = true; } } }); $(canvas).mouseup(function(e) { theSelection.bDragAll = false; for (i = 0; i < 4; i++) { theSelection.bDrag[i] = false; } theSelection.px = 0; theSelection.py = 0; }); })(); </script>
如上的一大坨代码其实大多都在做鼠标缩放选区,真正实现裁切的代码是非常少的,只有window.cropDone函数。

相关阅读