HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2012
0702
とりちゃそWindow外のpgetがしたい22解決


とりちゃそ

リンク

2012/7/2(Mon) 21:58:45|NO.47467

1ドットのRGBを返すPGet命令、HSPのウィンドウ外は取得できないみたいなのですが、
ウィンドウ外でも可能な命令はありますか?



この記事に返信する


fortunehill

リンク

2012/7/3(Tue) 00:39:27|NO.47468

/*デバイスコンテキストを取得すれば出来ます(下記はデスクトップ)*/

#include "gdi32.as" #include "user32.as" #define global ctype _Urgb(%1=0,%2=0) (%1 >> %2*8 & $FF) GetDC 0 :hh = stat GetPixel hh,100,100 :cc = stat color _Urgb(cc,0),_Urgb(cc,1),_Urgb(cc,2) boxf ReleaseDC 0,hh



とりちゃそ

リンク

2012/7/3(Tue) 06:30:05|NO.47469

ほうほう…

ちょっと勉強してきます^^;



だいちょ

リンク

2012/7/3(Tue) 17:44:26|NO.47470

fortunehillさんも使っていたように、gdi32を使えばできます。


#include "gdi32.as" #include "user32.as" repeat GetDC 0: dc=stat GetPixel dc, ginfo_mx , ginfo_my: col = stat cls pos 0, 0 mes col & 255 //R(赤) mes col >> 16 //B(青) mes col >> 8 & 255 //G(緑) wait loop ReleaseDC 0, dc

こんな感じで出来ます。
とりあえず難しいことは無視して、色を調べる最初に

GetDC 0: dc=stat GetPixel dc, ginfo_mx , ginfo_my: col = stat
と記述して、
col & 255
はR(赤)、
col >> 16
はB(青)、
col >> 8 & 255
はG(緑)ってやって、最後に
	ReleaseDC 0, dc
とやっておけばなんとかなります(笑)
こんな感じに使うときは、
if (col >> 8 & 255): stop
みたいな感じで()で囲んでくださいね。
がんばってくださいね^^



とりちゃそ

リンク

2012/7/3(Tue) 22:08:35|NO.47474

へぇ…!!
結構短く簡単に記述出来るんですね!!

今私情で忙しいので、後々報告させていただきます!



MillkeyWeler

リンク

2012/7/4(Wed) 01:50:25|NO.47479

だいちょさんのスクリプトの一部に、デバイスコンテキストを無限に増やしてしまうバグがある為
指摘させていただきます。


#include "gdi32.as" #include "user32.as" repeat GetDC 0: dc=stat ; ←Repeat 内で、GetDC を複数回取得しようとしている。


GetDC 0: dc=stat

ですが、記載内容だと、GetDC を複数取得し、OSのリソースを使いすぎる問題があるので、repeat 内で使用する際は、
GetDC と ReleaseDC とセットで使用してください。

また、一画面上で、複数GetPixel を使う場合は、repeat 前に GetDC をして、repeat を抜けた先で、ReleaseDC を使用する事もできます。



だいちょ

リンク

2012/7/4(Wed) 07:17:01|NO.47481

>MillkeyWelerさん
ご指摘ありがとうございます。
やっぱりまだまだ勉強不足ですね^^;
大変失礼しました。



とりちゃそ

リンク

2012/7/4(Wed) 22:11:32|NO.47495

いやー、高レベル過ぎてわけわかめです^^;

それに比べ自分はまともな返信出来ず…スミマセン。


もう少ししてリアルが落ち着いたらプログラム組んでみます。
みなさんありがとうございます!



とりちゃそ

リンク

2012/7/10(Tue) 21:09:34|NO.47595

やっと時間が出来たので5時間ほどカチャカチャ組んだのですが、
どうも色がおかしいです(笑)
全体にピンクがかかっているというか・・
確かに無理な処理を加えていますが(笑)


