用 texture/pattern 填充图像
Fill image with texture/pattern
我正在寻找更改产品 texture/pattern 的解决方案。
此刻我有:
- 带有透明背景的沙发的 .png 图片
- 纹理的.png图片
使用以下代码:
<canvas id="a" width="800" height="500">Canvas not supported on your browser</canvas>
var width = $(window).width();
var height = $(window).height();
var c = document.getElementById("a");
var ctx = c.getContext("2d");
var can2 = document.createElement('canvas');
document.body.appendChild(can2)
can2.width = c.width;
can2.height = c.height;
var ctx2 = can2.getContext("2d");
var test = new Image();
test.src = "Images/newBank.png";
test.onload = function () {
ctx2.drawImage(test, 0, 0);
};
var img = new Image();
img.src = "Images/texturetrans.png";
img.onload = function () {
ctx2.globalCompositeOperation = 'source-in';
var ptrn = ctx2.createPattern(img, 'repeat');
ctx2.fillStyle = ptrn;
ctx2.fillRect(0, 0, can2.width, can2.height);
}
`
我得到这个结果:
如你所见,整个对象都充满了我的纹理。枕头等的定义不再可见。是否可以让我的纹理成为一种透明蒙版?
我已经可以改变沙发的颜色了:
但我也希望能够在沙发上添加图案!
任何帮助将不胜感激,我已经为我糟糕的英语感到非常抱歉。
如果您只是想获得说明性的近似值,则可以结合使用混合和合成模式。
首先要确保您的主图像具有透明度 - 这对于合成工作很重要(我在下面的演示中进行了粗略的截断)。
主要步骤:
- 画出图案
- 使用混合模式在顶部绘制主图像
multiply
- 使用合成模式在顶部绘制主图像
destination-in
- 这将进行裁剪
如果您想减小图案的大小,您可以使用较小版本的图像来实现,以较小的尺寸绘制临时 canvas 并将其用作图案,或者使用模式本身的新变换方法。
演示
var img1 = new Image, img2 = new Image, cnt = 2,
canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
// image loading for demo (ignore)
img1.onload = img2.onload = function() {if (!--cnt) go()};
img1.src = "//i.imgur.com/8WqH9v4.png"; // sofa
img2.src = "//i.stack.imgur.com/sQlu8.png"; // pattern
// MAIN CODE ---
function go() {
// create a pattern
ctx.fillStyle = ctx.createPattern(img2, "repeat");
// fill canvas with pattern
ctx.fillRect(0, 0, canvas.width, canvas.height);
// use blending mode multiply
ctx.globalCompositeOperation = "multiply";
// draw sofa on top
ctx.drawImage(img1, 0, 0, img1.width*.5, img1.height*.5);
// change composition mode
ctx.globalCompositeOperation = "destination-in";
// draw to cut-out sofa
ctx.drawImage(img1, 0, 0, img1.width*.5, img1.height*.5);
}
<canvas id="canvas" width=600 height=400></canvas>
如果愿意,您还可以颠倒绘制图像的顺序等。这只是一种方式的示例。
如果你需要精确的贴图,那就没办法了,要么拍照,要么用3D软件,要么手绘贴图。
注意:IE 不支持 multiply
- 为此,您需要手动遍历像素并将每个分量相互相乘。
您可以通过这种方式测试支持:
ctx.globalCompositeOperation = "multiply";
if (ctx.globalCompositeOperation === "multiply") {
// blend as above
}
else {
// iterate and blend manually
}
混合模式luminosity
在评论中提到,当然也可以使用。我只想指出一些需要考虑的事情。首先,这是一种不可分离的混合模式,这意味着它依赖于所有组件,因为它通过 HSL 颜色模型。这使得计算更加密集。
第二个是,如果您最终不得不手动执行此操作(例如在 IE 中),则代码的模拟会稍微复杂一些,而且速度会明显变慢。
我正在寻找更改产品 texture/pattern 的解决方案。
此刻我有:
- 带有透明背景的沙发的 .png 图片
- 纹理的.png图片
使用以下代码:
<canvas id="a" width="800" height="500">Canvas not supported on your browser</canvas>
var width = $(window).width();
var height = $(window).height();
var c = document.getElementById("a");
var ctx = c.getContext("2d");
var can2 = document.createElement('canvas');
document.body.appendChild(can2)
can2.width = c.width;
can2.height = c.height;
var ctx2 = can2.getContext("2d");
var test = new Image();
test.src = "Images/newBank.png";
test.onload = function () {
ctx2.drawImage(test, 0, 0);
};
var img = new Image();
img.src = "Images/texturetrans.png";
img.onload = function () {
ctx2.globalCompositeOperation = 'source-in';
var ptrn = ctx2.createPattern(img, 'repeat');
ctx2.fillStyle = ptrn;
ctx2.fillRect(0, 0, can2.width, can2.height);
}
`
我得到这个结果:
如你所见,整个对象都充满了我的纹理。枕头等的定义不再可见。是否可以让我的纹理成为一种透明蒙版?
我已经可以改变沙发的颜色了:
但我也希望能够在沙发上添加图案!
任何帮助将不胜感激,我已经为我糟糕的英语感到非常抱歉。
如果您只是想获得说明性的近似值,则可以结合使用混合和合成模式。
首先要确保您的主图像具有透明度 - 这对于合成工作很重要(我在下面的演示中进行了粗略的截断)。
主要步骤:
- 画出图案
- 使用混合模式在顶部绘制主图像
multiply
- 使用合成模式在顶部绘制主图像
destination-in
- 这将进行裁剪
如果您想减小图案的大小,您可以使用较小版本的图像来实现,以较小的尺寸绘制临时 canvas 并将其用作图案,或者使用模式本身的新变换方法。
演示
var img1 = new Image, img2 = new Image, cnt = 2,
canvas = document.getElementById("canvas"),
ctx = canvas.getContext("2d");
// image loading for demo (ignore)
img1.onload = img2.onload = function() {if (!--cnt) go()};
img1.src = "//i.imgur.com/8WqH9v4.png"; // sofa
img2.src = "//i.stack.imgur.com/sQlu8.png"; // pattern
// MAIN CODE ---
function go() {
// create a pattern
ctx.fillStyle = ctx.createPattern(img2, "repeat");
// fill canvas with pattern
ctx.fillRect(0, 0, canvas.width, canvas.height);
// use blending mode multiply
ctx.globalCompositeOperation = "multiply";
// draw sofa on top
ctx.drawImage(img1, 0, 0, img1.width*.5, img1.height*.5);
// change composition mode
ctx.globalCompositeOperation = "destination-in";
// draw to cut-out sofa
ctx.drawImage(img1, 0, 0, img1.width*.5, img1.height*.5);
}
<canvas id="canvas" width=600 height=400></canvas>
如果愿意,您还可以颠倒绘制图像的顺序等。这只是一种方式的示例。
如果你需要精确的贴图,那就没办法了,要么拍照,要么用3D软件,要么手绘贴图。
注意:IE 不支持 multiply
- 为此,您需要手动遍历像素并将每个分量相互相乘。
您可以通过这种方式测试支持:
ctx.globalCompositeOperation = "multiply";
if (ctx.globalCompositeOperation === "multiply") {
// blend as above
}
else {
// iterate and blend manually
}
混合模式luminosity
在评论中提到,当然也可以使用。我只想指出一些需要考虑的事情。首先,这是一种不可分离的混合模式,这意味着它依赖于所有组件,因为它通过 HSL 颜色模型。这使得计算更加密集。
第二个是,如果您最终不得不手动执行此操作(例如在 IE 中),则代码的模拟会稍微复杂一些,而且速度会明显变慢。