デスクトップ画像を取得するには


RXhati  2005-03-19 08:08:25  No: 88926

はじめまして。RXhatiです。
デスクトップの画像を取得し他端末へ取得した画像を送信したいと考えています。通信の部分にはWinsockを使おうと思っているのですが、どのような方法でデスクトップの画像を取得すればよいか分かりません。
どなたか、よい方法をご存知の方はお願いいたします。


030  2005-03-19 09:30:36  No: 88927

下記の要領で出来るでしょう。

1)GetDesktopWindowでデスクトップのウィンドウハンドルを取得
2)GetDCで取得したウィンドウハンドルのデバイスコンテキストを取得
3)CreateCompatibleDCで2)で取得したデバイスコンテキストと同じメモリデバイスコンテキストを作成
4)CreateCompatibleBitmapで2)で取得したデバイスコンテキストとと関連するデバイスと互換性のあるビットマップを作成
5)3)で作成したデバイスコンテキストに4)で作成したデバイスコンテキストを割り当てる
6)BitBltで画像を転送
7)取得したビットマップをWinsockで送信


030  2005-03-19 09:32:40  No: 88928

3)〜5)はピクチャーボックスで代用してもいいんじゃないでしょうか。
6)でファイルに画像を書き出して
7)でファイルの内容をWinsockで送信

とか


Say  2005-03-19 11:34:05  No: 88929

参考までに、
プラットフォームSDKでkeybd_eventを調べれば、
PrintScreenキーストロ−クの合成で
画面キャプチャーする方法がかかれています。


RXhati  2005-03-20 08:14:13  No: 88930

早速の回答ありがとうございます。
RXhatiです。

030さんの通りに作成してみました。
ですが、どうもうまくデスクトップの画像が取得できません。
どこが悪いのかご指摘願います。

Dim nhWnd As Long     'ウインドウのハンドル
Dim DC As Long        'デバイスコンテキストハンドル
Dim MDC As Long       'メモリデバイスコンテキスト
Dim BMPDC As Long     'ビットマップ

'1)GetDesktopWindowでデスクトップのウィンドウハンドルを取得
nhWnd = GetDesktopWindow

'2)GetDCで取得したウィンドウハンドルのデバイスコンテキストを取得
DC = GetDC(nhWnd)

'3)CreateCompatibleDCで2)で取得したデバイスコンテキストと同じメモリデバイスコンテキストを作成
MDC = CreateCompatibleDC(DC)

'4)CreateCompatibleBitmapで2)で取得したデバイスコンテキストとと関連するデバイスと互換性のあるビットマップを作成
BMPDC = CreateCompatibleBitmap(DC, Screen.Width, Screen.Height)

'5)3)で作成したデバイスコンテキストに4)で作成したデバイスコンテキストを割り当てる
Call SelectObject(MDC, BMPDC)

'6)BitBltで画像を転送
Call BitBlt(Picture1.hdc, 0, 0, Screen.Width, Screen.Height, MDC, 0, 0, SRCCOPY)


ガッ  2005-03-20 08:23:58  No: 88931

個人的には、Sayさんの方法を薦めます。
※ClipBoardオブジェクト使ってすぐに受け取れるし。


ガッ  2005-03-20 08:26:11  No: 88932

連続投稿すみません(orz
ソースコードに「デスクトップの画像を転送するコード」が無いように見えますが…?
あと、作成したハンドルはちゃんと破棄するように(ぉ
そこまでがソースコードでs(ry


RXhati  2005-03-20 08:31:33  No: 88933

最初に書かなくて申し訳ありません。
デスクトップの画像を一度だけでなくリアルタイムに(1秒間に20回くらい)送ろうと考えております。
そのためにクリップボードオブジェクトを使いますと送り側のコピぺ等ができなくなってしまいます。
そのために、クリップボードを使わずに何かよい方法がございましたら
よろしくお願いいたします。


RXhati  2005-03-20 08:39:10  No: 88934

ガッさんのご指摘通りです。
実は上記の方法でどのような形でデスクトップ画像のデータが取得されるのかが分かりません。
分かり次第追加させていただこうと思います。
またハンドルを破棄するようにとありますが2)3)4)で取得したハンドルでよいのでしょうか。?
以上です。よろしくお願いいたします。


ガッ  2005-03-20 08:42:20  No: 88935

昔、おんなじこと考えていた人がいてなぁ…
「それだと、転送速度がバカにならない」といわれてあきらめた人が…
一応計算してみてくれ。
予想
最近のPCの画素数:1024*768=786432
最近のPCの色深度:32Bit=4Byte
画像全体のデータ:786432*4(Bytes)=3 145 728→3MB
…一秒間に20回サンプリングするんだろ、
3*20=60(MB/s)=480Mbps
…すっげーいい回線使ってるな♪光?

とまぁ、無圧縮だとこういう結果になる。
それなら圧縮すればいい、ということだが、「実際に組める」のなら問題ない。
しかーし、いろいろ弊害がある。
よって、静止画を連続して送ってはいけない。
で、ちょと俺考えてみた。
・動画の圧縮技術を利用しなくてはならない
・もちろん遅延処理もナイトいけない
・必要なら、やっぱり暗号化も考えなきゃいけない
…俺ならあきらめて、他の方法考えるぞ。

