2016-06-19 2 views
2

캔버스에 배경색을 지정하고 그 위에 PNG를 오버레이하려고합니다.배경색으로 채운 다음 PNG를 오버레이합니다.

enter image description here

예를 들어, (밝은 빨간색) backgroundColor = #D95753는 캔버스 충전 레벨이 될 경우 :

1 .-이 배경 색상을 설정

은 PNG 텍스처입니다

enter image description here

2.- PN를 오버레이 배경 색상

enter image description here

내가 가지고있는 코드의

하지만 작동하지 않습니다 위의 g. 배경색은 볼 수없고 PNG 이미지 만 볼 수 있습니다.

var background = new Image(); 
background.src = "http://i.stack.imgur.com/LF1P0.png"; 
background.height = y; // set it before 
background.width = x; // set it before 

ctx.fillStyle = backgroundColor; 
ctx.fillRect(0, 0, background.width, background.height); 

background.onload = function() { 
    ctx.drawImage(background,0,0, background.width, background.height); 
    memeEverything(); 
} 

고마워요!

답변

1

<canvas id="canvs" width="500" height="500"> 
<img src="http://i.stack.imgur.com/LF1P0.png" id="img"> 
</canvas> 

function onld(){ 
var can = document.getElementById('canvs'); 
var img = document.getElementById('img'); 
var ctx = can.getContext('2d'); 
ctx.fillStyle = 'rgba(217, 87, 83, 1)'; 
ctx.fillRect(10,10,500,500); 
ctx.globalAlpha=0.6; 
ctx.drawImage(img,10,10); 
} 
window.addEventListener('load',onld); 
+0

에 설명합니다. 0.8에서 1로 변경해보십시오. 그리고 이미지를 배경색과 병합하려면 투명해야합니다. – frnt

+0

@Kaiido가 말한 것과 같이 코드에 이것을 추가합니다. ctx.globalAlpha = 0.6; – frnt

2

ctx.globalCompositeOperation =

당신은 합성 방법을 사용하여 "곱"동적 범위를 잃지 않도록, 아래 RGBA 포맷 fillRect 할() 및 색상을 정의하는 의해 시도 대답은 frnt입니다. 0.6의 알파는 원래 마스크의 대비를 크게 줄입니다.

블렌딩 옵션이 많지만 이미지를 흰색으로 보이게하고 싶지 않고 어둠을 추가하고 싶다면 블렌드 모드 "곱하기"를 사용하십시오.이 방법을 사용하면 최상의 명암비를 얻을 수 있습니다.

ctx.fillStyle = ??? // the background colour you want 
ctx.fillRect(0, 0, ctx.canvas.width, ctx.canvas.height); // fill canvas with colour. This is now the destination 
// Destination pixels get multiplied by source pixels 
// nC = dC * (sC/255); (seperate for each channel RGB. no effect on alpha) 
// where nC is the new colour, dC is destination colour and, sC is source colour; 
// White pixels make no change, all others reduce the the colour 
ctx.globalCompositeOperation = "multiply"; 
// draw the image over the top. 
ctx.drawImage(img, 0, 0, canvas.width, cvtx.canvas.height); 
ctx.globalCompositeOperation = "source-over"; // reset to default 

최고 품질

이 더 좋은 방법이 있지만이 픽셀 데이터를 가져오고이 곱하기 전에 각 픽셀에 광자의 수를 일을 포함한다. 이렇게하면 원래 마스크에 더 가까운 일치를 얻을 수 있습니다. 수식은 nC =Math.sqrt(dC * dC * (sC * sC/(255*255)));입니다. 여기서 nC은 새 색이고 dC은 대상 색이며 sC은 원본 색입니다. 알파를 무시하고 각 채널 RGB에 적용합니다.

// r,g,b are the background colour 
// img is a loaded image to convert 
var r = ?, g = ?, b = ?; 
// create canvas and context for image 
var c = document.createElement("canvas"); 
c.width = img.width; 
c.height = img.height; 
var ctx = c.getContext("2d"); 
// draw image onto the canvas 
ctx.drawImage(img, 0,0); 
// get the pixel data 
var data = ctx.getImageData(0,0,c.width,c.height); 
var d = data.data; 
// Convert background colour to photon count and normalise 
r = r * r/(255 * 255); 
g = g * g/(255 * 255); 
b = b * b/(255 * 255); 
var i = 0, len = d.length;; 
// for each pixel do the multiply using photon counts 
while(i < len){ 
    d[i] = Math.sqrt(d[i] * d[i++] * r); 
    d[i] = Math.sqrt(d[i] * d[i++] * g); 
    d[i] = Math.sqrt(d[i] * d[i++] * b); 
    i ++; 
} 
// put the image data back onto the canvas. 
ctx.putImageData(data,0,0); 

