问题描述
我在寻找一个解决方案来改变产品的纹理/图案。
此时我有:
- 透明背景
- 一张.png图片纹理
使用以下代码:
< canvas id =awidth =800height = 500> Canvas不支持您的浏览器< / 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
- 使用合成模式
目标位置
在顶部绘制主图像 - a cut-out
如果你想减小模式的大小,你可以使用较小版本的图片,绘制到较小尺寸的临时画布,并将其用作模式,或者对模式本身使用新的变换方法。
演示
var img1 = new Image,img2 = new Image,cnt = canvas = document.getElementById(canvas),ctx = canvas.getContext(2d); //为demo加载图像(忽略)img1.onload = img2.onload = function(){if(! - cnt) go()}; img1.src =http://i.imgur.com/8WqH9v4.png; // sofaimg2.src =http://i.stack.imgur.com/sQlu8.png; // pattern // MAIN CODE --- function go(){//创建模式ctx.fillStyle = ctx.createPattern(img2,repeat); // fill pattern 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); //改变合成模式(混合模式自动设置为正常)ctx.globalCompositeOperation =destination-in; // draw to cut-out sofa ctx.drawImage(img1,0,0,img1.width * .5,img1.height * .5);}
< canvas id =canvaswidth = 600 height = 400>< / canvas>
/ pre>
如果您愿意,也可以颠倒绘制图片的顺序等。这只是一种方法的例子。
如果你需要准确的纹理,那么没有办法拍照或使用3D软件,或手绘纹理。
注意:IE不支持 multiply
。需要手动迭代像素并将每个组件彼此相乘。
您可以通过这种方式测试支持:
ctx.globalCompositeOperation =multiply;
if(ctx.globalCompositeOperation ===multiply){
//如上所述混合
}
else {
//手动迭代并混合
}
混合模式评论,这当然也可以使用。我只想指出几点要考虑的事情。第一个是这是一个不可分离的混合模式,意味着它取决于所有组件,因为它通过HSL颜色模型。这使它有点更加计算密集。
第二个是,如果你最终必须手动(例如在IE中),代码是一个更复杂以模拟,并且会明显更慢。
I'm looking for a solution to change the texture/pattern for a product.
At this moment i have:
- A .png picture of a couch with a transparent background
- A .png picture of a texture
With the following code:
<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);
}
`
I get this result:
As you can see, the whole object is filled with my texture. No definitions of the pillows etc. are visible anymore. Is it possible to let my texture be a sort of transparent mask?
I'm already able to change the color of the couch:
But I'd like to be able to also add a pattern to my couch!
Any help will be appreciated and I'm already very sorry for my bad English.
If you're just after an illustrative approximation you can use a combination of blending and composition modes.
First thing is to make sure your main image has transparency - this is important for composition to work (I made a rough cut-off in the following demo).
Main steps:
- Draw the pattern
- Draw the main image on top with blending mode
multiply
- Draw the main image on top with compositing mode
destination-in
- this will make a cut-out
If you want to reduce the size of the pattern you can either do this by using a smaller version of the image, draw to a temporary canvas at a smaller size and use that as pattern, or use the new transform methods on the pattern itself.
Demo
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 = "http://i.imgur.com/8WqH9v4.png"; // sofa
img2.src = "http://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 (blending mode is automatically set to normal)
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>
You can also reverse the order of which image is drawn etc., if you prefer. This is just an example of one way.
If you need accurate texture then there is no way around to either take photos or use a 3D software, or hand-drawn the textures.
NOTE: IE does not support multiply
yet. - For this you need to manually iterate through the pixels and multiply each component with each other.
You can test for support this way:
ctx.globalCompositeOperation = "multiply";
if (ctx.globalCompositeOperation === "multiply") {
// blend as above
}
else {
// iterate and blend manually
}
Blending mode luminosity
is mentioned in comments and this can be used too of course. I just want to point a couple of things to consider. The first is that this is a non-separable blending mode meaning it depends on all components as it goes through the HSL color model. This makes it a bit more compute intensive.
The second is that if you end up having to do this manually (in for example IE) the code is a bit more complex to emulate, and will be noticeably slower.
这篇关于用纹理/图案填充图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!