2016-06-19 7 views
2

キャンバスに背景色を付け、その上にPNGを重ねようとしています。背景色で塗りつぶしてからPNGをオーバーレイします。

これはPNGテクスチャである:backgroundColor = #D95753(明るい赤)たとえば

enter image description here

、レベルを充填キャンバスは次のようになります背景色を設定

1.- PNのオーバーレイ

enter image description here

2.-私が持っているコードだが、それが動作していない背景色

enter image description here

上記グラム。背景色は表示されず、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); 

アルファコンポジットを使用することもできますが、乗算は効果ではない可能性があります。シンプルとフォトン数の2つの方法があります。 注:2つの方法は、背景色のアルファ値が255であると仮定し、その値に対してONLYを使用します。

ピクセルのアルファを簡単に取得します。アルファチャンネルが設定され、キャンバスのソースオーバー(デフォルト)ブレンディング機能を使用しただけの場合はどのように処理されますか。フォトンカウントカラーモデルを使用する理由(それは高品質のプロフェッショナルに混合するためにどのように行われるか)

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

関連する問題