人に聞けない痔の悩み、これでスッキリ >>

アルファ(透明値)をもつピクセル同士を重ねる方法についての質問です。

たとえば
前景RGBA=(255,0,255,0)
背景RGBA=(255,255,255,255)
のように背景が完全不透明であるなら

FR = (FR * FA + BR * (255 - FA)) / 255
(FRは前景のR値、BRは背景のR値、FAは前景のアルファ値)

のように単純な演算で合成後の画素値を算出できますが、

前景RGBA=(255,0,255,64)
背景RGBA=(255,255,255,128)

のように両方ともアルファ値を持つ画素同士であれば、どういったアルゴリズムで合成すればよいでしょうか。

ちなみにイメージする結果は、Photoshopなどのペイントツールで、完全透明レイヤーに半透明のブラシを色違いで重ねたような感じです。

このQ&Aに関連する最新のQ&A

A 回答 (1件)

>両方ともアルファ値を持つ画素同士であれば、どういったアルゴリズムで合成すればよいでしょうか。



アルゴリズム(計算式)は合成処理の用途などに応じて自由に決めていいものだと思います(つまりコレを使うべき、というものはないと思います)。例えばPhotoshopでも合成処理は何種類か用意されていてそれを選択できるようになっています。
1番単純なものでしたら
r=(r1*a + r2*(255-a)) / (2*255)
ような感じでいいのではないでしょうか?

この回答への補足

お教えいただいた演算方法だと背景部分の透過情報が無視されるため、いびつな画像になるようです。

参考:
http://blogimg.goo.ne.jp/user_image/72/74/ddd54d …

両方のアルファ値を考慮した計算方法はありますでしょうか

イメージしている演算例(参考):
http://blogimg.goo.ne.jp/user_image/67/78/27f9e4 …

補足日時:2005/03/28 18:15
    • good
    • 0

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aと関連する良く見られている質問

QOpenGLで描画するテクスチャのアルファ値(透明度)を変更したい

初めて質問させていただきます、tri-oと申します。

現在OpenGLでの2D描画プログラムを書いています。
ある画像を描画する時、その画像全体のアルファ値に、任意の値を乗算して、全体の透明度を変更したいのですが、やり方がわかりません。
例えば、キャラクターが書いてある画像があって、時間が経つ毎に透明度が変わり、徐々に出現するようなプログラムを書きたいのです。

色々と検索してみたのですが、目的のページにたどり着けませんでした。
ご存知の方いらっしゃいましたら、ご回答よろしくお願いします。

Aベストアンサー

まだ、OpenGLはあまりやってないので詳しいことは
分からないんですけど、

glBegin( );

//------この部分------//
glColor4f( );
または
glColor4fv( );
//------この部分------//

glEnd();

で、出来ると思います。
自分は、これで出来ました。

QOpenGL 画像のα値操作

こんにちは。
現在、授業の一環でGLUTを用いたOpenGLのプログラムを作っています。
そのプログラムの機能の中に、読み込んだ画像のα値を記憶した後、キー操作によって表示・非表示を切り替える機能を作ろうとしています。

目的の機能自体は一応途中まで(各ピクセルのα値を255⇔0への切り替え)は作れたのですが、原理がよく分かりません。
具体的に書くと、(幅)×(高さ)×(色のチャンネル数) の画像を読み込んだのに、4倍の高さの範囲までα値に関する処理を加えないと、処理後の効果が画像全体に現れないのです。

下にプログラムの断片を張るので、わかる方がいたら解説お願いします。
出来れば、後々のために理由を知っておきたいので。

-*-*-*-*-*-*-*-*-*-
/* テクスチャの情報を格納する構造体 */
typedef struct{
unsigned int name; /* 識別番号 */
unsigned char* data; /* 画像のデータ */
int width; /* 画像の幅 */
int height; /* 画像の高さ */
int channels; /* 画像の色成分の数 */
}texture;

/* テクスチャ(グローバル変数) */
texture a;


/* 画面表示用の関数 */
void display (void)
{
 /* 初期化 */
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

/* 透明色を描けるようにする */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

 /* 描画 */
glDrawPixels(a.width, a.height, GL_RGBA, GL_UNSIGNED_BYTE, a.data);


glutSwapBuffers ();
}

