【问题标题】:How to get a rotated crop of an image with HTML5 canvas如何使用 HTML5 画布旋转裁剪图像
【发布时间】:2014-02-03 06:42:21
【问题描述】:

我有一个包含图像的大画布,如下例所示:

我有红色矩形的位置和旋转角度:

  red : {
       top : top,
       left : left,
       width : width,
       height : height,
       angle : angle
    }

我还有一整套翻译后的坐标,表示红色旋转矩形的实际角点。

最后我得到 blue 矩形 relativered 矩形的位置为:

blue : {
   left : left,
   top: top,
   width : width,
   height : height
}

我需要做的是创建一个新的画布,blue 矩形的大小包含 blue 矩形内包含的图像的正确旋转部分在这样的图像中:

我正在使用 HTML5 画布在 javascript 中执行此操作。我遇到的问题是在旋转矩形时获得正确的图像部分。

任何 hep 将不胜感激

编辑:这是我目前所拥有的:

        var c = getCenterPoint(); // returns center x/y positions of the RED rectangle
        canvas.width = blue.width;
        canvas.height = blue.height;
        var blueX = red.left + blue.left;
        var blueY = red.top + blue.top;
        var tx = blueX - c.x;
        var ty = blueY - c.y;


        this.cursorContext.translate(tx, ty);
        this.cursorContext.rotate(angle * (Math.PI / 180));
        this.cursorContext.translate(-tx, -ty);

        this.cursorContext.drawImage(image, -blueX, -blueY, blue.width, blue.height);

【问题讨论】:

  • 能分享一下你试过的相关代码吗?
  • @Ken 请看我的编辑

标签: javascript canvas html5-canvas


【解决方案1】:

您可以使用临时画布来剪辑和取消旋转蓝色框

  • 从图像中剪下蓝色矩形的边界框

  • 取消旋转边界框,使蓝色矩形不旋转(角度==0)

  • 剪掉多余的边界框区域,只显示蓝色矩形

  • 将蓝色矩形绘制到显示画布上

这是代码和演示:http://jsfiddle.net/m1erickson/28EkG/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    // blue rect's info

    var blueX=421;
    var blueY=343;
    var blueWidth=81;
    var blueHeight=44;
    var blueAngle=-25.00*Math.PI/180;

    // load the image

    var img=new Image();
    img.onload=start;
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/temp6.jpg";

    function start(){

        // create 2 temporary canvases

        var canvas1=document.createElement("canvas");
        var ctx1=canvas1.getContext("2d");
        var canvas2=document.createElement("canvas");
        var ctx2=canvas2.getContext("2d");

        // get the boundingbox of the rotated blue box

        var rectBB=getRotatedRectBB(blueX,blueY,blueWidth,blueHeight,blueAngle);

        // clip the boundingbox of the rotated blue rect
        // to a temporary canvas

        canvas1.width=canvas2.width=rectBB.width;
        canvas1.height=canvas2.height=rectBB.height;

        ctx1.drawImage(img,
            rectBB.cx-rectBB.width/2,
            rectBB.cy-rectBB.height/2,
            rectBB.width,
            rectBB.height,
            0,0,rectBB.width,rectBB.height
        );

        // unrotate the blue rect on the temporary canvas

        ctx2.translate(canvas1.width/2,canvas1.height/2);
        ctx2.rotate(-blueAngle);
        ctx2.drawImage(canvas1,-canvas1.width/2,-canvas1.height/2);

        // draw the blue rect to the display canvas

        var offX=rectBB.width/2-blueWidth/2;
        var offY=rectBB.height/2-blueHeight/2;

        canvas.width=blueWidth;
        canvas.height=blueHeight;
        ctx.drawImage(canvas2,-offX,-offY);

    }  // end start



    // Utility: get bounding box of rotated rectangle

    function getRotatedRectBB(x,y,width,height,rAngle){
        var absCos=Math.abs(Math.cos(rAngle));
        var absSin=Math.abs(Math.sin(rAngle));
        var cx=x+width/2*Math.cos(rAngle)-height/2*Math.sin(rAngle);
        var cy=y+width/2*Math.sin(rAngle)+height/2*Math.cos(rAngle); 
        var w=width*absCos+height*absSin;
        var h=width*absSin+height*absCos;
        return({cx:cx,cy:cy,width:w,height:h});
    }


}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=300 height=300></canvas>
</body>
</html>

【讨论】:

  • 很棒的答案。谢谢!
猜你喜欢
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多