我可以在 fabricjs 中使用图像过滤器在单个图像上应用两种阴影颜色吗?
Can I apply two shaded color on single image with image filter in fabricjs?
我有两种像这样的阴影颜色:
我想用 fabric js 图像过滤器在单个图像上应用渐变颜色。
基本上我为颜色添加了两个调色板。我需要的是当我从调色板更改颜色时,两种颜色都适用于单个图像,如上图。这可能吗?
我正在设计如下的 T 恤:
我想将这两种颜色应用到 T 恤的大灰色图像上。目前不同的颜色图像在 fabric js 中作为单独的图像和单独的对象工作,我想将这些颜色应用于单个灰色图像部分。
有什么方法可以实现吗?
由于 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: ''
});
.floatLeft {
display: inline-block;
border: 2px solid #ccc;
}
.placeholder {
margin-left: 10px;
}
<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>
这项工作是通过 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);
}
我有两种像这样的阴影颜色:
我想用 fabric js 图像过滤器在单个图像上应用渐变颜色。
基本上我为颜色添加了两个调色板。我需要的是当我从调色板更改颜色时,两种颜色都适用于单个图像,如上图。这可能吗?
我正在设计如下的 T 恤:
我想将这两种颜色应用到 T 恤的大灰色图像上。目前不同的颜色图像在 fabric js 中作为单独的图像和单独的对象工作,我想将这些颜色应用于单个灰色图像部分。
有什么方法可以实现吗?
由于 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: ''
});
.floatLeft {
display: inline-block;
border: 2px solid #ccc;
}
.placeholder {
margin-left: 10px;
}
<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>
这项工作是通过 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);
}