/* α値の操作(代入値がかわるだけなので、255にする方は省略) */
void alpham(void)
{
int i, j;

for (i = 0; i < a.height * 4; ++i) {
for (j = 0; j < (a.width); ++j) {
a.data[(a.width * i) + (a.channels * j) +3] = 0;
}
}

}

※画像データ の メモリ確保サイズ
a.data = (unsigned char*) malloc(width * height * channels)

こんにちは。
現在、授業の一環でGLUTを用いたOpenGLのプログラムを作っています。
そのプログラムの機能の中に、読み込んだ画像のα値を記憶した後、キー操作によって表示・非表示を切り替える機能を作ろうとしています。

目的の機能自体は一応途中まで(各ピクセルのα値を255⇔0への切り替え)は作れたのですが、原理がよく分かりません。
具体的に書くと、(幅)×(高さ)×(色のチャンネル数) の画像を読み込んだのに、4倍の高さの範囲までα値に関する処理を加えないと、処理後の効果が画像全体に現れないのです。

下...続きを読む

Aベストアンサー

> a.data[(a.width * i) + (a.channels * j) +3] = 0;

この部分の式の間違いですね。


data のバイトならびは、「ある画素のRGBA」「次の画素のRGBA」…
と、一画素あたり4(=channels)バイトずつ並んでいますので、
一行width画素のバイト数は、「(a.width * a.channels)バイト」になります。
ですから、y座標がiの時の左端のバイト位置は「(a.width * i)」ではなく「(a.width * a.channels * i)」になります。

Qリターンキー又は、スペースキーを使いたい。

まだまだ、初心者の自分なのですが、C++でプログラミングをしています。いま、単純に表示するだけのプログラムで、例えば、配列などに、数字が格納されている場合、リターンキーなどを押すごとに、順々に表示できるような処理を行いたいと思っています。ネットで検索してもなかなか合致するものがありません。リターンキー返す(?)関数見たいのはあったのですが、それだと、ずっと押されていることになっているみたいです。(たぶん)
いいかげんな質問かもしれませんが、キーボードのキーを使う方法を教えてください。お願いします。

Aベストアンサー

Visual C++ なら #include <conio.h> して、_getch() を呼ぶ。

# ドキュメントを読んでください

Q関数とメソッドの違い

初歩的な質問なのですが、
関数とメソッドの違いが分からず悩んでいます。
書籍や人によって、
関数とメソッドは同じ物として書いている物もあれば、
メソッドはクラスに関連付いた関数としていたり、
クラスでもpublic関数だけとか、
引数のある物がメソッド、
逆に無い物がメソッド等々…で、
どれが正しいのか良く分からないのです。

関数とメソッドの違いを教えていただけますよう、
お願いいたします。

Aベストアンサー

正解だけ先に言っておきましょう。オブジェクト指向での定義は
「メソッドとは、オブジェクトに送られてきたメッセージを処理するモノ」
「関数とは、メソッドの実装」
ついでに、
「メッセージとは、オブジェクトに何かしらお願いするために送られるモノ」
です。メッセージとメソッドと関数は明確に違うのですよ。


上記の通りなんですが、質問の文について、なにが正しいか、という解答は「文脈による」としか言いよ
うが無いんです。
解説書の一部分だけ抜き出して考えるのは非常に危険な行為です。
文脈を色々変えてみます。例えばオブジェクト指向の話をしているとしたら、

>1. 関数とメソッドは同じ物として書いている物もあれば、
バツ。意味的に全く異なります。
'\0'と""とNULLと0くらい違います。等価なんていってしまったら石が飛びます。(私が投げます:-p)

> 2.メソッドはクラスに関連付いた関数としていたり、
サンカク。C++での実装はそうでしょうが、オブジェクト指向を考える上で、その考え方は危険です。

> 3.クラスでもpublic関数だけとか、
> 引数のある物がメソッド、
> 逆に無い物がメソッド等々…で、
バツ。引数の数でメソッドで無くなる?そんなバカな!
例えprivateでもメソッドですよ。


オブジェクト指向言語C++のことを考えよう!という文脈ならば、
1.サンカク。実装は確かにそうなってます。ですが、上記の通り意味的に違うんです。
2.○。C++において、メソッドは「クラスに関連ついた関数」として実装されてます。
3.そんなわけないでしょう。

オブジェクト指向?なにそれ?構造体に関数がくっついただけでしょ?と乱暴極まりない文脈なら、
1.○。当然!
2.なにいってるの?
3.サブルーチンとファンクションの違いだ!


