繁体   English   中英

Fabric.js - 色调过滤器

[英]Fabric.js - Tint filter

我似乎无法使fabric.js的色调过滤器功能工作,或找到它正在使用的任何示例。 我试过了:

img.filters[0] = new f.Tint({
    color:'green'
});

我也试过#00ff00而不是green ,但两者都只是把图像变成黑色。

我有一些只是黑色和透明的png(例如基本形状),我希望能够改变它们的颜色,我不知道这是否可能,但我认为它听起来很有希望,我只是无法让它工作。

我也尝试过照片,只是变黑了,我在代码中的同一个地方使用了其他过滤器(如反转)并且工作正常。

任何帮助,将不胜感激。

更新:使用完整的JS,图片3只显示为黑盒子。

var canvas = new fabric.Canvas('c');
var f = fabric.Image.filters;

fabric.Image.fromURL('img/picture3.jpg', function(img) {
  img.set({
    left: 100,
    top: 120,
    angle: 0
  });
  img.filters[0] = new f.Tint({
      color:'00FF00'
  });
  img.applyFilters(canvas.renderAll.bind(canvas));
  canvas.add(img);
});

我写了那个过滤器,我在我们的一个项目中大量使用它,到目前为止它运行良好。 但我缺少的是对applyFilters的调用 - 也许你可以发布一些代码?

另外我觉得我总是应用以下颜色:

img.filters[0] = new f.Tint({
    color:'FF0000'
});

意味着没有颜色名称,前面没有哈希。 我知道颜色的解析器在那里应该更加健壮。 另外请确保此过滤器仅适用于具有Alpha通道的图像 - 表示半透明png文件。

我分析了Tint过滤器的原始类,我发现了这一行

var rgb = parseInt(this.color, 10).toString(16);

应该像这样调整

var rgb = this.color;

使其按预期工作。 当然,然后rgb变量是无用的,你可以直接将它改为this.color ,但我个人更喜欢单行更改。

我不确定将十六进制转换为整数然后转换为字符串的最初目的是什么,因为它对我没有意义。

您可能不希望修改fabric.js源代码,因此我建议您创建自定义过滤器类,如本教程中“过滤器”部分所述: http//fabricjs.com/fabric-intro-part-2/

我对JPEG图像或PNG图像(透明背景)也有同样的问题。

我发现Tint Class在这个问题上没有正常工作,所以我稍微改了一下。 您可以在Google网上论坛中找到该主题: https//groups.google.com/forum/#! msg / fabricjs / DPN0WuRtc- o / ZGgIQK5F9xAJ

这是我的解决方法类(通过使用完整的十六进制值来工作,但您可以轻松地根据您的需要调整它):

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

  type: 'Tint',

  /**
   * Constructor
   * @memberOf fabric.Image.filters.Tint.prototype
   * @param {Object} [options] Options object
   */
  //That's Different : HexColor
  initialize: function(HexColor) {
    this.color = HexColor;
  },


  /**
   * Applies filter to canvas element
   * @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;

    //That's different : computation of values
    var rUser = ((this.color).toString ()).substr(0,2);
    var gUser = ((this.color).toString ()).substr(2,2);
    var bUser = ((this.color).toString ()).substr(4,2);


    for (var i = 0, len = data.length; i < len; i += 4) {


        r = data[i];
        g = data[i + 1];
        b = data[i + 2];

        data[i] = parseInt ((r * parseInt (rUser, 16))/255);
        data[i + 1] = parseInt ((g * parseInt (gUser, 16))/255);
        data[i + 2] = parseInt ((b * parseInt (bUser, 16))/255);


    }

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

/**
 * Returns json representation of filter
 * @return {Object} json representation of filter
 */