#include "gdi32.as" #include "user32.as" Screen 0,220,40,0,,,,, GSel 0,2 Dim ColorR : Dim ColorG : Dim ColorB : ColorR=0 : ColorG=0 : ColorB=0 Dim Field,4 Repeat 4,0 Field(Cnt)==0 Loop Dim Key,28 Repeat 27,1 Key(Cnt)=0 Loop Dim a SDim TitleMes TitleMes="" Dim Step Step=1 While Repeat 27,1 GetKey a,Cnt If(Key(Cnt)==-1) : Key(Cnt)=0 If(a==1) : Key(Cnt)++ : Else : Key(Cnt)=-1 Loop If(Key(17)==1) { Step=1 ColorR=0 : ColorG=0 : ColorB=0 Repeat 4,0 Field(Cnt)==0 Loop } If(Key(27)==1) { If(Step==1){ Field(0)=GInfo_MX Field(1)=GInfo_MY Step=2 }Else{If(Step==2){ If(GInfo_MX!=Field(0))&(GInfo_MY!=Field(1)){ Field(2)=GInfo_MX Field(3)=GInfo_MY Step=3 } } Else{If(Step==3){ Screen 0,ABS(Field(0)-Field(2)),ABS(Field(1)-Field(3)),0,GInfo_WX1,ginfo_WY1,,, Title "Field:("+Field(0)+","+Field(1)+")~("+Field(2)+","+Field(3)+")"+TitleMes Color 1,1,1 : BoxF Repeat ABS(Field(0)-Field(2))*ABS(Field(1)-Field(3)),0 GetDC 0 DC=Stat GetPixel DC,Field(0)+Cnt\ABS(Field(0)-Field(2)),Field(1)+Cnt/ABS(Field(0)-Field(2)) ColorR=Stat&255 : ColorG=Stat>>16 : ColorB=Stat>>8&255 Color ColorR,ColorG,ColorB PSet Cnt\ABS(Field(0)-Field(2)),Cnt/ABS(Field(0)-Field(2)) ReleaseDC 0,DC Loop Step=4 } Else{If(Step==4){ DiaLog "bmp",17,"どこに保存しますか?" BMPSave refstr ColorR=0 : ColorG=0 : ColorB=0 Repeat 4,0 Field(Cnt)==0 Loop Screen 0,220,40,0,,,,, Step=1 }}}} } Title "Field:("+Field(0)+","+Field(1)+")~("+Field(2)+","+Field(3)+")" ReDraw 1 Wait 10 ReDraw 0 Wend

汚くてホントすみません。
せっかく頂いたコードぐちゃぐちゃにしてすみません。

あと、Windows2000のほうだとさらーっとキャプチャしてくれるのですが、
Windows7のほうになると尋常じゃないくらい重くなります(笑)
処理はWindows7のほうが圧倒的に速いはずなんですが・・


欲を言うとGetDC、ReleaseDCらへんの意味を教えて頂ければ幸いです。



とりちゃそ

リンク

2012/7/10(Tue) 21:12:17|NO.47596

