通过从图像中心旋转并缩放来拉直HTML5画布中的图像

时间:2014-09-21 00:23:02

标签: html5 canvas html5-canvas

Instagram有一个很好的拉直功能 https://help.instagram.com/135826209959819

如果您拉直图像,它将从图像中心旋转并缩放。

在画布中旋转不是从中心旋转(我认为它是从0,0开始)

缩放缩放到0,0

context.rotate(.01)
context.scale(2.2, 2.2)

你知道一种强制画布从中心旋转,向中心缩放的方法吗?

干杯

1 个答案:

答案 0 :(得分:1)

回答您的问题...您可以使用以下方法设置所需的旋转点:

context.translate(desiredRotationX,desiredRotationY)

这会导致context.rotate围绕您想要的旋转点旋转。

但请注意:未调整图像的正确旋转点可能/可能不是图像的中心。它取决于原始图像的原始旋转点。

也许更好的矫正形象的方法是:

  • 找到图片的左上角和右上角。

  • 确定连接这两个点的直线的角度。

  • 按角度的负值旋转图像。

enter image description here

示例代码和演示:

&# 13;

var canvas1=document.getElementById("canvas1");
var ctx1=canvas1.getContext("2d");

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var $canvas=$("#canvas");
var canvasOffset=$canvas.offset();
var offsetX=canvasOffset.left;
var offsetY=canvasOffset.top;
var scrollX=$canvas.scrollLeft();
var scrollY=$canvas.scrollTop();

var cw,ch,topLeft,topRight,bottomRight,bottomLeft;
var pT,pR,pB,pL;

var img=new Image();
img.crossOrigin='anonymous';
img.onload=start;
//        img.src="https://dl.dropboxusercontent.com/u/139992952/multple/tiltedCW.png";
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/tiltedCCW.png";
function start(){
  cw=canvas.width=img.width;
  ch=canvas.height=img.height;
  ctx.drawImage(img,0,0);

  calcCorners();

  $("#canvas").mousedown(function(e){handleMouseDown(e);});
}


function handleMouseDown(e){
  e.preventDefault();
  e.stopPropagation();         
  mx=parseInt(e.clientX-offsetX);
  my=parseInt(e.clientY-offsetY);

  var dT=calcDistance(mx,my,pT);
  var dR=calcDistance(mx,my,pR);
  var dB=calcDistance(mx,my,pB);
  var dL=calcDistance(mx,my,pL);

  if(dT<dR && dT<dB && dT<dL){
    topLeft=pT;
    topRight=pR;
    bottomRight=pB
  }else if(dR<dT && dR<dB && dR<dL){
    topLeft=pR;
    topRight=pB;
    bottomRight=pL;
  }else if(dB<dT && dB<dR && dB<dL){
    topLeft=pB;
    topRight=pL;
    bottomRight=pT;
  }else{
    topLeft=pL;
    topRight=pT;
    bottomRight=pR;
  }


  // straighten
  var dx=topRight.x-topLeft.x;
  var dy=topRight.y-topLeft.y;
  var angle=Math.atan2(dy,dx);
  var width=Math.sqrt(dx*dx+dy*dy);
  dx=bottomRight.x-topRight.x;
  dy=bottomRight.y-topRight.y;
  var height=Math.sqrt(dx*dx+dy*dy);

  canvas1.width=width;
  canvas1.height=height;
  ctx1.rotate(-angle);
  ctx1.drawImage(img,-topLeft.x,-topLeft.y);

}

function calcDistance(mx,my,p){
  var dx=mx-p.x;
  var dy=my-p.y;
  return(Math.sqrt(dx*dx+dy*dy));
}

function calcCorners(){
  var data=ctx.getImageData(0,0,cw,ch).data;

  // pT (topmost)
  for(var y=0;y<ch;y++){
    for(var x=0;x<cw;x++){
      var n=(y*cw+x)*4+3;
      if(!pT &&data[n]>40){ pT={x:x,y:y}; break; }
    }}
  // pR (rightmost)
  for(var x=cw-1;x>=0;x--){
    for(var y=ch-1;y>=0;y--){
      var n=(y*cw+x)*4+3;
      if(!pR &&data[n]>40){ pR={x:x,y:y}; break; }
    }}
  // pB (bottommost)
  for(var y=ch-1;y>=0;y--){
    for(var x=cw-1;x>=0;x--){
      var n=(y*cw+x)*4+3;
      if(!pB &&data[n]>40){ pB={x:x,y:y}; break; }
    }}
  // pL (leftmost)
  for(var x=0;x<cw;x++){
    for(var y=0;y<ch;y++){
      var n=(y*cw+x)*4+3;
      if(!pL && data[n]>40){ pL={x:x,y:y};  break; }
    }}
}
&#13;
body{ background-color: white; }
canvas{border:1px solid purple;}
#red{color:red;}
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<h4>Original: tilted with transparency</h4>
<h4 id=red>Click near the top-left corner of the image</h4>
<canvas id="canvas" width=300 height=300></canvas><br>
<h4>Straightened</h4>
<canvas id="canvas1" width=300 height=300></canvas>
&#13;
&#13;
&#13;