AlphaBlendをもちいて線を半透明に描画したいのですが、わかりません

[戻る]
TKO 2009/11/05(木) 17:50:07
    HDC hDC = NULL;
    HPEN hOldPen = NULL, hPen = NULL;
    hDC = GetDC(hWnd); 


hPen = CreatePen(PS_SOLID, 3, pen_color);
(HPEN)SelectObject(hDC, hPen);
            
            (HPEN)SelectObject(hTranseContext, hPen);

            MoveToEx(hTranseContext, MyPoint.OldPoint.x, 
MyPoint.OldPoint.y, NULL);
            LineTo(hTranseContext, MyPoint.NowPoint.x, 
MyPoint.NowPoint.y);

            //AlphaBlend( hDC, 0, 0, SizeX, SizeY, hTranseContext, 
0,    0, SizeX, SizeY, tBlendData );
            int abc;
            abc= BitBlt( hDC, 0, 0, SizeX, SizeY, hTranseContext, 0, 
0, SRCCOPY);

             SelectObject( hTranseContext, (HBRUSH)NULL);
hTranseContextのメモリハンドル上でLineToを用いて線を描画しそれをAlphaBlendを用いて
半透明に描画しようとしたのですが線がまったく描画されてないという状態です。

AlphaBlendがうまくいかないのでBitBltで描画しようと試みたのですがまったく描画できませんでした。

FlatWest 2009/11/05(木) 17:55:29
質問を質問で返します。

・HDC hTranseContext はどこでどうやって作成してますか?
・この関数自体はどのタイミングで実行してますか?

TKO 2009/11/05(木) 18:01:49
返答ありがとうございます
HDC   hTranseContext    = CreateCompatibleDC( hDC );
と宣言しています

FlatWest 2009/11/05(木) 18:10:52
では、hTranseContext上で線を描くためのキャンバスはどこで手にいれましたか?
( 作製した HBITMAP hBitmap との関連付けは?)

TKO 2009/11/05(木) 18:27:02
返答ありがとうございます

hdcというキャンパスにペンというオブジェクトで描画できると考えていました
現在
ペンをいうオブジェクトなっていたのをhTranseBitmapに変更し、

HBITMAP    hTranseBitmap    = ::CreateCompatibleBitmap( hDC, SizeX, SizeY );
    (HPEN)SelectObject(hTranseContext,  hTranseBitmap);

と変更したところ

ウインドが真黒になりました

FlatWest 2009/11/05(木) 18:59:34
入手したばかりのキャンバス (hBitmap) は全体が黒なので、
まずは FillRect 等を使ってキャンバスをあなた色に染め上げる
ことから始めます。線を描くのはそれからです。

そのうえで BitBlt し、確認ができたところで、違う描画方法にすればよろしいかと。

なお、HDC hDC へのBitBlt(なりAlphaBlend)は、WM_PAINTのメッセージハンドラ内
で処理します。(その他はご自由に)

蛇足ながら、入手したキャンバスは適切に廃棄物処理しましょう。:-)

TKO 2009/11/05(木) 19:10:48
丁寧にせつめいしてくだってありがとうごいます


違う描画方法にすればよろしいかと。
とのご指摘頂いたのですが

現在パワーポイントの下線描画を透明にするという
プログラムを作成しています

そこで
LineTo()関数で描画した線を
hTranseContextというメモリハンドルに保存して

AlphaBlend(hDC, 0, 0, SizeX, SizeY, hTranseContext, 0,    0, SizeX, SizeY, 
tBlendData )関数を用いて
元のスライドに半透明な線を描画することはできますか??

FlatWest 2009/11/05(木) 21:31:40
あなたが最終的にどんな結果を望んでいるのか、パワーポイントを使用した
経験のない僕には「パワーポイントの下線描画を透明にする」と仰られても、
申し訳ないが正直ピンとこない。

