creating a custom image temperature filter using fabric.js stable

68 Views Asked by At

I use fabric.js 5.3.0 and i'm trying to create a custom temperature filter, I understand that fabric.js had many API changes, i tried to search online and nothing quite works. so lets see what I've got so far.

so every search i did, or every bot i asked gave me a different answer which is very confusing. i want to create a temperature custom filter that is based on canvas2d and not webgl because.. well i don't know webgl!

if something like that is not that complicated in webGL and can someone provide an example it would be great...

i understand that applyTo2d function is supposed to be executed and with that i can get the image data and manipulate it? but in my case only the applyTo function is being called, i assume it's because it still works with webGL and not canvas. i may be wrong i investigated a lot and got different information every time so still confused.

i tried some code suggestions to disable webGL for this filter but nothing made much sense.

this is the code that I have so far:

//@ts-ignore
fabric.Image.filters.Temperature = fabric.util.createClass({
  type: 'Temperature',

  initialize: function(options: any) {
    options = options || {};
    this.temperature = options.temperature || 0;
  },

  applyTo: function(options: any) {
    var imageData = options.imageData,
      data = imageData.data,
      i, len;

    for (i = 0, len = data.length; i < len; i += 4) {
      data[i] += this.temperature;
      data[i + 2] -= this.temperature;
    }
  },
  
  toJSON: function() {
    return {
      temperature: this.temperature
    };
  }
});

// @ts-ignore
fabric.Image.filters.Temperature.fromObject = function(object) {
  // @ts-ignore
  return new fabric.Image.filters.Temperature(object);
};

i'm sure i tried many other things.. i'm at this issue over a week i'm just confused from all the scrambled information i got so far.

so in general i would like to know how to create a custom filter, and i'm pretty sure that learning webGL will complicate things, but if the image manipulation part is as easy as canvas.. cool if not.. l need the canvas solution.

update

so.. yeah i really don't mind learning webgl but if i could just find any custom webgl image filter for fabric.js that i can at least know how to apply it, it would be awesome, if someone can post that it would be great.

anywho i finally got a custom filter to work with canvas2d but dumping and restoring causing the canvas to look empty only when i apply any of my custom filters. still can't figure out why.

so this is what I have so far:

first.. i need to force canvas2d instead of webGL:

 //@ts-ignore
    fabric.initFilterBackend = function() {
      return (new fabric.Canvas2dFilterBackend());
    };

now i wanted a range of -1 to 1, where zero was the default, and that the effect will be subtle, so i did this:

//@ts-ignore
fabric.Image.filters.Temperature = fabric.util.createClass({
  type: 'Temperature',
  temperature: 0,

  initialize: function(options: any) {
    options = options || {};
    // Scale the temperature factor to make adjustments more subtle
    this.temperature = (options.temperature || 0); // Default temperature value
    console.info(`set temperature to ${this.temperature}`);

  },
  isNeutralState: function () {
    return this.temperature === 0;
  },

  applyTo: function(options: any) {
    console.info('applyTo');
    let imageData = options.imageData;
    let data = imageData.data;
    const len = data.length;
    const temperature = this.temperature*50; // Scale temperature to be between -255 and 255

    for (let i = 0; i < len; i += 4) {
      // Apply temperature adjustment to each pixel
      data[i] += temperature; // Red channel
      data[i + 2] -= temperature; // Green channel
    }

    options.imageData = imageData;

    // Set willReadFrequently to true
    options.ctx.canvas.willReadFrequently = true;
  },

  toObject: function () {
    return {
      type: this.type,
      temperature: this.temperature,
    };
  },

});

//@ts-ignore
fabric.Image.filters.Temperature.fromObject = function(object) {
  // @ts-ignore
  return new fabric.Image.filters.Temperature(object);
};

excuse all the //@ts-ignore, i'm on an angular17 typescript project.

update

ok so canvas.loadFromJSON() fails silently, i tried to debug, the objects looks the same.. unless for some reason it broke the actual base64 images while applying the filter again? i'll try to investigate more by if anyone has any information it would be great

0

There are 0 best solutions below