あ、Escキーを使って範囲を決めれるスクリーンショットを撮るソフトを組んでみました((言い忘れてましたw



とりちゃそ

リンク

2012/7/10(Tue) 21:57:08|NO.47597

ただでさえ汚いんだからコメントくらいつけるべきでしたね^^;

あと、実は「>>」や「&」の意味もよく分かってません。・゜・(ノД`)・゜・。
>>はビットシフトだとはC言語をかじった時にやったのですが理解出来ませんでした…。
&は論理和、だそうですね^^;
論理和といったら条件式と論理和回路しか思い浮かびませぬ…
数式に含まれるとなるとどうなるのか…
色々試したのですがさっぱりな値が返されてしまいますorz

この意味不明な中学生に教えてあげるような心優しい物好き様はいらっしゃいませんか…?



連続投稿お邪魔しました。



だいちょ

リンク

2012/7/10(Tue) 22:40:03|NO.47599

すいません。
僕がR→B→Gの順番で教えてしまったのでおかしくなっていますね。
52行目を
ColorR=Stat&255 : ColorG=Stat>>8&255 : ColorB=Stat>>16

にしてみてください。 DCは、デバイスコンテキストの略称で、ディスプレイなどのハード機器を仮想化します。 要するに、ハード機器ですることをソフトでするってことです。 だから、これを使って、デスクトップに描画することも出来るということです。 僕も100%理解しているわけではないので、あまり詳しくありません^^; 詳しくは「デバイスコンテキストとは」などで検索をかけてみてください。 http://programer.seesaa.net/article/1187170.html ここが一番わかやすいです。 「>>」や「&」は、「演算子」とか「C言語演算子」などで検索すれば出てきます。 シフト演算子と言って少し難しいかもしれませんが、頑張ってください。



とりちゃそ

リンク

2012/7/10(Tue) 22:51:38|NO.47600

M>>N

M×(1/(2^N))
という感じですかね!?

なるほどRGB値がごっちゃになってましたか^^;
よく見直せば分かったのに…すみません。



あとは

Repeat ABS(Field(0)-Field(2))*ABS(Field(1)-Field(3)),0 GetDC 0 DC=Stat GetPixel DC,Field(0)+Cnt\ABS(Field(0)-Field(2)),Field(1)+Cnt/ABS(Field(0)-Field(2)) ColorR=Stat&255 : ColorG=Stat>>16 : ColorB=Stat>>8&255 Color ColorR,ColorG,ColorB PSet Cnt\ABS(Field(0)-Field(2)),Cnt/ABS(Field(0)-Field(2)) ReleaseDC 0,DC Loop
が悪さしているであろう処理の重さをどうにかしなくては…。
まあ重くなるのは見りゃ分かるんですが、なぜ2000と7でこんなにも違うのか…。
もうちょっと調べてみます。



ああ、あとデバイスコンテキスト、か…。
まだまだ勉強が必要ですねorz

分かりやすい説明どうもありがとうございました!



MillkeyWeler

リンク

2012/7/10(Tue) 23:17:51|NO.47601

ヒント

Repeat ABS(Field(0)-Field(2))*ABS(Field(1)-Field(3)),0 GetDC 0 DC=Stat GetPixel DC,Field(0)+Cnt\ABS(Field(0)-Field(2)),Field(1)+Cnt/ABS(Field(0)-Field(2)) ColorR=Stat&255 : ColorG=Stat>>16 : ColorB=Stat>>8&255 Color ColorR,ColorG,ColorB PSet Cnt\ABS(Field(0)-Field(2)),Cnt/ABS(Field(0)-Field(2)) ReleaseDC 0,DC Loop
の部分を

GetDC 0 DC=Stat Repeat ABS(Field(0)-Field(2))*ABS(Field(1)-Field(3)),0 GetPixel DC,Field(0)+Cnt\ABS(Field(0)-Field(2)),Field(1)+Cnt/ABS(Field(0)-Field(2)) ColorR=Stat&255 : ColorG=Stat>>16 : ColorB=Stat>>8&255 Color ColorR,ColorG,ColorB PSet Cnt\ABS(Field(0)-Field(2)),Cnt/ABS(Field(0)-Field(2)) Loop ReleaseDC 0,DC
にかえてみて。たぶん処理速度は大幅に上がると思うから。



fortunehill

リンク

2012/7/10(Tue) 23:18:25|NO.47602

/*キャプチャが目的なら他の方法もあります*/

#include "gdi32.as" #include "user32.as" GetDC 0 :hh = stat BitBlt hdc,0,0,640,480,hh,640,480,$00CC0020 redraw ReleaseDC 0,hh



MillkeyWeler

リンク

2012/7/10(Tue) 23:55:52|NO.47603

即席でキャプチャ目的のスクリプトを作ってみた。

#include "user32.as" #include "gdi32.as" screen 0,300,100,0 : title "範囲スクリーンキャプチャ" onexit *p_end font "MSゴシック",12,0 pos 5,5 : mes "マウスで取得したい開始地点(X,Y)へ動かし\nESC キーを押してください。" repeat await 10 stick ki,,0 if ki=128 : break loop px=ginfo_mx : py=ginfo_my color 255,255,255 : boxf : color 0,0,0 pos 5,5 : mes "マウスで取得したい終了地点(X,Y)へ動かし\nESC キーを押してください。" repeat await 10 stick ki,,0 if ki=128 : break loop ex=ginfo_mx : ey=ginfo_my if px>ex : tx=ex : ex=px : px=tx if py>ey : ty=ey : ey=py : py=ty sx=ex-px+1 sy=ey-py+1 //screen shot gsel 0,-1 await 100 GetDC 0 : DC=stat if DC=0 : dialog "DC ERROR" : end buffer 4,sx,sy,0 : buffer_hdc=hdc bitblt buffer_hdc,0,0,sx,sy,DC,px,py,0xCC0020 ReleaseDC 0,DC gsel 0,1 color 255,255,255 : boxf : color 0,0,0 pos 5,5 : mes "BMP 保存です。" gsel 4 DiaLog "bmp",17,"どこに保存しますか?" if stat=0 : mes "キャンセルされました。" : stop BMPSave refstr stop *p_end ReleaseDC 0,DC end

参考にどうぞ^^



とりちゃそ

リンク

2012/7/11(Wed) 08:37:27|NO.47604

MillkeyWelerさん
指示通りにやってみましたところ、
確かに速くなったのですがそれでも遅いんです・・

ですので、fortunehillさんに紹介されたBitBlt命令を見よう見まねで使ってみたところ見事に

・・・動かなくなりました。



#include "gdi32.as"
#include "user32.as" Screen 0,220,40,0,,,,, GSel 0,2 Dim ColorR : Dim ColorG : Dim ColorB : ColorR=0 : ColorG=0 : ColorB=0 Dim Field,4 Repeat 4,0 Field(Cnt)==0 Loop Dim Key,28 Repeat 27,1 Key(Cnt)=0 Loop Dim a SDim TitleMes TitleMes="" Dim Step Step=1 While Repeat 27,1 GetKey a,Cnt If(Key(Cnt)==-1) : Key(Cnt)=0 If(a==1) : Key(Cnt)++ : Else : Key(Cnt)=-1 Loop If(Key(17)==1) { Step=1 ColorR=0 : ColorG=0 : ColorB=0 Repeat 4,0 Field(Cnt)==0 Loop } If(Key(27)==1) { If(Step==1){ Field(0)=GInfo_MX Field(1)=GInfo_MY Step=2 }Else{If(Step==2){ If(GInfo_MX!=Field(0))&(GInfo_MY!=Field(1)){ Field(2)=GInfo_MX Field(3)=GInfo_MY Step=3 } } Else{If(Step==3){ Screen 0,ABS(Field(0)-Field(2)),ABS(Field(1)-Field(3)),0,GInfo_WX1,ginfo_WY1,,, Title "Field:("+Field(0)+","+Field(1)+")~("+Field(2)+","+Field(3)+")"+TitleMes Color 1,255,1 : BoxF GetDC 0 DC=Stat;よくわかんないけど入れてみた HH=Stat;よくわかんないけど入れてみた BitBlt buffer_hdc,0,0,ABS(Field(0)-Field(2)),ABS(Field(1)-Field(3)),DC,Field(0),Field(1),BLACKNESS ReleaseDC 0,DC Step=4 } Else{If(Step==4){ DiaLog "bmp",17,"どこに保存しますか?" BMPSave refstr ColorR=0 : ColorG=0 : ColorB=0 Repeat 4,0 Field(Cnt)==0 Loop Screen 0,220,40,0,,,,, Step=1 }}}} } Title "Field:("+Field(0)+","+Field(1)+")~("+Field(2)+","+Field(3)+")" ReDraw 1 Wait 10 ReDraw 0 Wend

BitBlt よく分かんない,コピー先の左上X,コピー先の左上Y,コピー先左上からの距離X,コピー先左上からの距離Y,よく分かんない,コピー元左上X,コピー元左上Y,よく分かんない

みたいな感じですか?^^; 出来る限りMillkeyWelerさんのソースまんま写さず、自分のソースでなんとかやってみたいです((わがまま乙



check

リンク

2012/7/11(Wed) 10:13:39|NO.47605

WindowsAPIの知識がないのであれば今はどうにかしのげても、
また躓いたりして結局分けがわからなくなると思う。

もう俺はこの規模のスクリプトを読んでデバッグする気にはならないが、
BitBltの最後のパラメータにBLACKNESSとしているみたいだが、
HSPではその定数は定義されていないから自分で引っ張ってくるしかないぞ。
そしてそこにはSRCCPYを指定するのが普通だ。
(SRCCPYは対象と成るDCからそっくりコピーするオプション)



check

リンク

2012/7/11(Wed) 10:27:20|NO.47606

そしてBitBltしかり他のWinAPIがよくわからないのならMSDNのヘルプや
その他のサイトのWinAPI講座を見て使い方を把握しろよ。

>fortunehillさんに紹介されたBitBlt命令を見よう見まねで使ってみたところ見事に
>・・・動かなくなりました。
まず見よう見まねでWinAPIの関数を使おうとしている時点で間違っているだろ。
少しは自分から調べることもしろよ。
わからないのによくパラメータをいじる気になったなぁ。

>確かに速くなったのですがそれでも遅いんです
NO.47603のMilky Weler氏のスクリプトは実行速度がかなり速いが。
もしかしてその前のGetPixelを使っているスクリプトの話か?
それは遅いさ。
GetPixelで広範囲の色情報を取得することは想定されていないから。
HSPのpgetの中身は実質GetPixelだろうよ。



とりちゃそ

リンク

2012/7/11(Wed) 10:54:27|NO.47607

はい、
もっと勉強してから再登場させて頂きます^^;



MillkeyWeler

リンク

2012/7/11(Wed) 13:12:25|NO.47608

とりあえず、もう一度ヒントだけ。
自身でpget(GetPixel)を大量に扱うなら、一旦、Bitblt にて、HSPの buffer スクリーンにコピーし
そこから、VRAM領域を参照すればいい。

check さんの言いたい事は、これだと思うよ?
WinAPI を使えば、呼び出すのだけで、時間がかかるのを理解しよう。
(ボトルネックという意味)

check さんの言い方は、ちょっと怖いけど、気にするな。
WinAPI は、利用は便利だけど、使い方を間違えると、OSを破壊する凶器にもなるから。
(それを心配して言ってると思うよ^^;)



MillkeyWeler

リンク

2012/7/11(Wed) 13:40:40|NO.47609

とりあえず、変更版。

Else{If(Step==3){ Screen 0,ABS(Field(0)-Field(2)),ABS(Field(1)-Field(3)),0,GInfo_WX1,ginfo_WY1,,, : buffer_hdc=HDC ;←ここのHDC が青くなっているのに気づいて! Title "Field:("+Field(0)+","+Field(1)+")~("+Field(2)+","+Field(3)+")"+TitleMes Color 1,255,1 : BoxF GetDC 0 DC=Stat ;←で GetDC の戻り値が Stat に代入されている為、それを DC 変数にコピーしてるのよ。 //下のbuffer_HDC ってのは、HSP ウィンドウの DC 領域ってことだ。これも検索すれば出てくる。用語「API HDC」 BitBlt buffer_hdc,0,0,ABS(Field(0)-Field(2)),ABS(Field(1)-Field(3)),DC,Field(0),Field(1),0xCC0020 ;0xCC0020 は SCRCOPY(画素処理しないコピーって意味) ReleaseDC 0,DC ;←自分で作った、DC領域を開放って意味。 Step=4 }
惜しいって言っていいのか、悪いのか。
HSP に直接 API 定数を入力しちゃってるのとか、buffer_hdc をなにも代入せずにAPI に渡しちゃってるのとか。
たぶんこれで大丈夫だとは思うけど。



とりちゃそ

リンク

2012/7/12(Thu) 06:25:14|NO.47619

WinAPIですか…

なんのことかサッパリ…((ダメダメですね



一応ソースは完成したので解決済みとさせて頂きます。

もっと勉強して出直します。みなさん本当にありがとうございました!



ONION software Copyright 1997-2021(c) All rights reserved.