我可以在fabricjs中使用图像滤镜在单张图像上应用两种阴影颜色吗?

Ash*_*pal 1 javascript canvas fabricjs

我有两个这样的阴影颜色:

颜色为红色和蓝色

我想使用fabric js图像过滤器在单个图像上应用渐变颜色.

基本上我添加了两个颜色调色板.我需要的是当我从调色板中改变颜色时两种颜色都应用在单个图像中,如上图所示.那可能吗?

我正在设计一件如下的T恤:

T恤

我想在T恤的大灰色图像上应用这两种颜色.目前,不同颜色的图像在织物js中作为单独的图像和单独的对象工作,我想在单个灰色图像部分上应用这些颜色.

有没有办法让这项工作?

ale*_*dro 6

由于FabricJs本身没有给出应用渐变的可能性Image,因此您可以使用ImageFilter以下代码段中包含的内容来完成任务.

(function(global) {

      'use strict';

      var fabric = global.fabric || (global.fabric = {}),
        extend = fabric.util.object.extend;

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

        type: 'GradientEffect',

        initialize: function (options) {
          options = options || {};
          this.gradient = options.gradient || {};
          this.img = options.img;
        },

        applyTo: function(canvasEl) {
          var gr = this.gradient;
          var w = this.img._element.naturalWidth;
          var h = this.img._element.naturalHeight;
          var hc = document.createElement('canvas');

          hc.setAttribute('width', w);
          hc.setAttribute('height', h);

          var fhc = new fabric.Canvas(hc);
          var rect = new fabric.Rect({
            fill: 'transparent',
            width: w,
            height: h
          });

          rect.setGradient('fill', gr);

          fhc.add(rect);
          fhc.renderAll();

          var ifhcContext = fhc.getContext('2d');
          var fhcImageData = ifhcContext.getImageData(0, 0, fhc.width, fhc.height);
          var fhcData = fhcImageData.data;

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

          for (var i = 0, n = data.length; i < n; i += 4) {
            if(data[i] != 0 && data[i+1] != 0 && data[i+2] != 0) {
              data[i] += fhcData[i];
              data[i + 1] += fhcData[i + 1];
              data[i + 2] += fhcData[i + 2];

            }
          }

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

        toObject: function() {
          return extend(this.callSuper('toObject'), {
            gradient: this.gradient

          });
        }
      });

      fabric.Image.filters.GradientEffect.fromObject = function(object) {
        return new fabric.Image.filters.GradientEffect(object);
      };

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


var canvas = new fabric.Canvas('c');

fabric.Image.fromURL('http://i.imgur.com/bkMw5mx.png', function(img) {
  var gr = {
    x1: 0,
    y1: 0,
    x2: 0,
    y2: img.height,
    colorStops: {
      0: "red",
      1: "blue",
    }
  };
  img.filters.push(new fabric.Image.filters.GradientEffect({
    gradient: gr,
    img: img,
    
  }));
  img.applyFilters(canvas.renderAll.bind(canvas));
  canvas.add(img.set({
    width: 150,
    height: 150,

  }));
}, {
  crossOrigin: ''
});
Run Code Online (Sandbox Code Playgroud)
.floatLeft {
  display: inline-block;
  border: 2px solid #ccc;
}
.placeholder {
  margin-left: 10px;
}
Run Code Online (Sandbox Code Playgroud)
<script src="//cdnjs.cloudflare.com/ajax/libs/fabric.js/1.5.0/fabric.min.js"></script>
<img class='image floatLeft' src='http://i.imgur.com/bkMw5mx.png' width='200' height='200'>
<div class='placeholder floatLeft'>
  <canvas id='c' width='300' height='300'></canvas>
  <div>
Run Code Online (Sandbox Code Playgroud)


这项工作是通过applyTo函数完成的,我在运行中创建了一个新的,我Canvas在其上放置了一个填充了参数渐变的矩形,然后,逐个像素地应用从渐变中拾取的相对颜色.唯一的问题是你的图像无法动态调整大小,因为imageData图像和imageData渐变的长度应该是相同的长度:

applyTo: function(canvasEl) {
          var gr = this.gradient;
          var w = this.img._element.naturalWidth;
          var h = this.img._element.naturalHeight;
          var hc = document.createElement('canvas');

          hc.setAttribute('width', w);
          hc.setAttribute('height', h);

          var fhc = new fabric.Canvas(hc);
          var rect = new fabric.Rect({
            fill: 'transparent',
            width: w,
            height: h
          });

          rect.setGradient('fill', gr);

          fhc.add(rect);
          fhc.renderAll();

          var ifhcContext = fhc.getContext('2d');
          var fhcImageData = ifhcContext.getImageData(0, 0, fhc.width, fhc.height);
          var fhcData = fhcImageData.data;

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

          for (var i = 0, n = data.length; i < n; i += 4) {
            if(data[i] != 0 && data[i+1] != 0 && data[i+2] != 0) {
              data[i] += fhcData[i];
              data[i + 1] += fhcData[i + 1];
              data[i + 2] += fhcData[i + 2];

            }
          }

          context.putImageData(imageData, 0, 0);
        }
Run Code Online (Sandbox Code Playgroud)