Image Crop After Rotate By Canvas
Solution 1:
If you rotate your image, you can recalculate the boundingbox needed to contain it.
This code will takes width/height/rotation angle and returns the new bounding box size:
functionnewSize(w,h,a){
var rads=a*Math.PI/180;
var c = Math.cos(rads);
var s = Math.sin(rads);
if (s < 0) { s = -s; }
if (c < 0) { c = -c; }
size.width = h * s + w * c;
size.height = h * c + w * s ;
}
Here is example code and a Fiddle: http://jsfiddle.net/m1erickson/h65yr/
<!doctype html><html><head><linktype="text/css"media="all"href="css/reset.css" /><!-- reset css --><scripttype="text/javascript"src="http://code.jquery.com/jquery.min.js"></script><style>#containerDiv{
border: 1px solid red;
position:absolute;
top:100px;
left:100px;
}
#canvas{
border: 1px solid green;
}
</style><script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var imgWidth=200;
var imgHeight=300;
var size={width:imgWidth, height:imgHeight};
var rotation=0;
var deg2Rad=Math.PI/180;
var count1=0;
var count2=0;
var img=newImage();
img.onload=function(){
imgWidth=img.width;
imgHeight=img.height;
size={width:imgWidth, height:imgHeight};
draw();
}
img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/Rotate.png";
functiondraw(){
canvas.width=size.width;
canvas.height=size.height;
// calculate the centerpoint of the canvasvar cx=canvas.width/2;
var cy=canvas.height/2;
var info=document.getElementById("info");
info.innerHTML="canvas size: "+(count1++)+": "+cx+" / "+cy;
// draw the rect in the center of the newly sized canvas
ctx.clearRect(0,0,canvas.width,canvas.height);
ctx.fillStyle="rgba(216,216,150,1.0)";
ctx.translate(cx,cy);
ctx.rotate(rotation * deg2Rad);
ctx.drawImage(img,-imgWidth/2,-imgHeight/2);
}
document.getElementById("rotate").addEventListener("click", rotateClicked, false);
functionrotateClicked(e){
rotation+=30;
draw();
}
document.getElementById("resize").addEventListener("click", resizeClicked, false);
functionresizeClicked(e){
rotation+=30;
newSize(imgWidth,imgHeight,rotation);
draw();
}
functionnewSize(w,h,a){
var rads=a*Math.PI/180;
var c = Math.cos(rads);
var s = Math.sin(rads);
if (s < 0) { s = -s; }
if (c < 0) { c = -c; }
size.width = h * s + w * c;
size.height = h * c + w * s ;
}
});
</script></head><body><buttonid="rotate">Rotate without resize</button><buttonid="resize">Resize with resize</button><pid=info></p><divid="containerDiv"><canvasid="canvas"width=400height=400></canvas></div></body></html>
Solution 2:
Issues
There are two issues you are facing:
- There is not enough room in the canvas to do a rotation
- You are drawing the image at center of rotation rather than center of image
Solutions
To properly size your canvas you can use maximum boundary of the rotated rectangle. To find this boundary you can do one of two things:
If you only need to rotate per 90 degrees:
var length = Math.max(img.width, img.height);
If you want to use free angle:
var length = Math.sqrt(img.width * img.width + img.height * img.height);
Then use one of these results to set the size of the canvas:
canvas.width = canvas.height = length; /// both has same length
Next thing is to properly draw in the image. After rotation you need to translate back as the image is always drawn from its upper left corner:
var pivot = length * 0.5;
ctx.save();
ctx.translate(pivot, pivot);
ctx.rotate(degrees * Math.PI / 180);
ctx.drawImage(image, -image.width * 0.5, -image.height * 0.5);
ctx.restore();
It's important you use the pivot of the image to offset it back as the image will here be of a different size than canvas.
The result from this LIVE DEMO here:
Solution 3:
change the parameter of drawImage
ctx.drawImage(image, -image.width / 2, -image.height/ 2);
Post a Comment for "Image Crop After Rotate By Canvas"