Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to fill a image with pattern

let's say i have a image ! enter image description here

now i want to fill that image with enter image description here

and my final image should look like thisenter image description here

how to do it? so far i was able to change the color of that image but was not able to fill pattern.

can i do it with html5 canvas (pattern)? is there any way to do it with php or any web platform.

like image 536
MD TAHMID HOSSAIN Avatar asked Jul 27 '13 05:07

MD TAHMID HOSSAIN


2 Answers

Use these steps to create simulate applying a mapped pattern to your shirt:

  • Create a high-contrast version of your shirt.
  • DrawImage that shirt onto the canvas
  • Set globalCompositeOperation to “source-atop”
  • (any new drawing will only appear where the shirt image is opaque)
  • Create a pattern from your checkered image
  • Fill the canvas with the checkered pattern
  • (it will only appear in the non-transparent shirt)
  • Set the globalAlpha to a very low value
  • Repeatedly drawImage the high-contrast shirt
  • (this effectively superimposes the shirt “wrinkles”)

enter image description here

For a better solution

Create a “bump-map” of the shirt and apply it with the checkered pattern in three.js

Here is code and a Fiddle: http://jsfiddle.net/m1erickson/kzfKD/

<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script src="http://code.jquery.com/jquery.min.js"></script>

<style>
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style>

<script>
$(function(){

    var canvas=document.getElementById("canvas");
    var ctx=canvas.getContext("2d");

    var img1=new Image();
    var img=new Image();
    img.onload=function(){

        img1.onload=function(){
            start();
        }
        img1.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/4jiSz1.png";
    }
    img.src="https://dl.dropboxusercontent.com/u/139992952/stackoverflow/BooMu1.png";

    function start(){

        ctx.drawImage(img1,0,0);

        ctx.globalCompositeOperation="source-atop";

        ctx.globalAlpha=.85;

        var pattern = ctx.createPattern(img, 'repeat');
        ctx.rect(0, 0, canvas.width, canvas.height);
        ctx.fillStyle = pattern;
        ctx.fill();

        ctx.globalAlpha=.15;
        ctx.drawImage(img1,0,0);
        ctx.drawImage(img1,0,0);

    }


}); // end $(function(){});
</script>

</head>

<body>
    <canvas id="canvas" width=436 height=567></canvas>
</body>
</html>
like image 167
markE Avatar answered Sep 19 '22 12:09

markE


As suggested in the comments on your question, one approach is to overlay DOM elements -- the top DOM element should be a PNG with transparency, and the bottom one should be your background pattern. This also works (and it's faster since you don't have to compute the combined image) but provides a little less flexibility in terms of the way the images are combined. With the canvas method, you can use any blend mode you want.

A second option which is not supported by most browsers yet is to use CSS background blend modes. This would allow you to create a PNG image with transparency, assign it a background color, and use blending with CSS. This is fast and only requires one DOM element.

A third approach is to use canvases. (Edit: markE's canvas approach is faster and simpler.) I implemented one canvas-based approach in this JSFiddle: http://jsfiddle.net/IceCreamYou/uzzLa/ -- here's the gist:

// Get the base image data
var image_data = ctx.getImageData(0, 0, ctx.canvas.width, ctx.canvas.height);
var image_data_array = image_data.data;

// Get the pattern image data
var overlay_data = ovlyCtx.getImageData(0, 0, ovlyCtx.canvas.width, ovlyCtx.canvas.height).data;

// Loop over the pixels in the base image and merge the colors
for (var i = 0, j = image_data_array.length; i < j; i+=4) {
    // Only merge when the base image pixel is nontransparent
    // Alternatively you could implement a border-checking algorithm depending on your needs
    if (image_data_array[i+3] > 0) {
        image_data_array[i+0] = combine(image_data_array[i+0], overlay_data[i+0]); // r
        image_data_array[i+1] = combine(image_data_array[i+1], overlay_data[i+1]); // g
        image_data_array[i+2] = combine(image_data_array[i+2], overlay_data[i+2]); // b
    }
}

// Write the image data back to the canvas
ctx.putImageData(image_data, 0, 0);

What it does is create one canvas with the base image and a second canvas that tiles your pattern image, then uses the pixel data to overlay the pattern over the base when the base pixels are nontransparent.

like image 26
IceCreamYou Avatar answered Sep 19 '22 12:09

IceCreamYou