描画されたキャンバス要素の要素の不透明度(アルファ、透明度)を変更する方法は?


196

HTML5の使用 <canvas>要素、画像ファイル(PNG、JPEGなど)をロードし、キャンバスに完全に透過的に描画してから、フェードインします。画像をロードして描画する方法を理解しました。キャンバスですが、一度描画されたときに不透明度を変更する方法がわかりません。

ここに私がこれまでに持っているコードがあります:

var canvas = document.getElementById('myCanvas');

if (canvas.getContext)
{
    var c           = canvas.getContext('2d');
    c.globalAlpha   = 0;

    var img     = new Image();
    img.onload  = function() {
        c.drawImage(img, 0, 0);
    }
    img.src     = 'image.jpg';
}

設定するプロパティや、不透明度を変更するために呼び出す関数など、誰かが私を正しい方向に向けてくれますか?

回答:


307

私はまた、この質問への回答を探しています(明確にするために、不透明度を使用して図形を描画する方法など、ユーザー定義の不透明度で画像を描画できるようにしたい)塗りつぶしとストロークを設定できるプリミティブシェイプで描画する場合透明度を定義するアルファ付きの色。私が現時点で結論付けている限り、これは画像の描画に影響を与えていないようです。

//works with shapes but not with images
ctx.fillStyle = "rgba(255, 255, 255, 0.5)";

私はglobalCompositeOperation画像を使った作品のセッティングと結論づけました。

//works with images
ctx.globalCompositeOperation = "lighter";

画像に色合いを付けて簡単に透明にできるように、色を設定する何らかの第3の方法があるのだろうか。

編集:

さらに掘り下げた後、画像globalAlphaを描画する前にパラメータを設定することで、画像の透明度を設定できると結論付けました。

//works with images
ctx.globalAlpha = 0.5

時間の経過とともにフェージング効果を実現したい場合は、アルファ値を変更する何らかのループが必要です。これはかなり簡単です。これを実現する1つの方法はsetTimeout関数です。ループを作成して、アルファを変更します。時間。


7
globalAlphaは完全に動作します。標準の一部です:whatwg.org/specs/web-apps/current-work/multipage/...
Aleris

42
正確にcanvasは、globalAlphaプロパティを持つ要素ではなく、キャンバスから取得するコンテキストです。
Steve Blackwell

8
ctx.save()およびctx.restore()に関する以下のIanのコメントは、globalAlphaがキャンバスの残りの部分に影響するのを防ぎます。
アロスボロ

1
キャンバスに描かれたものの不透明度を制御するのではなく、私には思えますが、それはより簡単で、画像が描かれた後(一度だけ)キャンバス全体の不透明度を制御するだけの目的に役立ちます。これを行うには、通常のCSS /スタイルメソッド(canvaselement.style.opacity = '0.3';など)を使用します。CSS3を使用すると、ループ全体を省略して、代わりにブラウザーにフェーディングを処理させることもできます(遷移のようなもの:NNNms)。不透明度イーズインアウト)、またはフェードを「アニメート」します。
チャックコラーズ2013年

1
残念ながら、canvas2d.fillStyle = "rgba(255, 255, 255, 0.5)";動作しません。値は16進数でなければなりません。
WebWanderer 2015

113

を使用するための簡単なコード例globalAlpha

ctx.save();
ctx.globalAlpha = 0.4;
ctx.drawImage(img, x, y);
ctx.restore();

imgロードする必要がある場合:

var img = new Image();
img.onload = function() {
    ctx.save();
    ctx.globalAlpha = 0.4;
    ctx.drawImage(img, x, y);
    ctx.restore()
};
img.src = "http://...";

ノート:

  • 'src'最後の値を設定してonload、画像がすでにキャッシュにある場合でも、すべてのプラットフォームでハンドラーが確実に呼び出されるようにします。

  • とのglobalAlpha間の変更をラップsaverestore(実際にはそれらをたくさん使用します)、特に描画コードのビットがイベントから呼び出される場合に、他の場所からの設定を変更しないようにします。


globalAlphaはキャンバス上のすべての画像または描画をぼかしますが、それはあなたが望むものではありません。
グランピー、2014年

6
@グランピー-いいえ、globalAlpha何もぼかしません。これは、すべてのアルファ設定されます、後続のコード例では、私はそれを包む理由は、図面(それはすでに描かれて何も変更しない)、saveそしてrestore、それが適用されるものを制限します。
イアン

ctx.restore()がglobalAlphaを復元するかどうかはわかりませんが、最後にこれを実行する必要がある場合もあります(少なくとも、以前のバージョンのChromeでは必要でした)ctx.globalAlpha = 1;
Sean

1
@Sean-わからない場合は確認してください。それは非常に古いChromeであったに違いなく、現在すべてのプラットフォームで動作しています:jsfiddle.net/y0z9h9m7
Ian

14

編集: 「正しい」とマークされた答えは正しくありません。

簡単です。このコードを試して、「ie.jpg」をお手持ちの写真に置き換えてください。

