带有柔化边缘的html5画布图像裁剪

时间:2014-09-19 15:03:11

标签: html5 canvas

我已经关注了这个(https://github.com/netplayer/crop)存储库并创建了一些图像裁剪工具并进行了一些更改。当我使用图案和线条裁剪图像时,图像会被锯齿状边缘裁剪。如何删除锯齿状边缘并在图像周围应用一些阴影,如Photoshop中的羽毛特征。这是fiddle

以下是我的代码的相关部分

var canvas = document.getElementById('myCanvas');
    var ctx = canvas.getContext('2d');
    var points=[];
    ctx.save();
    ctx.beginPath();
    var offset = $('#myCanvas').offset();
    for (var i = 0; i < points.length; i += 2) {
        var x = parseInt(jQuery.trim(points[i]));
        var y = parseInt(jQuery.trim(points[i + 1]));
        if (i == 0) {
            ctx.moveTo(x - offset.left, y - offset.top);
        } else {
            ctx.lineTo(x - offset.left, y - offset.top);
        }



    }
    ctx.restore();
    var pattern = ctx.createPattern(imageObj, "repeat");
    ctx.fillStyle = pattern;
    ctx.fill();

1 个答案:

答案 0 :(得分:2)

以下是使用合成和阴影的一种方法:

  • 从路径创建遮罩图像。蒙版是用户填充的路径,边缘使用阴影进行羽化。下面的图像是一个形状像星星的面具 - 注意用阴影创建的羽毛边缘。

enter image description here

  • 在画布上绘制遮罩。

  • 将合成设置为'source-in',这会导致仅在现有像素不透明的情况下绘制任何新图形。

  • 在画布上绘制汽车图像。由于合成,图像将仅在用户的路径内绘制,并且也会像面具一样进行羽化。

enter image description here

示例代码和演示:

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

var fadeLength=20;

var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/car.jpg";
function start(){

  var mask=document.createElement('canvas');
  var mctx=mask.getContext('2d');

  canvas.width=mask.width=img.width;
  canvas.height=mask.height=img.height;

  mctx.translate(-500,0);

  mctx.shadowColor='black';
  mctx.shadowOffsetX=500;
  mctx.shadowOffsetY=0;
  mctx.shadowBlur=fadeLength;

  drawStar(mctx,150,120,5,90,30);
  drawStar(mctx,150,120,5,90,30);

  mctx.translate(500,0);

  ctx.drawImage(mask,0,0);

  ctx.globalCompositeOperation='source-in'
  ctx.drawImage(img,0,0);

}


function drawStar(ctx,cx,cy,spikes,outerRadius,innerRadius){
  var rot=Math.PI/2*3;
  var x=cx;
  var y=cy;
  var step=Math.PI/spikes;

  ctx.strokeSyle="#000";
  ctx.beginPath();
  ctx.moveTo(cx,cy-outerRadius)
  for(i=0;i<spikes;i++){
    x=cx+Math.cos(rot)*outerRadius;
    y=cy+Math.sin(rot)*outerRadius;
    ctx.lineTo(x,y)
    rot+=step

    x=cx+Math.cos(rot)*innerRadius;
    y=cy+Math.sin(rot)*innerRadius;
    ctx.lineTo(x,y)
    rot+=step
  }
  ctx.lineTo(cx,cy-outerRadius)
  ctx.closePath();
  ctx.fillStyle='black';
  ctx.fill();
}
body{ background-color:white; padding:10px;}
canvas{border:1px solid red; background-color:black;}
<canvas id="canvas" width=300 height=300></canvas>