2016-05-21 2 views
2

У меня есть холст, и я хочу использовать drawImage, чтобы нарисовать изображение за текущим контентом на холсте.Как нарисовать изображение за другим содержимым на холсте?

В связи с тем, что на холсте есть контент (я использую «Буквально холст» для создания холста, содержащего изображение, поэтому я не могу нарисовать изображение первым), я не могу использовать drawImage перед тем, как сделать рендер остальное содержание.

Возможно ли до drawImage позади всего остального содержимого на холсте?

+0

единственная цель водяного знака должен быть на вершине чего-то не за – slash197

+0

@ slash197 Игнорируйте тот факт, что это водяной знак - это возможность вставить его за все другое содержимое на холсте? – think123

+0

Нет, это не так, у холста нет такой памяти. –

ответ

2

К сожалению о предыдущем посте, я не правильно прочитал ваш пост

Может быть, вы могли бы спасти холст, нарисовать изображение, а затем перезагрузить старое содержание на верхней часть нарисованного изображения? Вот некоторые JS psuedocode:

var imgData=ctx.getImageData(0,0,canvas.width,canvas.height); 
ctx.drawImage('Your Image Watermark Stuff'); 
ctx.putImageData(imgData,0,0); 
+0

Я понимаю, что это можно сделать, но это не то, что я хочу сделать - я хочу вставить изображение позади всего другого контента, а не делать его прозрачным. – think123

+0

О, извините, я просто прочитал водяной знак и прыгнул на него –

+0

Обновлено мой ответ –

2

Да, вы можете просто использовать globalCompositeOperationdestination-over, но учтите, что ваше первое изображение нуждается в прозрачности, в противном случае, вы, очевидно, не видит ничего:

var img1 = new Image(); 
 
var img2 = new Image(); 
 

 
var loaded = 0; 
 
var imageLoad = function(){ 
 
    if(++loaded == 2){ 
 
    draw(); 
 
    } 
 
    }; 
 
img1.onload = img2.onload = imageLoad; 
 

 
var draw = function(){ 
 
    var ctx = c.getContext('2d'); 
 
    ctx.drawImage(img1, 100,100); 
 
    // wait a little bit before drawing the background image 
 
    setTimeout(function(){ 
 
    ctx.globalCompositeOperation = 'destination-over'; 
 
    ctx.drawImage(img2, 0,0); 
 
    }, 500); 
 
    } 
 
img1.src = "https://dl.dropboxusercontent.com/s/4e90e48s5vtmfbd/aaa.png"; 
 
img2.src = "http://lorempixel.com/200/200";
<canvas id="c" width="200" height="200"></canvas>

+0

Мне очень понравился этот ответ, но я просто понял, что он не очень широко поддерживается. –

+0

@wateriswet hum поддерживается всеми браузерами, поддерживающими холст html5. – Kaiido

+0

Вы уверены? Если это так, вы должны обновить документацию MDN, связанную с вашим ответом. –

0

Простым решением было бы использовать другой холст за первым.

Обычно пиксели холста инициализируются прозрачным черным цветом и поэтому отлично видны.

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

  1. создать временный холст того же размера
  2. нарисовать свой образ в этом временном полотне
  3. получить Объект ImageData как временного холста, так и исходного холста
  4. копия с временного холста на исходный холст, только если исходный холст не установлен на цвет фона

В коде:

var tmpcanvas = document.createElement("canvas"); 
tmpcanvas.width = canvas.width; 
tmpcanvas.height = canvas.height; 
var temp_ctx = tmpcanvas.getContext("2d"); 

// ... draw your image into temporary context ... 

var temp_idata = temp_ctx.getImageData(0, 0, canvas.width, canvas.height); 
var temp_data = temp_idata.data; 

// Access the original canvas pixels 
var ctx = canvas.getContext("2d"); 
var idata = ctx.getImageData(0, 0, canvas.width, canvas.height); 
var data = idata.data; 

// Find the background color (here I'll use first top-left pixel) 
var br_r = data[0], bg_g = data[1], bg_b = data[2]; 

// Replace all background pixels with pixels from temp image 
for (var i=0,n=canvas.width*canvas.height*4; i<n; i+=4) { 
    if (data[i] == bg_r && data[i+1] == bg_g && data[i+2] == bg_b) { 
     data[i] = tmp_data[i]; 
     data[i+1] = tmp_data[i+1]; 
     data[i+2] = tmp_data[i+2]; 
     data[i+3] = tmp_data[i+3]; 
    } 
} 

// Update the canvas 
ctx.putImageData(idata, 0, 0); 

этот подход, однако, будет иметь более низкое качество, если исходный холст графика был составлен со сглаживанием или если пиксели фонового цвета также используется в изображении (например, объект на белом фоне #FFF, где также выделяются объекты #FFF). Другая проблема заключается в том, что цвет фона не является абсолютно однородным значением RGB (это произойдет, если изображение было сжато с помощью алгоритма с потерями, например jpeg).

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

+0

Как это отличается от моего поста? –

1

Вы можете использовать KonvaJS. И затем используйте слои для него.

<!DOCTYPE html> 
<html> 

<head> 
    <script src="https://cdn.rawgit.com/konvajs/konva/0.13.0/konva.min.js"></script> 
    <meta charset="utf-8"> 
    <title>Konva Rect Demo</title> 
    <style> 
    body { 
     margin: 0; 
     padding: 0; 
     overflow: hidden; 
     background-color: #F0F0F0; 
    } 
    </style> 
</head> 

<body> 
    <div id="container"></div> 
    <script> 
    var width = window.innerWidth; 
    var height = window.innerHeight; 

    var stage = new Konva.Stage({ 
     container: 'container', 
     width: width, 
     height: height 
    }); 

    var layer = new Konva.Layer(); 
    var imageObj = new Image(); 
    imageObj.onload = function() { 
     var baseImage = new Konva.Image({ 
     x: 50, 
     y: 50, 
     width: width, 
     height: height, 
     image: image 
     }); 

     // add the shape to the layer 
     layer.add(rect); 

     // add the layer to the stage 
     stage.add(layer); 
    }; 
    imageObj.src = 'url to your image' 
    </script> 

</body> 

</html> 
Смежные вопросы