Как заполнить изображение с рисунком

скажем, у меня есть изображение! enter image description here

теперь я хочу заполнить это изображение с помощью enter image description here

и мое окончательное изображение должно выглядеть так: enter image description here

как это сделать? пока я смог изменить цвет этого изображения, но не смог заполнить шаблон.

Могу ли я сделать это с html5 canvas (pattern)? есть ли способ сделать это с помощью php или любой веб-платформы.

Ответ 1

Используйте эти шаги для создания имитации применения сопоставленного шаблона к вашей рубашке:

  • Создайте высококонтрастную версию вашей рубашки.
  • DrawImage, который рубашка на холсте
  • Установите globalCompositeOperation в "source-atop"
  • (любой новый рисунок появится только там, где изображение рубашки непрозрачно)
  • Создайте шаблон из вашего клетчатого изображения
  • Заполните холст клетчатым рисунком
  • (он появится только в непрозрачной рубашке)
  • Установите для globalAlpha очень низкое значение
  • Неоднократный drawImage высококонтрастная рубашка
  • (это эффективно накладывает "морщины" рубашки).

enter image description here

Для лучшего решения

Создайте "рельефную карту" рубашки и примените ее с клетчатым рисунком в three.js

Вот код и скрипт: 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>

Ответ 2

Как указано в комментариях к вашему вопросу, одним из подходов является наложение элементов DOM - верхний элемент DOM должен быть PNG с прозрачностью, а нижний должен быть вашим фоновым рисунком. Это также работает (и это быстрее, поскольку вам не нужно вычислять комбинированное изображение), но обеспечивает немного меньшую гибкость с точки зрения сочетания изображений. С помощью метода холста вы можете использовать любой режим смешивания, который вы хотите.

Второй вариант, который еще не поддерживается большинством браузеров, заключается в использовании режимов фонового смешивания CSS. Это позволит вам создать изображение PNG с прозрачностью, присвоить ему цвет фона и использовать смешение с CSS. Это быстро и требует только одного элемента DOM.

Третий подход - использовать холсты. ( Изменить: подход markE canvas быстрее и проще.) В этом JSFiddle я применил один подход, основанный на холсте: http://jsfiddle.net/IceCreamYou/uzzLa/ - здесь суть:

// 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);

Что он делает, это создать один холст с базовым изображением и второй холст, который разбивает изображение вашего шаблона, а затем использует пиксельные данные для наложения рисунка над базой, когда базовые пиксели непрозрачны.