と、文脈で全然変わるんですよ。これに関しては、本一冊だけだとなかなか気付きにくいです。
是非とも多数の本を読み比べることをお勧めします。

正解だけ先に言っておきましょう。オブジェクト指向での定義は
「メソッドとは、オブジェクトに送られてきたメッセージを処理するモノ」
「関数とは、メソッドの実装」
ついでに、
「メッセージとは、オブジェクトに何かしらお願いするために送られるモノ」
です。メッセージとメソッドと関数は明確に違うのですよ。


上記の通りなんですが、質問の文について、なにが正しいか、という解答は「文脈による」としか言いよ
うが無いんです。
解説書の一部分だけ抜き出して考えるのは非常に危険な行為です...続きを読む

Q色混ぜのアルゴリズム

このジャンルでお願いします。

例えば絵の具などで黄色と青色を混ぜると緑色(またはそれに近い色)
になると思いますが、これをプログラムで再現しようとすると
(白色)rgb(255,225,255) = (黄色)rgb(255,225,0)+(青色)rgb(0,0,255)
になってしまいます・・・
どのような割合でrgbを調節すれば、理想とする結果が得られるのでしょうか?

Aベストアンサー

★アドバイス
・この質問は絵の具と同じ感じで色を混ぜ合わせるアルゴリズムですか?
 そう解釈しましたので『半透明処理』で調べればよいと思います。
 例:
 http://eternalwindows.jp/graphics/bitmap/bitmap11.html→『アルゴリズム』
 ここに色を混ぜ合わせる公式があります。→RGB方式
 抜粋すると
 『dest = src * (alpha / 255) + dest * (1 - (alpha / 255));』
 です。これは赤・緑・青の1つの成分であるため3つ処理します。
 詳しくは次のサイトなどを参考にして下さい。
 http://www.sm.rim.or.jp/~shishido/toumei.html→『パレットによる半透明処理』
 http://www13.plala.or.jp/kymats/study/MULTIMEDIA/bmp_semitransparent.html→『半透明処理』
 http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%AB%E3%83%95%E3%82%A1%E3%83%96%E3%83%AC%E3%83%B3%E3%83%87%E3%82%A3%E3%83%B3%E3%82%B0→『アルファブレンド』
・ネット検索するときは『半透明』または『半透明処理』とか、
 『アルファブレンド』『AlphaBlend』で調べます。
 API関数では
 http://msdn.microsoft.com/ja-jp/library/cc428300.aspx→『AlphaBlend』
 がります。

考え方:
『黄色』と『緑色』を1:1で混ぜるとき(RGB方式)

黄色=250,240,0(これを背景と考える)
緑色=0,230,0(こちらを前景と考える)
となり alpha=128(50%) とすると

赤輝度= 0 * (alpha / 255) + 250 * (1 - (alpha / 255))=124
緑輝度=230 * (alpha / 255) + 240 * (1 - (alpha / 255))=177
青輝度= 0 * (alpha / 255) + 0 * (1 - (alpha / 255))=0
となります。

よって『黄色』と『緑色』を1:1の比(50%)で混ぜ合わせると
赤輝度=124
緑輝度=177
青輝度=0

RGB=124,177,0
となります。

CYMも同じ考えて混ぜ合わせれば良いでしょう。

参考URL:http://eternalwindows.jp/graphics/bitmap/bitmap11.html

★アドバイス
・この質問は絵の具と同じ感じで色を混ぜ合わせるアルゴリズムですか?
 そう解釈しましたので『半透明処理』で調べればよいと思います。
 例:
 http://eternalwindows.jp/graphics/bitmap/bitmap11.html→『アルゴリズム』
 ここに色を混ぜ合わせる公式があります。→RGB方式
 抜粋すると
 『dest = src * (alpha / 255) + dest * (1 - (alpha / 255));』
 です。これは赤・緑・青の1つの成分であるため3つ処理します。
 詳しくは次のサイトなどを参考にして下さい。
 http://www...続きを読む

QC++/CLIで画像処理

お世話になります

VC 2010 C++/CLIで作成されている、既存プロジェクトに以下のグラフィック機能を追加したいのですが、
色々試しては挫折してます。
実現可能なライブラリを教えていただけないでしょうか。