알파 합성물을 통해.

알파 합성물을 사용해도 곱셈 효과가 아닐 수 있습니다. 간단한 방법과 광자 계산 방법 두 가지가 있습니다. 두 가지 방법은 배경색이 알파 값이 255라고 가정하고 그 값으로 을 사용한다고 가정하십시오.

간단한 방법으로 픽셀의 알파를 얻습니다. 알파 채널을 설정하고 캔버스 소스 오버 (기본) 혼합 기능을 사용한 경우 어떻게 수행됩니까?광자 카운트 색상 모델을 사용하는 이유 (가 고품질의 전문 믹싱을 수행하는 방법)

// assume you have got the pixel data etc.. see above snipets 
var amount = ?; // the mixing amount 
var i = 0, len = d.length;; 
// for each pixel do the alpha blend 
while(i < len){ 
    var rr = d[i]; // get source channels 
    var gg = d[i + 1]; 
    var bb = d[i + 2]; 
    var alpha = (rr + gg + bb)/(3 * 255); // calculate alpha by finding the mean 
    // alpha is inverted but also need to clamp alpha as floating point may give a value too high so clamp and invert 
    alpha = Math.min(1, 1 - alpha); 
    alpha *= amount; // set the mix amount 
    var aInv = 1 - alpha; // invert again 
    // each channel is the sum of background and image colour time their respective mix amounts 
    d[i++] = aInv * r + alpha * rr; 
    d[i++] = aInv * g + alpha * gg; 
    d[i++] = aInv * b + alpha * bb; 
    d[i++] = 255; // in this case alpha is always 255 
} 
// put the image data back onto the canvas. 
ctx.putImageData(data,0,0); 

그리고 올바른 방법

// assume you have got the pixel data etc.. see above snipets 
var amount = ?; // the mixing amount 
// Convert background colour to photon count and normalise 
r = r * r/(255 * 255); 
g = g * g/(255 * 255); 
b = b * b/(255 * 255); 
var i = 0, len = d.length;; 
// for each pixel do the alpha blend using photon counts 
while(i < len){ 
    var rr = d[i]; // get source channels 
    var gg = d[i + 1]; 
    var bb = d[i + 2]; 
    rr *= rr; 
    gg *= gg; 
    bb *= bb; 
    var alpha = (rr * + gg + bb)/(3 * 255 * 255); // calculate alpha by finding the mean in photon space 
    // alpha is inverted but also need to clamp alpha as floating point may give a value too high so clamp and invert 
    alpha = Math.min(1, 1 - alpha); 
    alpha *= amount; // set the mix amount 
    var aInv = 1 - alpha; // invert again 
    // each channel is the sum of background and image colour time their respective mix amounts 
    d[i++] = Math.sqrt(aInv * r + alpha * rr); 
    d[i++] = Math.sqrt(aInv * g + alpha * gg); 
    d[i++] = Math.sqrt(aInv * b + alpha * bb); 
    d[i++] = 255; // in this case alpha is always 255 
} 
// put the image data back onto the canvas. 
ctx.putImageData(data,0,0); 

.

내가 사용하는 색상 모델은 장치 디스플레이에서 방출되는 광자 수를 기반으로합니다. 각 색상 채널은 0에서 255까지의 값을 보유하지만이 값은 모니터의 실제 출력과 일치하지 않으며 카메라 (입력 장치)에서 캡처 한 광자 수를 나타내지 않습니다. 그것들은 광자 플럭스의 제곱근입니다. 간단한 선형 평균을 사용하여 색상을 혼합하고 이것을 고려하지 않으면 결과 색상이 어둡게 될 것입니다 (이미지의 색상이 높을 때 특히 현저합니다) 대비 곡선이 넓어집니다. 최상의 결과를 위해 픽셀을 직접 조작 할 때는 항상 r, g, b 값을 제곱하고 혼합, 블렌딩 등을 수행하십시오. 준비가되면 결과의 제곱근을 계산하여 값을 다시 로그 표현으로 변환하십시오.

이 동영상은 우리가 색상의 불투명도를 줄일 수 있도록, RGBA로 진수로 변환 된 밝은 빨간색 배경을 채우기 위해 fillRect 할을 사용한 오버 여기에 더 자세히 Computer Color is Broken

관련 문제