※だからといって、いい方法を思いついたわけでもな(ry


ガッ  2005-03-20 09:02:44  No: 88936

ノ<頑張る気なら、昔俺がちょと作ってみた…アレ…ぁ、ここ実家だ(orz
……w;
ノ<資料が無いので、うろ覚えですが、何か書いて見ますw;;

使ったAPIはコレ。

Public Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hDC As Long) As Long
Public Declare Function BitBlt Lib "gdi32" _
     (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, _
     ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
'Sample1
Public Sub BitBltTO(ByVal hDC As Long)
    
    'スクリーン全体をBitBltしてみる
    Dim DeskTopWidth            As Long
    Dim DeskTopHeight           As Long
    Dim DeskTopWindowHandle     As Long
    Dim DeskTopWindowDC         As Long
    
    'デスクトップ関連のを読み取る
    DeskTopWidth = Screen.Width \ Screen.TwipsPerPixelX
    DeskTopHeight = Screen.Height \ Screen.TwipsPerPixelY
    DeskTopWindowHandle = GetDesktopWindow()
    DeskTopWindowDC = GetDC(DeskTopWindowHandle)
    
    Debug.Print BitBlt(hDC, 0, 0, DeskTopWidth, DeskTopHeight, DeskTopWindowDC, 0, 0, vbSrcCopy)
    
    ReleaseDC DeskTopWindowHandle, DeskTopWindowDC
        
End Sub

BitBltTO関数で、デスクトップの画像を目的のDCにコピーできます。
で、ココからが本題。

1  デバイス独立ビットマップ情報を自分でゴリゴリする。
メモリデバイスコンテキストに関連付けられたメモリビットマップに対して、
GetDIBits()を使ってビットマップのメモリイメージを受け取ることが出来まして、
そのビットマップのメモリイメージが…そうですねぇ、「ビットマップファイルのデータ構造」と類似しています。
…つまり、オンメモリでビットマップをゴリゴリ出来ます。
ビットマップの取得のしかたは、GetDIBits()をインターネットで調べれば、
結構出てくる模様です。
後の作業は、あなたにお任せしますw;

2  (ry
他にいい方法がありそうですが、見当たりません&思いつきませんでした(or-----z
一応参考に、
http://www2j.biglobe.ne.jp/~little-g/cgi-bin/vbtheme2.cgi
を"GDI+"で検索すれば、少しおいしいかも。


ガッ  2005-03-20 09:03:25  No: 88937

ノ<頑張る気なら、昔俺がちょと作ってみた…アレ…ぁ、ここ実家だ(orz
……w;
ノ<資料が無いので、うろ覚えですが、何か書いて見ますw;;

使ったAPIはコレ。

Public Declare Function GetDesktopWindow Lib "user32" () As Long
Public Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
Public Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hDC As Long) As Long
Public Declare Function BitBlt Lib "gdi32" _
     (ByVal hDestDC As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, ByVal nHeight As Long, _
     ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
'Sample1
Public Sub BitBltTO(ByVal hDC As Long)
    
    'スクリーン全体をBitBltしてみる
    Dim DeskTopWidth            As Long
    Dim DeskTopHeight           As Long
    Dim DeskTopWindowHandle     As Long
    Dim DeskTopWindowDC         As Long
    
    'デスクトップ関連のを読み取る
    DeskTopWidth = Screen.Width \ Screen.TwipsPerPixelX
    DeskTopHeight = Screen.Height \ Screen.TwipsPerPixelY
    DeskTopWindowHandle = GetDesktopWindow()
    DeskTopWindowDC = GetDC(DeskTopWindowHandle)
    
    Debug.Print BitBlt(hDC, 0, 0, DeskTopWidth, DeskTopHeight, DeskTopWindowDC, 0, 0, vbSrcCopy)
    
    ReleaseDC DeskTopWindowHandle, DeskTopWindowDC
        
End Sub

BitBltTO関数で、デスクトップの画像を目的のDCにコピーできます。
で、ココからが本題。

1  デバイス独立ビットマップ情報を自分でゴリゴリする。
メモリデバイスコンテキストに関連付けられたメモリビットマップに対して、
GetDIBits()を使ってビットマップのメモリイメージを受け取ることが出来まして、
そのビットマップのメモリイメージが…そうですねぇ、「ビットマップファイルのデータ構造」と類似しています。
…つまり、オンメモリでビットマップをゴリゴリ出来ます。
ビットマップの取得のしかたは、GetDIBits()をインターネットで調べれば、
結構出てくる模様です。
後の作業は、あなたにお任せしますw;

2  (ry
他にいい方法がありそうですが、見当たりません&思いつきませんでした(or-----z
一応参考に、
http://www2j.biglobe.ne.jp/~little-g/cgi-bin/vbtheme2.cgi
を"GDI+"で検索すれば、少しおいしいかも。


ガッ  2005-03-20 09:38:33  No: 88938

==○)oT)<ぁぅ…すみません、連続投稿してしますた(orz


....  2005-03-20 21:09:15  No: 88939

>ガッさんのご指摘通りです。
>実は上記の方法でどのような形でデスクトップ画像のデータが取得されるのかが分かりません。
分かってるなら最初にそう聞けば良いのに。
どこが悪いのかって。。なんかいやらしい聞き方ですね。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加