Fabric.js - Shade Filter

It seems I can not use the fabric.js hue filter function to work or find any example of its use. I tried:

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

I also tried #00ff00 instead of green , but both of them just turn the image black.

I have a number of pngs that are only black and transparent (like basic shapes), and I want to be able to change their color, I donโ€™t know if this is possible or not, but I decided the shade seemed promising, I just canโ€™t get it work.

I also tried it in photos, just black, and I used other filters (like invert) in one place in the code, and it worked fine.

Any help would be greatly appreciated.

UPDATE: Full JS is used, image three is simply displayed as a black box.

 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); }); 
+4
source share
5 answers

I wrote this filter, and I use it in one of our projects, and it still worked well. But what I'm missing is a call to applyFilters - maybe you could write a little more code?

I also think that I always applied colors such as:

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

It has no color names, no hash in front. I know that a parser for flowers should be a little more reliable. Also make sure that this filter only works for images with an alpha channel - means translucent PNG files.

+4
source

I parsed the source class for the Tint filter, and I found that this line

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

should be configured this way

 var rgb = this.color; 

so that it works properly. Of course, then the rgb variable is useless, and you can directly change it to this.color, but I personally prefer single-line changes.

I'm not sure what the original purpose of converting hex to integer, and then to string, was because it makes no sense to me.

You will not want to change the source of fabric.js, so I suggest you create your own filter class, as described in this lesson in the Filters section: http://fabricjs.com/fabric-intro-part-2/

+3
source

I had the same problem with a JPEG or PNG image (with a transparent background).

I found out that the hue class is not working properly, so I changed it a bit. You can find the stream in Google Groups: https://groups.google.com/forum/#!msg/fabricjs/DPN0WuRtc-o/ZGgIQK5F9xAJ

Here is my workaround class (which works using the full hex value, but you can easily adapt it to your needs):

  fabric.Image.filters.Tint = fabric.util.createClass({ type: 'Tint', /** * Constructor * @memberOf fabric.Image.filters.Tint.prototype * @param {Object} [options] Options object */ //That 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 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 }; } 

}) `

I use it this way tho:

 //$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)); 

Hope this helps someone.

L.

EDIT

Some changes have been made inside the hue filter class (Github: https://github.com/kangax/fabric.js/pull/862 ).

I tested it again, but I still had no luck, so I changed it a bit. You can find the source code + explanations in Google Groups ( https://groups.google.com/forum/#!topic/fabricjs/DPN0WuRtc-o )

EDIT No. 2

So, Kienz made a JSFiddle ( http://jsfiddle.net/Kienz/4wGzk/ ) that uses the hue filter class with error correction, and it got it working. I would recommend implementing it the way it did.

+1
source

I had the same problem. It turned out to be the js version that I used. Without grabbing the latter, fearing to upset other things, I grabbed only what I needed and used it as a custom filter that overrides the current implementation of the shades.

Here is what I used:

 /** * 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 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 }); } }); 
0
source

One thing that I noticed when doing something like this is that the filter will not work until the image itself has been added to the canvas.

0
source

Source: https://habr.com/ru/post/1439140/


All Articles