|
|
2012/7/2(Mon) 21:58:45|NO.47467
1ドットのRGBを返すPGet命令、HSPのウィンドウ外は取得できないみたいなのですが、
ウィンドウ外でも可能な命令はありますか?
|
|
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
へぇ…!!
結構短く簡単に記述出来るんですね!!
今私情で忙しいので、後々報告させていただきます!
|
|
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
分かりやすい説明どうもありがとうございました!
|
|
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
にかえてみて。たぶん処理速度は大幅に上がると思うから。
|
|
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
|
|
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さんのソースまんま写さず、自分のソースでなんとかやってみたいです((わがまま乙
| |
|
2012/7/11(Wed) 10:13:39|NO.47605
WindowsAPIの知識がないのであれば今はどうにかしのげても、
また躓いたりして結局分けがわからなくなると思う。
もう俺はこの規模のスクリプトを読んでデバッグする気にはならないが、
BitBltの最後のパラメータにBLACKNESSとしているみたいだが、
HSPではその定数は定義されていないから自分で引っ張ってくるしかないぞ。
そしてそこにはSRCCPYを指定するのが普通だ。
(SRCCPYは対象と成るDCからそっくりコピーするオプション)
|
|
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
はい、
もっと勉強してから再登場させて頂きます^^;
|
|
2012/7/11(Wed) 13:12:25|NO.47608
とりあえず、もう一度ヒントだけ。
自身でpget(GetPixel)を大量に扱うなら、一旦、Bitblt にて、HSPの buffer スクリーンにコピーし
そこから、VRAM領域を参照すればいい。
check さんの言いたい事は、これだと思うよ?
WinAPI を使えば、呼び出すのだけで、時間がかかるのを理解しよう。
(ボトルネックという意味)
check さんの言い方は、ちょっと怖いけど、気にするな。
WinAPI は、利用は便利だけど、使い方を間違えると、OSを破壊する凶器にもなるから。
(それを心配して言ってると思うよ^^;)
|
|
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ですか…
なんのことかサッパリ…((ダメダメですね
一応ソースは完成したので解決済みとさせて頂きます。
もっと勉強して出直します。みなさん本当にありがとうございました!
|
|