が、線下になる元の画像の色を考慮して線を引きたいということであれば、
PATINVERTなりDSTINVERTなりのオペレーションコードを使って
PatBltしてもいいのではないか、とも思う。

回答でなくてゴメンね。

TKO 2009/11/06(金) 01:16:44
ありがとうございます

PatBltやってみます

subaru 2009/11/06(金) 15:45:05
アルファ値を適用して半透明な線を引くこと自体は
GDI+のGraphics::DrawLineを使うと楽です。

ただ描画先がパワーポイントとなると
リアルタイムに書き換えできないだろうから
何をやろうとしているのかちょっと疑問ではあります。

TKO 2009/11/06(金) 16:52:44
subaruさん
返答ありがとうございます

Graphics::DrawLineはNET Frameworkクラスライブラリ
なのですが
どうやってNET Frameworkクラスライブラリを使えるように
設定したらよいのかわかりません

なにをインストールしてどうファイルをインクルードしたらいいかなど
よろしくおねがいします

subaru 2009/11/06(金) 17:14:19
.NET Framework版もありますが、
WindowsXP以降であればPlatform SDKのみで利用可能なので
何もインストールする必要はないです。

猫でもわかるプログラミングならこの辺とか。
http://homepage2.nifty.com/c_lang/sdk4/sdk_335.htm

TKO 2009/11/12(木) 16:27:59
回答ありがとうございます。

Graphics::DrawLineでアルファ値を設定して
線を描写しました

僕のプログラムはパワーポイントを起動して蛍光ペンのように
スライドの文字が見えるように透明な線を引きたいのですが

現在引いている線は

半透明にしているにもかかわらず赤い線がピンク色っぽくなるだけで
下のスライドが塗りつぶされてしまします

これはなにが原因だと考えられますか

よろしくお願いします

仲澤@失業者 2009/11/12(木) 18:03:08
パワーポイントを起動中に、その前面に「僕のプログラム」を
実行している状態なのでしょうか。それともアドイン?

前者なら「僕のプログラム」のウインドウ自体を半透明にして、
描画自体は透明でない普通の描画をする
という手もありますが、・・・・Paint.NETなんかが
やってるやつですけど。どうなんだろ。

subaru 2009/11/13(金) 10:47:43
例えば以下のようにデスクトップのHDCに対して
直接線を引くときちんと半透明になってくれます。
(エラー処理は省略しています)

#include <tchar.h>
#include <windows.h>
#include <gdiplus.h>

#pragma comment(lib, "gdiplus.lib")

using namespace Gdiplus;

int _tmain()
{
    ULONG_PTR token;
    GdiplusStartupInput input;
    Gdiplus::GdiplusStartup(&token, &input, NULL);
    HDC hdc = GetDC(NULL);
    {
        Pen pen(Color(128, 255, 0, 0), 20);
        Graphics g(hdc);
        g.DrawLine(&pen, 0, 0, 100, 100);
    }
    ReleaseDC(NULL, hdc);
    GdiplusShutdown(token);
    return 0;
}

>半透明にしているにもかかわらず赤い線がピンク色っぽくなるだけで
>下のスライドが塗りつぶされてしまします
>
>これはなにが原因だと考えられますか

どのようなコードを書いてそうなるのかわかりませんが
最初のコードのようにダブルバッファリングしているのでしょうか?
そうであれば、メモリDCに対して一旦デスクトップの内容を取り込んでやらないと
アルファブレンドできません。

ちなみに描画内容は一時的なものですぐに壊れてしまうので
仲澤さんの方法がましだと思いますが、複雑な図形を書く場合は
リージョンの作成が面倒になります。

TKO 2009/11/16(月) 14:59:31
返信ほんとうにありがとうございます

パワーポイント上に透明な線を引くことはできました。

しかし

マウスで線を引くとリアルタイムで透明な線が描画されるのですが
タブレットで線を引くと遅れて線が表示されます

これはDRAWLINEがタブレットの場合では計算処理に時間がかかるからでしょうか??