【補足】
・既存プロジェクトはそれなりに大きなものなので、既存部の書き換えは考えておりません
・既存プロジェクトはPictureBoxで出来る範囲の色々な描画を行っているので、ここはそのまま残す予定

【追加機能】※ 以下は新規に子フォームを作成して、独立した機能として追加予定
1. 異なるサイズの画像(写真)を重ねて描画する(これは、単純なので標準の機能を始め全てで出来ます。)
2. 上面の画像を半透明にして、背景の写真を透過
(上面画像の背景を透過するのではなく、上面画像の全体を透過)
3. 上面の画像をマウスに追従して移動
4. 上面の画像の4点を個別にマウス指定で変形
5. 1~4で出来上がった画像の合成&出力

【試したもの】(理解ミスが有るかもしれません)
※事前検討で実現困難なライブラリも小細工できないかと、念のためそれぞれ試しております。
1. 標準の機能
・アドバイスをいただき、透過はできたのですが、4の変形ができない
(画像データを変形毎に計算して求めるのは非現実的なので適用していません・・変形後も移動が有る為)

2. OpenCV
・透過処理がアルファブレンドなので、3の処理が遅い
(理想はOpenGLの様にZバッファを使用して、背景が透過するもの・・・背景を意識しない処理のみで済むもの)
・透過処理がアルファブレンドなので、同サイズの画像か背景を上面と重なる部分を検出して切り出す必要がある
(上面の画像の変形を考えると、背景を上面に合わせて切り出すのは困難)
・4が矩形しか対応していないので、ひし形までしか変形できない
(視点の変更で形状こそ求めているものに近くなるが、今回の用途ではユーザーに単純操作で変形させてあげる必要がある)

3.OpenGL
・画像単体での読み書きができない
(テクスチャマッピング機能を用いるか他のライブラリを併用する必要がある)
・平面ポリゴンを定義して、テクスチャマッピングをした場合、4の変形時にマッピング画像が追従するようにする必要がある

4.DXLib
・追加機能に対応する機能を持ってはいるが、そもそもCLIに対応していない

5.GDI+
・CLI対応のサンプルが見つからない?
(CLI以外のサンプルは多々見かけるのですが、ウインドウのハンドルやポインタの使い方が異なり、苦戦中)
・そもそも、説明しているサイトが少ない
(私のような素人がみるとどれがGDI+の記述でどれが標準の機能なのか判らないものばかり
 せめてGDI+のXXXを使用すると以下のソースになるみたいな説明がされているサイトがが有れば教えてください)

6.Direct2D
※まだ検証してません

お世話になります

VC 2010 C++/CLIで作成されている、既存プロジェクトに以下のグラフィック機能を追加したいのですが、
色々試しては挫折してます。
実現可能なライブラリを教えていただけないでしょうか。

【補足】
・既存プロジェクトはそれなりに大きなものなので、既存部の書き換えは考えておりません
・既存プロジェクトはPictureBoxで出来る範囲の色々な描画を行っているので、ここはそのまま残す予定

【追加機能】※ 以下は新規に子フォームを作成して、独立した機能として追加予定
1. 異なるサイズ...続きを読む

Aベストアンサー

こんにちは。
全てを網羅的に知っている訳ではないので、どれが良いかなどには答えられませんが、コメントを。

【1. 標準機能】

> 画像データを変形毎に計算して求めるのは非現実的なので

どの様なライブラリ・APIを使ったとしても、(プログラマーが意識しなくても) 内部的には変形された画像データを計算している事には変わりありません。従って、画像データを変形の度に計算する事自体に関しては非現実的とは思いません。ただ、実際的な問題として、コーディングの手間と計算時間があるかと思います。標準機能の範囲内で実現するとしたら、コーディングの手間は惜しまないとしても、計算時間が問題として残りそうではあります。

しかし、実測していないので usami99 さんの目的の計算で、どれくらいの時間になるかは分かりません。もしかすると無視できるぐらい時間が短いかもしれませんし、或いは非現実的に遅いかもしれません。ところで、計算時間を評価する上で以下の事は確認した方が良いです:

「変形対象の画像サイズが大きすぎないか?」
画像サイズが実際の表示に用いている物よりも大きい場合には、画像サイズを表示する大きさに縮小してから表示するべきです。計算時間は画像の面積(∝長さの二乗)に比例しますので。

因みに OpenCV, OpenGL, DXLib, (それから、もしその様な機能が在れば Direct2D も) では、GPU の機能を呼び出して変形を計算していると思われるので、愚直に計算するよりは格段に速いと予想されます。

この方法を採用する場合に考慮するべきは
★コーディングの手間
★計算時間の評価 (過大評価しているかもしれないので、効率的な実装にしてから、実測)

【2. OpenCV】
使った事がないので分かりません。ただ、
> (視点の変更で形状こそ求めているものに近くなるが、
という事であれば、「どの様に視点を変更すれば目的の形になるか」を計算すれば良いのではないでしょうか。三次元の幾何学の計算(数式変形)が必要になると思いますが。

> ・透過処理がアルファブレンドなので、同サイズの…
何をしているのか良く分かりませんが、例えば、↓にある様な事をしようとしているという事でしょうか。
http://www3.pf-x.net/~chopper/home2/WinAPI/WinGDI21.html
それならば、上記URLに書いてあるように、変形した後の余白に対応するマスク画像を生成すれば良いのではないでしょうか。

★4点に対応する視点の計算方法が分かればする
★マスクは可能か?

【3. OpenGL】
余り使った事がないので分かりませんが…

> 4の変形時にマッピング画像が追従するようにする必要がある
勘違いしているかも知れませんが、テクスチャ(及びポリゴン上の UV 座標)はそのままで、平面ポリゴンの方を傾けるのでは駄目なのでしょうか。この場合も 4 点に対応するテクスチャの傾け方を考える必要がありますが。

★テクスチャの方を傾けるのは可能か?

【4. DXLib】
すみません分かりません。
DXLib は他の枠組と相互運用できない様に思われます。DXLib の上で UI を全て作り直すのであれば可能そうですが。

【5. GDI+】
他の方が回答されている様に C++/CLI との親和性は高いですが、4点を指定して画像を変形する機能は GDI+ にはないと思うのですが…(勘違いでしたら済みません)。

というのも、.NET Framework の System::Drawing は元々 Gdiplus のラッパーとして設計されているからです。従って、GDI+ と System::Drawing の親和性が高いのは、そもそも同一の物ですから当然です。そして、4点を指定して画像を変形する機能は GDI+ にないので、標準の機能 (.NET Framework System::Drawing) にもないのです。

> 同じ名称の物が有るたびに
> 一つ一つ、動作確認しながらクラスの定義をしなくてはならず、難儀しています。
> > 回答No.2 なにか言葉を湾曲して捉えられていませんか?
質問者さんは「System::Drawing::Graphics と Gdiplus::Graphics を混同している」とか「CLI からうまく使えない」とかいうのではなくて、例えば、「その辺りにある解説サイトに登場する Graphics オブジェクトが Systen::Drawing::Graphics の事なのか Gdiplus::Graphics の事なのか解説サイトに明記されていない(or分かりにくい)」事を嘆いていられるのですよね。お気持ち分かります。

★GDI+ は標準の機能とほぼ同等

【6. Direct2D】
これも知りませんが、Wikipedia によると GDI/GDI+ と相互運用できるとあるので、
System::Drawing::Graphics^ g の g->GetHdc() で得られる HDC に対して描画できるのではないでしょうか。
もしこれでできるのであれば、この方法が一番綺麗だと思われます。

サンプル (C++)
http://code.msdn.microsoft.com/windowsapps/Direct2D-perspective-7db78f51

--------

4点を指定して変換するという事が今回の鍵になると思うのですが、その辺りの経緯を分かり易くする為にも、過去の関連する質問へのリンクがあった方が良いかもしれません。
http://oshiete.goo.ne.jp/qa/8696755.html
http://oshiete.goo.ne.jp/qa/8679117.html
http://oshiete.goo.ne.jp/qa/8662361.html

こんにちは。
全てを網羅的に知っている訳ではないので、どれが良いかなどには答えられませんが、コメントを。

【1. 標準機能】

> 画像データを変形毎に計算して求めるのは非現実的なので

どの様なライブラリ・APIを使ったとしても、(プログラマーが意識しなくても) 内部的には変形された画像データを計算している事には変わりありません。従って、画像データを変形の度に計算する事自体に関しては非現実的とは思いません。ただ、実際的な問題として、コーディングの手間と計算時間があるかと思います。標準機...続きを読む


人気Q&Aランキング