toJSON: function() {
  return {
    type: this.type,
    color: this.color
  };
}

})`

我这样使用它:

//$oCanvas is my fabric Canvas object
//data.color could be 'ff0000' but not 'f00' not anything else like fabric.Color
$img.filters[0] = new fabric.Image.filters.Tint(data.color); 
$img.applyFilters($oCanvas.renderAll.bind($oCanvas));

希望能帮助别人。

L.

编辑

在Tint过滤器类中进行了一些更改(Github: https//github.com/kangax/fabric.js/pull/862 )。

我再次测试它仍然没有运气所以我稍微改变了一下。 您可以在Google网上论坛找到源代码+说明( https://groups.google.com/forum/#!topic/fabricjs/DPN0WuRtc-o

编辑#2

好吧Kienz制作了一个JSFiddle( http://jsfiddle.net/Kienz/4wGzk/ ),它使用带有错误修正的Tint过滤器类,并让它运行起来。 我建议按照他的方式实施它。

我遇到了同样的问题。 它原来是我正在使用的结构js的版本。 在没有抓住最新版本的情况下,由于害怕破坏其他东西,我只抓住了我需要的东西并将其用作覆盖当前色调实现的自定义过滤器。

这是我用过的东西:

/**
   * Tint filter class
   * Adapted from <a href="https://github.com/mezzoblue/PaintbrushJS">https://github.com/mezzoblue/PaintbrushJS</a>
   * @class fabric.Image.filters.Tint
   * @memberOf fabric.Image.filters
   * @extends fabric.Image.filters.BaseFilter
   * @see {@link fabric.Image.filters.Tint#initialize} for constructor definition
   * @see {@link http://fabricjs.com/image-filters/|ImageFilters demo}
   * @example <caption>Tint filter with hex color and opacity</caption>
   * var filter = new fabric.Image.filters.Tint({
   *   color: '#3513B0',
   *   opacity: 0.5
   * });
   * object.filters.push(filter);
   * object.applyFilters(canvas.renderAll.bind(canvas));
   * @example <caption>Tint filter with rgba color</caption>
   * var filter = new fabric.Image.filters.Tint({
   *   color: 'rgba(53, 21, 176, 0.5)'
   * });
   * object.filters.push(filter);
   * object.applyFilters(canvas.renderAll.bind(canvas));
   */
  fabric.Image.filters.Tint = fabric.util.createClass(fabric.Image.filters.BaseFilter, /** @lends fabric.Image.filters.Tint.prototype */ {

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

    /**
     * Constructor
     * @memberOf fabric.Image.filters.Tint.prototype
     * @param {Object} [options] Options object
     * @param {String} [options.color=#000000] Color to tint the image with
     * @param {Number} [options.opacity] Opacity value that controls the tint effect's transparency (0..1)
     */
    initialize: function(options) {
      options = options || { };

      this.color = options.color || '#000000';
      this.opacity = typeof options.opacity !== 'undefined'
                      ? options.opacity
                      : new fabric.Color(this.color).getAlpha();

      console.log(this.color + " " + this.opacity);                
    },

    /**
     * Applies filter to canvas element
     * @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,
          iLen = data.length, i,
          tintR, tintG, tintB,
          r, g, b, alpha1,
          source;

      source = new fabric.Color(this.color).getSource();

      tintR = source[0] * this.opacity;
      tintG = source[1] * this.opacity;
      tintB = source[2] * this.opacity;

      alpha1 = 1 - this.opacity;

      for (i = 0; i < iLen; i+=4) {
        r = data[i];
        g = data[i + 1];
        b = data[i + 2];

        // alpha compositing
        data[i] = tintR + r * alpha1;
        data[i + 1] = tintG + g * alpha1;
        data[i + 2] = tintB + b * alpha1;
      }

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

    /**
     * Returns object representation of an instance
     * @return {Object} Object representation of an instance
     */
    toObject: function() {
      return extend(this.callSuper('toObject'), {
        color: this.color,
        opacity: this.opacity
      });
    }
  });

在做类似事情时我注意到的一件事是,在将图像本身添加到画布之前,过滤器将无法工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM