Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to set contrast and saturation using fabric.js

I want to set contrast, saturation and hue in my image editor. for this i use fabric.js but it have only brightness option..

Here is the my fabric js code

(function() {

fabric.Object.prototype.transparentCorners = false;
  var $ = function(id){return document.getElementById(id)};
  console.log($);

  function applyFilter(index, filter) {
    console.log(filter);
      var obj = canvas.getActiveObject();
      obj.filters[index] = filter;
      obj.applyFilters(canvas.renderAll.bind(canvas));
  }

  function applyFilterValue(index, prop, value) {
   var obj = canvas.getActiveObject();
   if (obj.filters[index]) {
   obj.filters[index][prop] = value;
   obj.applyFilters(canvas.renderAll.bind(canvas));
  }
 }

  fabric.Object.prototype.padding = 5;
  fabric.Object.prototype.transparentCorners = false;

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

  fabric.Image.fromURL('../lib/bg.png', function(img) {
    canvas.backgroundImage = img;
   canvas.backgroundImage.width = 400;
  canvas.backgroundImage.height = 400;
  });


  canvas.on({
   'object:selected': function() {
    fabric.util.toArray(document.getElementsByTagName('input'))
                       .forEach(function(el){ el.disabled = false; })

    var filters = ['brightness',];
 //         var filters = ['grayscale', 'invert', 'remove-white',  'sepia', 'sepia2',
 //                      'brightness', 'noise', 'gradient-transparency', 'pixelate',
 //                      'blur', 'sharpen', 'emboss', 'tint', 'multiply',   'blend'];

      for (var i = 0; i < filters.length; i++) {
         $(filters[i]).checked = !!canvas.getActiveObject().filters[i];
      }

      applyFilter(5, true   && new f.Brightness({
      brightness: parseInt($('brightness-value').value, 10)
    }));



    },
    'selection:cleared': function() {
      fabric.util.toArray(document.getElementsByTagName('input'))
                      .forEach(function(el){ el.disabled = true; })
    }
   });

   fabric.Image.fromURL('../upload/Chrysanthemum.jpg', function(img) {
    var oImg = img.set({ left: 50, top: 100, angle: 0 }).scale(0.9);
   canvas.add(oImg).renderAll();
   canvas.setActiveObject(oImg);
  });
 $('brightness').onclick = function () {
   applyFilter(5, this.checked && new f.Brightness({
    brightness: parseInt($('brightness-value').value, 10)
   }));
   };
    $('brightness-value').onchange = function() {
    applyFilterValue(5, 'brightness', parseInt(this.value, 10));
  };

 })();
like image 486
Praveen Avatar asked Oct 31 '22 19:10

Praveen


2 Answers

Last year I wrote a HSL plugin which might be of use:

fabric.Image.filters.HSL = fabric.util.createClass(fabric.Image.filters.BaseFilter, {

    type: 'HSL',

    initialize: function(options) {
        options || (options = {});
        this.hue        = options.hue        || 0;
        this.saturation = options.saturation || 0;
        this.lightness  = options.lightness  || 0;
    },

    rgbToHsl: function(r, g, b) {
        r /= 255, g /= 255, b /= 255;
        var max = Math.max(r, g, b), min = Math.min(r, g, b);
        var h, s, l = (max + min) / 2;

        if (max == min) {
            h = s = 0;
        } else {
            var d = max - min;
            s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
            switch (max) {
                case r: h = (g - b) / d + (g < b ? 6 : 0); break;
                case g: h = (b - r) / d + 2; break;
                case b: h = (r - g) / d + 4; break;
            }
            h /= 6;
        }

        return [h, s, l];
    },

    hslToRgb: function(h, s, l) {
        var r, g, b;

        if (s == 0) {
            r = g = b = l;
        } else {
            function hue2rgb(p, q, t){
                if (t < 0) t += 1;
                if (t > 1) t -= 1;
                if (t < 1/6) return p + (q - p) * 6 * t;
                if (t < 1/2) return q;
                if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
                return p;
            }

            var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
            var p = 2 * l - q;
            r = hue2rgb(p, q, h + 1/3);
            g = hue2rgb(p, q, h);
            b = hue2rgb(p, q, h - 1/3);
        }
        return [r * 255, g * 255, b * 255];
    },

    applyTo: function(canvasEl) {
        var context = canvasEl.getContext('2d'),
            imageData = context.getImageData(0, 0, canvasEl.width, canvasEl.height),
            data = imageData.data;

        for (var i=0; i<data.length; i+=4)
        {
            // Convert RGB to HSL
            var hsl = this.rgbToHsl(data[i], data[i+1], data[i+2]);

            // Apply HSL values
            if (this.hue       ) hsl[0] = this.hue;
            if (this.saturation) hsl[1] = this.saturation;
            if (this.lightness ) hsl[2] = this.lightness;

            // Convert HSL back to RGB
            var rgb = this.hslToRgb(hsl[0], hsl[1], hsl[2]);

            // Update data
            data[i]   = rgb[0];
            data[i+1] = rgb[1];
            data[i+2] = rgb[2];
        }

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

    toObject: function() {
        return extend(this.callSuper('toObject'), {
            hue: this.hue,
            saturation: this.saturation,
            lightness: this.lightness
        });
    }
});

Add to your page after FabricJS has loaded and call like this:

var hue = 1;        // Range: 0 to 1
var brightness = 1; // Range: 0 to 1
var lightness = 1;  // Range: 0 to 1

var filterHSL = new img.filters.HSL({
    hue: hue,
    saturation: saturation,
    lightness: lightness
});

img.filters = [filterHSL];
img.applyFilters(canvas.renderAll.bind(canvas));

...where canvas is your FabricJS canvas object.

I hope this helps.

like image 117
Steve Holgado Avatar answered Nov 09 '22 12:11

Steve Holgado


You can now do this with the latest Fabricjs release, 1.6.6

fabric.Image.filters.Contrast and fabric.Image.filters.Saturate were added in this release.

I made a fiddle to show you how to achieve it (note: change the applyFilter() function to achieve different filters):

DEMO

like image 25
jdrake Avatar answered Nov 09 '22 12:11

jdrake