为图像创建复杂的剪切路径?

Posted

技术标签:

【中文标题】为图像创建复杂的剪切路径?【英文标题】:Creating complex clipping path for image? 【发布时间】:2017-06-04 18:16:09 【问题描述】:

我是 fabricjs 的新手(以及一般的 javascript 开发)。我正在“移植”一个遗留的 Flex/Actionscript 项目,并且需要使用户能够为图像创建一个复杂的剪切路径。

我在 Actionscript 中的方法是使用 Actionscript Graphics 类,使用 BlendMode.ERASE 从黄色基础矩形“擦除”(即呈现擦除的外观),然后使用该组矩形创建位图用作动态创建的最终图像(第 3 步)的 Alpha 通道。

谁能建议我如何在 Fabric 中完成类似的功能?它似乎不支持html5 Canvas Blend modes,虽然我看到它支持图像的剪切路径,但我没有看到如何使用户能够交互地创建剪切路径,而无需进行大量交叉检查以尝试导出点以动态创建新路径。

谢谢!


第 1 步: 用户绘制了一个基本矩形后,拖动选项/alt-key 使他们能够绘制一个矩形(红线),该矩形将从基本矩形中减去。

第 2 步: 基础矩形显示为减法。

第 3 步:基本矩形用于剪切或遮盖基本图像的一部分


第一步


第 2 步


第 3 步

【问题讨论】:

【参考方案1】:

威尔塔,

没有简单的方法可以做到这一点。步骤如下:

    绘制“黄色”矩形 绘制“红色”矩形 使用 PolyBool 之类的裁剪库进行交集和异或运算 将绘制结果转换为组合矩形的剪切路径 剪辑您的图像

我创建了一些快速的fiddle。您必须单击每个按钮才能进行剪辑。如果您不在画布上添加 2 个矩形,它将不会剪辑。这是一个非常简单的例子。为了正常工作,您必须用鼠标绘制矩形(使它们动态)。此外,这个逻辑没有考虑到这些变化(你也必须处理它们): 对于这些用例 Clipping Library 将返回给您 2 组结果,这意味着应该实现不同的逻辑。

没有 jQuery、FabriJs 和 PolyBool 库的实际代码:

var imgURL = 'http://fabricjs.com/lib/pug.jpg';
var clipYellowRect = null;
var clipRedRect = null;
var pug = null;
var canvas = new fabric.Canvas('c');

// insert image into canvas
var pugImg = new Image();
pugImg.onload = function (img)     
    pug = new fabric.Image(pugImg, 
        angle: 0,
        width: 500,
        height: 500,
        left: 100,
        top: 50,
        scaleX: 0.5,
        scaleY: 0.5,
        clipName: 'pug',
    );
    canvas.add(pug);
;
pugImg.src = imgURL;

//draw yellow rectangle
$('#btnYellowRect').on('click', function()
    clipYellowRect = new fabric.Rect(
      originX: 'left',
      originY: 'top',
      left: 120,
      top: 60,
      width: 200,
      height: 200,
      fill: 'rgba(255,255,0,0.5)',
      strokeWidth: 0,
      selectable: false
  );
canvas.add(clipYellowRect);
);

//draw red rectangle
$('#btnRedRect').on('click', function()
    clipRedRect = new fabric.Rect(
      originX: 'left',
      originY: 'top',
      left: 90,
      top: 120,
      width: 100,
      height: 100,
      strokeWidth: 3,
      fill: 'transparent',
      stroke: 'rgba(255,0,0,1)', /* use transparent for no fill */
      strokeWidth: 0,
      selectable: false
  );

canvas.add(clipRedRect);
);

//clip
$('#btnClip').on('click', function()
    var yellowRectRegion = getRegion(clipYellowRect);
  var redRectRegion = getRegion(clipRedRect);
  //determine inersection
  var intersectResult = PolyBool.intersect(
    regions: [yellowRectRegion],
    inverted: false
  , 
    regions: [redRectRegion],
    inverted: false
  );

  //generate clipping path
  var xorResult = PolyBool.xor(
    regions: [yellowRectRegion],
    inverted: false
  , 
    regions: intersectResult.regions,
    inverted: false
  );
  clipImage(xorResult.regions[0]);
);

//prepare data for clipping library
function getRegion(rect)
return [[rect.left, rect.top],
                [rect.left + rect.width, rect.top],
        [rect.left + rect.width, rect.top + rect.height],
        [rect.left, rect.top + rect.height]]



function clipImage(points)
     //actual clipping 
  pug.clipTo = function (ctx) 
      var scaleXTo1 = (1 / pug.scaleX);
      var scaleYTo1 = (1 / pug.scaleY);
      ctx.save();

      var ctxLeft = -( pug.width / 2 );
      var ctxTop = -( pug.height / 2 );

      ctx.translate( ctxLeft, ctxTop );
      ctx.scale(scaleXTo1, scaleYTo1);
      ctx.beginPath();
      console.log(points)
      ctx.moveTo(points[0][0] - pug.oCoords.tl.x, points[0][1] - pug.oCoords.tl.y);
      for (var i=1; i < points.length; i++)
      ctx.lineTo(points[i][0] - pug.oCoords.tl.x, points[i][1] - pug.oCoords.tl.y);
      
      ctx.closePath();
      ctx.restore();
      ;
      clipYellowRect.remove();
        clipRedRect.remove();
      canvas.renderAll();

希望对你有所帮助。

【讨论】:

太棒了——感谢您的帮助!看起来我将不得不重新考虑一些事情,因为看起来剪切路径在转换剪切的图像时不会缩放或移动。我还是 JS(和 Fabric)的新手,所以我对将其他库与它结合起来有点胆怯。我想我会研究一个 Node 图像库(如 pngjs-image)以动态创建一个带有 alpha 的图像——这是用于 Electron 中的桌面应用程序,因此速度和安全性都可以。

以上是关于为图像创建复杂的剪切路径?的主要内容,如果未能解决你的问题,请参考以下文章

使用 iTextSharp 将图像转换为 PDF 保留剪切路径

html 自定义SVG图像的剪切路径

SVG 剪切路径缩放

如何告诉 Ghostscript 在从 eps 到 tiff 的转换中不要使用剪切路径?

在哪里可以找到当前的 Adob​​e 图像格式规范? “剪切路径”

带有剪切路径的 imagemagick 锯齿边缘