cretepenを用いてMoveToExと    LineTo関数を使ってタブレットで線を引く場合は
線はリアルタイムに表示されます



それとも
プログラムを書き換えることによって
リアルタイムに線を描画することができますか??

TKO 2009/11/16(月) 17:12:10
たびたびすいません
DRAWLINE関数は描画速度おそいですか??

PATIO 2009/11/16(月) 17:36:32
えーと。

一般的に余計ない仕事をさせれば、遅くなる道理なので
単なるGDIとGDI+を比べたらmGDI+の方が遅いと思いますよ。
まあ、ハードウエアアクセラレータが利いているのかとか
色々な要素があると思うので一概には言えないかもしれませんが。

実際に御自分の環境で試して見てそうなるのであれば、
その環境ではそうなんでしょうとしか言えません。
ハードの環境によっては変わってくるかもしれませんけれど、
その環境で動かさない限り確かめようが有りません。

で、既に単純にGDI+を使っただけのプログラムで出来る事の範疇は
超えていると思うので高速化を考えるのであれば、
GDI+を使ったグラフィック描画に関する専門書等で勉強するとか
しないと無理なんじゃないかと思います。
ある程度、専門的な知識も要求されてくると思うので。

PATIO 2009/11/16(月) 17:38:43
あうあう。

わかると思いますが、

一般的に余計な仕事をさせれば、遅くなる道理なので
単なるGDIとGDI+を比べたらGDI+の方が遅いと思いますよ。

が正しいです。

subaru 2009/11/16(月) 21:39:50
GDI+の方が多機能で扱いやすい分、GDIに比べて遅くなってるものが多いだろうし、
アルファ値なしでの描画よりアルファブレンドを適用した処理の方が
かなり重いだろうとは想像します。

とはいえ、そこまで劇的に重くなるもんですかね?
どのような環境でどのようなプログラムを実行しているのかわからないので
プログラム的に問題がないと言えるかどうかはわかりません。

ryo 2009/11/17(火) 01:30:34
いくつか気になる点
1:使用してるマウスとタブレットで入力速度はどのくらい差があるか
(タブレットのほうが反応がよすぎて描画が遅れるほど処理回数が発生してるのではな
いか?)
2:透明描画のときと、createpenで書いたときと、それ以外に処理方法に差はないか?


あと、おまけ
・ダブルバッファなどしてる場合、画面・クライアント領域全体よりも、
2点間を引いた線が入る領域だけを抜いて処理したほうが無駄が少なく早いです
位置計算しないといけないのが面倒だが、全体をコピーするよりゃはるかに早い

仲澤@失業者 2009/11/17(火) 16:49:22
大昔にWinTabとWindows Tablet PC Editionを使用した経験で言うと
マウスに比べて、タブレットの方がストローク内の点の数が多いです。
これが原因で描画が遅くなる場合が考えられます。
回避するには、ストローク入力中の描画(リアルタイム描画)では
点数をある程度おろぬいて描画し、ストロークが完了したら、全点での
再描画を行うという方法があります。

TKO 2009/11/18(水) 00:21:11
みなさん返信ありがとうございました

仲澤@失業者 さんの回答非常に参考になりましたありがとうございます

TKO 2009/11/18(水) 00:21:42
[[解決]]
ありがとうございました

subaru 2009/11/18(水) 10:56:14
既に本題とは関係ないところですが一つ訂正。

>subaru 2009/11/13(金) 10:47:43
>ちなみに描画内容は一時的なものですぐに壊れてしまうので
>仲澤さんの方法がましだと思いますが、複雑な図形を書く場合は
>リージョンの作成が面倒になります。

SetLayeredWindowAttributes関数の第4引数を
組み合わせて使えることを知りませんでした。
描画内容から半透明ウインドウを作る方法では
(複雑な)リージョンの作成は必要なかったみたいですm(_ _)m

古いスレッドには追加発言できません。