如何通过在 fabric js 中传递颜色代码来创建自定义过滤器

gam*_*ler 1 javascript jquery image-editing fabricjs

我正在尝试创建一个自定义过滤器,它应该像接受颜色代码一样。

这是我的代码。

它工作正常。

fabric.Image.fromURL('pug.jpg', function(img) {
  img.filters.push(
    new fabric.Image.filters.Sepia(),
    new fabric.Image.filters.Brightness({ brightness: 100 }));

  img.applyFilters(canvas.renderAll.bind(canvas));
  canvas.add(img);
}); 
Run Code Online (Sandbox Code Playgroud)

现在,我需要创建一个具有特定颜色代码的过滤器。我发现的是

fabric.Image.filters.Redify = fabric.util.createClass({

  type: 'Redify',

  applyTo: function(canvasEl) {
    var context = canvasEl.getContext('2d'),
        imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
        data = imageData.data;

    for (var i = 0, len = data.length; i < len; i += 4) {
      data[i + 1] = 0;
      data[i + 2] = 0;
    }

    context.putImageData(imageData, 0, 0);
  }
});

fabric.Image.filters.Redify.fromObject = function(object) {
  return new fabric.Image.filters.Redify(object);
};
Run Code Online (Sandbox Code Playgroud)

我需要解释 for 循环的作用...还请解释我如何传递颜色代码。

And*_*zzi 5

您找到的 redify 过滤器并不是真正的 colorify 过滤器。正如您从代码中看到的那样,它杀死了绿色和蓝色通道,而只剩下图像的红色。这与您应用红色着色的效果不同。

您可以以相同的方式创建一个蓝色和绿色过滤器,只需更改幸存的通道即可:

fabric.Image.filters.Greenify= fabric.util.createClass({

  type: 'greenify',

  applyTo: function(canvasEl) {
    var context = canvasEl.getContext('2d'),
        imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
        data = imageData.data;

    for (var i = 0, len = data.length; i < len; i += 4) {
      //kill red
      data[i] = 0;
      //kill blue
      data[i + 2] = 0;
    }

    context.putImageData(imageData, 0, 0);
  }
});
Run Code Online (Sandbox Code Playgroud)

要创建着色过滤器,首先您必须知道如何操作。我亲自检查了 GIMP 的 colorify 过滤器是如何工作的:

https://docs.gimp.org/en/plug-in-colorify.html

1)使图像灰度化,基于亮度

2)乘以您想要的颜色的灰度

这或多或少等于按灰度和乘法应用现有的fabricjs 过滤器。

fabric.Image.filters.Greenify= fabric.util.createClass({

  type: 'greenify',

  applyTo: function(canvasEl) {
    var context = canvasEl.getContext('2d'),
        imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
        data = imageData.data;

    for (var i = 0, len = data.length; i < len; i += 4) {
      //kill red
      data[i] = 0;
      //kill blue
      data[i + 2] = 0;
    }

    context.putImageData(imageData, 0, 0);
  }
});
Run Code Online (Sandbox Code Playgroud)
var canvas = new fabric.Canvas("c");

 fabric.Image.filters.Luminosity = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Luminosity.prototype */ {

    /**
     * Filter type
     * @param {String} type
     * @default
     */
    type: 'Luminosity',

    /**
     * Applies filter to canvas element
     * @memberOf fabric.Image.filters.Grayscale.prototype
     * @param {Object} canvasEl Canvas element to apply filter to
     */
    applyTo: function(canvasEl) {
      var context = canvasEl.getContext('2d'),
          imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
          data = imageData.data,
          len = imageData.width * imageData.height * 4,
          index = 0,
          average;

      while (index < len) {
        //Luminosity = 0.21 × R + 0.72 × G + 0.07 × B
        average = (0.21 * data[index] + 0.72 * data[index + 1] + 0.07 * data[index + 2]);
        data[index]     = average;
        data[index + 1] = average;
        data[index + 2] = average;
        index += 4;
      }

      context.putImageData(imageData, 0, 0);
    }
  });

  /**
   * Returns filter instance from an object representation
   * @static
   * @return {fabric.Image.filters.Grayscale} Instance of fabric.Image.filters.Grayscale
   */
  fabric.Image.filters.Grayscale.fromObject = function() {
    return new fabric.Image.filters.Grayscale();
  };


fabric.Image.fromURL("http://fabricjs.com/assets/pug.jpg", function(img) {
  img.filters.push(new fabric.Image.filters.Grayscale());
  img.filters.push(new fabric.Image.filters.Multiply({color: '#F0F'}));
  img.scale(0.3);
  img.applyFilters(function() {
    canvas.add(img);
  });
}, {crossOrigin: 'Anonymous'});




fabric.Image.fromURL("http://fabricjs.com/assets/pug.jpg", function(img) {
  img.filters.push(new fabric.Image.filters.Luminosity());
  img.filters.push(new fabric.Image.filters.Multiply({color: '#F0F'}));
  img.applyFilters(function() {
    img.scale(0.3);
    img.left = img.getWidth();
    canvas.add(img);
  });
}, {crossOrigin: 'Anonymous'});
Run Code Online (Sandbox Code Playgroud)
为了将fabricjs 的内置函数与gimp 的示例进行比较,我创建了一个亮度过滤器来代替基于“平均”方法的灰度过滤器。如您所见,结果非常相似,但它取决于图像。

如果您想构建自己的过滤器,请检查乘法过滤器源代码以了解如何处理过滤器中的参数。