<!DOCTYPE HTML>
<html>
    <head>
        <script>
            var canvas;
            var context;
            var ga = 0.0;
            var timerId = 0;

            function init()
            {
                canvas = document.getElementById("myCanvas");
                context = canvas.getContext("2d");
                timerId = setInterval("fadeIn()", 100);
            }

            function fadeIn()
            {
                context.clearRect(0,0, canvas.width,canvas.height);
                context.globalAlpha = ga;
                var ie = new Image();
                ie.onload = function()
                {
                    context.drawImage(ie, 0, 0, 100, 100);
                };
                ie.src = "ie.jpg";

                ga = ga + 0.1;
                if (ga > 1.0)
                {
                    goingUp = false;
                    clearInterval(timerId);
                }
            }
        </script>
    </head>
    <body onload="init()">
        <canvas height="200" width="300" id="myCanvas"></canvas>
    </body>
</html>

重要なのは、globalAlphaプロパティです。

Win7上のIE 9、FF 5、Safari 5、およびChrome 12でテスト済み。


13

投稿はこれまでのところ古いので、私は私の提案に従っていきます。提案は、キャンバスの2Dコンテキストでのピクセル操作に基づいています。MDNから:

キャンバスのピクセルデータをバイトレベルで直接操作できます

ピクセルを操作するには、ここでgetImageDataとputImageDataの2つの関数を使用します。

getImageData関数の使用法:

var myImageData = context.getImageData(left、top、width、height);

そしてputImageData構文:

context.putImageData(myImageData、dx、dy); // dx、dy-キャンバス上のxおよびyオフセット

場所のコンテキストあなたのキャンバス2Dコンテキストです

したがって、赤、緑、青、およびアルファ値を取得するには、次のようにします。

var r = imageData.data[((x*(imageData.width*4)) + (y*4))];
var g = imageData.data[((x*(imageData.width*4)) + (y*4)) + 1];
var b = imageData.data[((x*(imageData.width*4)) + (y*4)) + 2];
var a = imageData.data[((x*(imageData.width*4)) + (y*4)) + 3];

ここで、xはxオフセット、yは yは、キャンバス上のオフセットであります

画像を半透明にするコードがあります

var canvas = document.getElementById('myCanvas');
var c = canvas.getContext('2d');
var img = new Image();
img.onload  = function() {
   c.drawImage(img, 0, 0);
   var ImageData = c.getImageData(0,0,img.width,img.height);
   for(var i=0;i<img.height;i++)
      for(var j=0;j<img.width;j++)
         ImageData.data[((i*(img.width*4)) + (j*4) + 3)] = 127;//opacity = 0.5 [0-255]
   c.putImageData(ImageData,0,0);//put image data back
}
img.src = 'image.jpg';

独自の「シェーダー」を作成できます-MDNの全記事はこちら


7

あなたはできる。デスティネーションアウトグローバルコンポジット操作を使用すると、透明なキャンバスをすばやくフェードできます。100%完璧ではありません。場合によっては痕跡が残ることもありますが、必要に応じて微調整することができます(つまり、「ソースオーバー」を使用して、0.13のアルファの白い色で塗りつぶし、フェードしてキャンバスを準備します)。

// Fill canvas using 'destination-out' and alpha at 0.05
ctx.globalCompositeOperation = 'destination-out';
ctx.fillStyle = "rgba(255, 255, 255, 0.05)";
ctx.beginPath();
ctx.fillRect(0, 0, width, height);
ctx.fill();
// Set the default mode.
ctx.globalCompositeOperation = 'source-over';

3

これは質問に最もよく答えると思います。実際に、すでに描かれているもののアルファ値を変更します。たぶん、この質問が出されたとき、これはAPIの一部ではありませんでした。

与えられた2Dコンテキストc

function reduceAlpha(x, y, w, h, dA) {
    var screenData = c.getImageData(x, y, w, h);
    for(let i = 3; i < screenData.data.length; i+=4){
    screenData.data[i] -= dA; //delta-Alpha
    }
    c.putImageData(screenData, x, y );
}

この回答は、7年前のSoul_manの回答とどのように異なるのですか?
BReddy

-2

あなたが使用している場合はjCanvasのライブラリをあなたが使用することができ、不透明度描画するときに、プロパティを。さらにフェード効果が必要な場合は、別の値で再描画してください。


-11

できません。即時モードのグラフィックです。しかし、不透明度のある背景色で長方形の上に長方形を描くことで、それをある程度シミュレートできます。

画像が一定の色以外のものの上にある場合、それはかなりトリッキーになります。この場合、ピクセル操作メソッドを使用できるはずです。画像を描画する前に領域を保存し、その後、不透明度を上にブレンドしてください。


5
これは正解ではありません。以下を
ライアンバドール

正解です。キャンバスに描画した要素のいずれかの不透明度を変更することはできませんが、キャンバス全体の不透明度を変更できます。それで十分な場合もあります。
MPG

2
MPG-あなたのコメント(5月11日)も間違っています。キャンバスの不透明度を変更できますが、それはOPが望んでいたことでも、上記の回答で示唆されていることでもありません。
イアン
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.