質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.40%
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

1回答

295閲覧

Canvasで複数の画像を描画しピクセル同士が重なったとき、alpha値が高い方を優先して描画したい

jow

総合スコア1

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

2クリップ

投稿2024/05/10 06:33

編集2024/05/10 09:02

実現したいこと

jsで透明度を持った画像を複数枚描画するとき、画像同士が重なることがあります。
このとき、何も設定せずにdrawImageで描画すると、alpha値は加算され、重なるほどにalpha値が大きくなっていってしまいます。
今回実現したいのは、このような「alpha値が加算されていくような描画」ではなく、「alpha値の高い方のみが描画されるような描画」になります。
なお今回使用される画像は単色で、alpha値で濃淡が表現されています。

↓今(重なったところがより濃くなってしまう)
イメージ説明

↓理想(重なっても滑らか)
イメージ説明

試したこと

getImageDataでImageDataを取得して、配列を直接書き換える方法を試しました。この方法なら一応実現できましたが、描画頻度が高く、画像サイズが大きいため、処理落ちは避けられません。他の方法がなければ、これをより効率化していく方向で実装しようと思いますが、それにも限界があると思い、できればCanvasの描画機能内で実現したいと思っています。

サンプルコード

全文を載せると膨大になるため主要な箇所だけを記載します

javascript

1const canvas = document.createElement('canvas'); 2const ctx = canvas.getContext('2d', {alpha: true, willReadFrequently: true}); 3function pointerMove (event) { 4 ctx.globalAlpha = event.pressure; // 筆圧から透明度を設定 5 ctx.drawImage(img, event.clientX, event.clientY); // 画像を描画 (画像自体も透明度をもつ) 6} 7document.addEventListener('pointermove', pointerMove);

上記のような処理で画像同士が重なると下レイヤーの画像の影響を受けます。
その結果、筆圧で設定した透明度と下レイヤーの透明度が合計された状態で描画されることになります。
今回実現したいのは、より高い透明度を持った方のみの描画になります。

拙い文章で申し訳ありませんが
ご助力、よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2024/05/10 07:47

とりあえず現在動作しているサンプルを例示ください
jow

2024/05/10 08:24

簡単なサンプルコードを追加しました
pecmm

2024/05/10 08:37

試したことないのであてずっぽうですが globalCompositeOperation=darken/lighten辺りで実現できたりしますかね。 (暗い/明るい方ってのはα関係なく輝度とかの話なんだろうか?)
jow

2024/05/10 08:43

現在触ってみている最中ですが、少なくともdarkenやlightenを単純に設定しただけでは難しそうです。 (globalCompositeOperationにおけるalphaの扱いがイマイチわからないですね…)
guest

回答1

0

こうするとどうでしょうか。重なっている部分をあらかじめ消す感じで。

js

1 ctx.globalCompositeOperation = "destination-out"; 2 ctx.globalAlpha = 1; 3 ctx.drawImage(img, event.clientX, event.clientY); 4 ctx.globalCompositeOperation = "source-over"; 5 ctx.globalAlpha = event.pressure; // 筆圧から透明度を設定 6 ctx.drawImage(img, event.clientX, event.clientY); // 画像を描画 (画像自体も透明度をもつ)

投稿2024/05/10 09:04

Lhankor_Mhy

総合スコア36601

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Lhankor_Mhy

2024/05/10 09:06

あー、テクスチャブラシなんですね。じゃあうまくいかないかもですね。
Lhankor_Mhy

2024/05/10 09:09

あー、単純な上書きではなくて、アルファ値の高い方を残すのですね……
jow

2024/05/11 02:51

回答ありがとうございます! 仰る通りで、単純な上書きではないので消すことも難しいんですよね…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.40%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問