我试图创建一个自定义过滤器,它应该喜欢接受颜色代码。
这是我的密码。
它很好用。
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);
}); 现在,我需要创建一个带有特定颜色代码的过滤器。我发现
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,请解释我如何通过颜色代码。
发布于 2016-03-21 06:38:04
您发现的redify过滤器并不是真正的彩色过滤器。正如你可以从代码中看到的那样,它正在扼杀绿色和蓝色的channell,而只留下了图像的红色。这是不一样的效果,你会得到的应用颜色与红色。
您可以通过更改尚存的channell的方式创建一个蓝色和绿色的过滤器:
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)将灰度乘以你想要的颜色。
这将或多或少地等于应用现有的制造滤波器的灰度和乘法。
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'});<script src="http://www.deltalink.it/andreab/fabric/fabric.js"></script>
<canvas width="500" height="400" id="c" ></canvas>为了比较内置的函数is和gimp的例子,我创建了一个光度滤波器来代替基于“平均”方法的灰度滤波器。正如您所看到的,结果是非常相似的,但它是图像依赖的。
如果要构建自己的筛选器,请检查乘法筛选器源代码,以查看如何处理筛选器中的参数。
发布于 2018-01-10 22:56:54
为了能够使用您的过滤器,您需要根据Fabricjs滤波器样板将筛选器代码更改为下面
(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);一旦您这样做了,您就可以像下面这样简单地使用它来传递一个变量
fabric.Image.fromURL('pug.jpg', function(img) {
img.filters.push(
new fabric.Image.filters.Redify({ threshold: 10 }));
img.applyFilters();
canvas.add(img);
});https://stackoverflow.com/questions/36082793
复制相似问题