首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何通过在fabric js中传递颜色代码来创建自定义筛选器

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

Stack Overflow用户
提问于 2016-03-18 11:06:19
回答 2查看 3.5K关注 0票数 1

我试图创建一个自定义过滤器,它应该喜欢接受颜色代码。

这是我的密码。

它很好用。

代码语言:javascript
复制
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);
}); 

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

代码语言:javascript
复制
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);
};

我需要解释什么循环does...also,请解释我如何通过颜色代码。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-03-21 06:38:04

您发现的redify过滤器并不是真正的彩色过滤器。正如你可以从代码中看到的那样,它正在扼杀绿色和蓝色的channell,而只留下了图像的红色。这是不一样的效果,你会得到的应用颜色与红色。

您可以通过更改尚存的channell的方式创建一个蓝色和绿色的过滤器:

代码语言:javascript
复制
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);
  }
});

要创建一个彩色过滤器,首先你必须知道如何做它。我亲自检查了GIMP的彩色过滤器是如何工作的:

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

1)基于亮度的图像灰度化。

2)将灰度乘以你想要的颜色。

这将或多或少地等于应用现有的制造滤波器的灰度和乘法。

代码语言:javascript
复制
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'});
代码语言:javascript
复制
<script src="http://www.deltalink.it/andreab/fabric/fabric.js"></script>
<canvas width="500" height="400" id="c"  ></canvas>

为了比较内置的函数is和gimp的例子,我创建了一个光度滤波器来代替基于“平均”方法的灰度滤波器。正如您所看到的,结果是非常相似的,但它是图像依赖的。

如果要构建自己的筛选器,请检查乘法筛选器源代码,以查看如何处理筛选器中的参数。

票数 5
EN

Stack Overflow用户

发布于 2018-01-10 22:56:54

为了能够使用您的过滤器,您需要根据Fabricjs滤波器样板将筛选器代码更改为下面

代码语言:javascript
复制
(function(global) {

'use strict';

var fabric  = global.fabric || (global.fabric = { }),
    filters = fabric.Image.filters,
    createClass = fabric.util.createClass;

/**
 * Redify filter class
 * @class fabric.Image.filters.Redify
 * @memberOf fabric.Image.filters
 * @extends fabric.Image.filters.BaseFilter
 * @see {@link fabric.Image.filters.Redify#initialize} for constructor definition
 * @see {@link http://fabricjs.com/image-filters|ImageFilters demo}
 * @example
 * var filter = new fabric.Image.filters.Redify({
*   add here an example of how to use your filter
* });
 * object.filters.push(filter);
 * object.applyFilters();
 */
filters.Redify = createClass(filters.BaseFilter, /** @lends fabric.Image.filters.Redify.prototype */ {

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

    /**
     * Fragment source for the threshold program
     */
    fragmentSource: 'precision highp float;\n' +
    'uniform sampler2D uTexture;\n' +
    'uniform float uthreshold;\n' +
    'varying vec2 vTexCoord;\n' +
    'void main() {\n' +
    'vec4 color = texture2D(uTexture, vTexCoord);\n' +
    // add your gl code here
    'gl_FragColor = color;\n' +
    '}',

    /**
     * Redify value, from -1 to 1.
     * translated to -255 to 255 for 2d
     * 0.0039215686 is the part of 1 that get translated to 1 in 2d
     * @param {Number} threshold
     * @default
     */
    threshold: 5,

    /**
     * Describe the property that is the filter parameter
     * @param {String} m
     * @default
     */
    mainParameter: 'threshold',

    /**
     * Apply the Redify operation to a Uint8ClampedArray representing the pixels of an image.
     *
     * @param {Object} options
     * @param {ImageData} options.imageData The Uint8ClampedArray to be filtered.
     */
    applyTo2d: function(options) {
        var imageData = options.imageData,
            data = imageData.data, i, len = data.length,sublim = 255-this.threshold;
        for (i = 0; i < len; i += 4) {
            if (data[i] < sublim && data[i + 1] < sublim && data[i + 2] < sublim) {
                data[i + 1] = 0;
                data[i + 2] = 0;
            }
        }
    },

    /**
     * Return WebGL uniform locations for this filter's shader.
     *
     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
     * @param {WebGLShaderProgram} program This filter's compiled shader program.
     */
    getUniformLocations: function(gl, program) {
        return {
            uMyParameter: gl.getUniformLocation(program, 'uMyParameter'),
        };
    },

    /**
     * Send data from this filter to its shader program's uniforms.
     *
     * @param {WebGLRenderingContext} gl The GL canvas context used to compile this filter's shader.
     * @param {Object} uniformLocations A map of string uniform names to WebGLUniformLocation objects
     */
    sendUniformData: function(gl, uniformLocations) {
        gl.uniform1f(uniformLocations.uMyParameter, this.threshold);
    },
});

/**
 * Returns filter instance from an object representation
 * @static
 * @param {Object} object Object to create an instance from
 * @param {function} [callback] to be invoked after filter creation
 * @return {fabric.Image.filters.Redify} Instance of fabric.Image.filters.Redify
 */
fabric.Image.filters.Redify.fromObject = fabric.Image.filters.BaseFilter.fromObject;

})(typeof exports !== 'undefined' ? exports : this);

一旦您这样做了,您就可以像下面这样简单地使用它来传递一个变量

代码语言:javascript
复制
fabric.Image.fromURL('pug.jpg', function(img) {
  img.filters.push(
    new fabric.Image.filters.Redify({ threshold: 10 }));

  img.applyFilters();
  canvas.add(img);
});
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36082793

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档