Winsockでキャプチャ画像をリアルタイムに送受信するには


Toshihiko  2004-12-01 21:47:11  No: 87064  IP: [192.*.*.*]

お世話になります。
過去ログをみたところ、画像の送信についてはサンプルを見つけることができましたが、受信部分のサンプルを見つけることができませんでした。またGoogleなどで検索したところ、一度ファイルに保存したあとでの送信方法は見つけることができました。
ですが、今回ファイルに保存しないでなめらかにリアルタイムに、画面キャプチャ画像を送信し、受信できるシステムにしてみたいと思っています。
送信側はクライアントで受信側がサーバにする予定です。

ご教授ください。

編集 削除
ももんが  2004-12-01 22:14:43  No: 87065  IP: [192.*.*.*]

いろいろありすぎて回答に困ってしまう質問ですね。
問題を整理しましょう。

1.基本的なTCP/IPの通信の方法が分からないのですか?
2.画面キャプチャをするところが分からないのですか?
3.画面キャプチャした画像のビットマップハンドルの取得の仕方が分からないのですか?
3.リアルタイムにしたいため画面キャプチャのデータを圧縮・解凍する方法が分からないのですか?

あと開発環境なんかも書いたほうが良いですね。

編集 削除
Toshihiko  2004-12-01 22:27:42  No: 87066  IP: [192.*.*.*]

返答ありがとうございます。

えと、キャプチャのサンプルをよく見かけるので、今回は特別必要とはしていません。ですが、送受信の部分でやりやすくなるようなキャプチャ方法があればそれも教えて頂きたいです。

画面キャプチャの圧縮・解凍については是非教えて頂きたいと思います。

そして、TCP/IPの通信方法は今回もっとも聞きたい部分です。一度に送信できるデータ量が64kbまでなどど聞きます。文字データの送受信はある程度理解していますが、画像はまったくわかりません。ですので、その方法をお願いします。

編集 削除
Toshihiko  2004-12-01 23:01:55  No: 87067  IP: [192.*.*.*]

追加です。

開発環境ですが、VB6です。
使用OSはWinXPですが、このソフトはWin98系でもNT系でも動くようにしたいと思っています。

一度に質問をしすぎて申し訳ないと思いますが、どうかよろしくお願い致します。

編集 削除
ガッ  2004-12-02 00:23:23  No: 87068  IP: [192.*.*.*]

そこまで分からないなら…とりあえず、1MB以上のデータを送受信できるTCPを使ったライブラリを構築することをオススメするぞ。
どうすればいいのかが、分かるはずだ。

ヒント:
TCPはデータをストリームで送ってくるから、「100バイトを一回で送った」から、
「100バイト一回に届く」わけじゃ「ない」、
最悪複数回に分けられて「最終的に100バイト届く」通信規約だ。
…まぁ、実際には100バイトくらいなら一回で送りきれるんだがな。

あとは…まぁ、ヘルプ読んでくれ。

編集 削除
Toshihiko  2004-12-02 10:31:50  No: 87069  IP: [192.*.*.*]

わかりました。ではデータの送信については自分でがんばってみます。

画像圧縮については引き続きお願いします。一応ランレングス法の圧縮のサンプルは見つけましたが、キャプチャー画像(1280*1024)だと3.8MBから2.8MBまでしか小さくならなかったので”なめらかにリアルタイム”にするにはちょっと難しいと思います。
一度保存するのならJPGにできますが、保存なしでなめらかに送受信できるくらいまで圧縮する方法あるのでしょうか?

編集 削除
GG  2004-12-02 12:13:15  No: 87070  IP: [192.*.*.*]

キャプチャー画像ってデスクトップとかの画面でしょうか?
変化したところだけを送信すればデータ量も少なくなって良いのでは

編集 削除
Toshihiko  2004-12-02 13:07:02  No: 87071  IP: [192.*.*.*]

キャプチャ画像は、画面全体の物です。デスクトップを始め、タスクバー、ウインドウなどPrintScreenを使用したときと同じものです。
「変化したところだけ」というのは確かにいいと思いますが、やはり確実になめらかにとはいかないのではないでしょうか?何かのウインドウの位置を少し動かしただけでも画像としては大幅な変化になってしまうと思いますし。

参考までに、現在使用しているキャプチャ方法はこのような物です。

'デスクトップのウインドウハンドル取得
Private Declare Function GetDesktopWindow Lib "user32" () As Long
'ウインドウ画像のデバイスコンテキスト取得
Private Declare Function GetDC Lib "user32" (ByVal hwnd As Long) As Long
'デバイスコンテキストの解放
Private Declare Function ReleaseDC Lib "user32" (ByVal hwnd As Long, ByVal hDC As Long) As Long

'BitBlt
Private 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
    
Const SRCCOPY = &HCC0020

Private Sub Command1_Click()
    Command1.Enabled = False
    'スクリーンキャプチャ
    Dim hDeskTopWnd As Long
    Dim hDeskTopDC As Long
    Dim Ret As Long
    'デスクトップ画像のハンドルを取得
    hDeskTopWnd = GetDesktopWindow
    hDeskTopDC = GetDC(hDeskTopWnd)
    'フォーム全体に描画
    Ret = BitBlt(Form1.hDC, 0, 0, Screen.Height, Screen.Width, hDeskTopDC, 0, 0, SRCCOPY)
    If Ret = 0 Then MsgBox "失敗", vbCritical
    'リフレッシュ
    Form1.Refresh
    'デバイスコンテキストの解放
    Ret = ReleaseDC(hDeskTopWnd, hDeskTopDC)
    
    Command1.Enabled = True
End Sub

Private Sub Form_Load()
Form1.ScaleMode = 3
Form1.AutoRedraw = True

End Sub

編集 削除
GG  2004-12-02 20:54:04  No: 87072  IP: [192.*.*.*]

なめらかにという感じにもよりますが、一度試しに作ってみたらどうですか?
周期的に画像を送信するのかイベント発生時に画像を送信するかによっても
なめらかにという意味が違ってくるような気がしますね。
周期的にだと画面の変更がなくても常に画像を送っていなければならないので
かなりの高負荷になりそうな予感がしますが。

編集 削除
Toshihiko  2004-12-02 21:03:20  No: 87073  IP: [192.*.*.*]

そうですね。
変化したところだけを送るやり方はちょっとわかりませんが、変化したら送るということなら、自分でもできそうですのでやってみます。

あと、どういう物にしたいかの具体例として、MSNメッセンジャーのリモートアシスタンスのような物にしてみたいと思っています。

編集 削除
通りすがり  2004-12-02 21:54:50  No: 87074  IP: [192.*.*.*]

・サイズ1280*1024の映像を画質を落とさずに
  ・ネットワークで送って
  ・滑らか(おそらく30fpsぐらい?)で表示する
ってこれはかなりキツイ処理ですね。

まず、1280x1024でフルカラーの画像だと1フレーム3MBで
30fpsだとその30倍、一秒間に100MB近くになります。
ビットレートで言えば800,000,000bpsぐらいですか。
これだけで普通の環境では非圧縮では
送れないであろうことがわかると思います。

次に圧縮ですが、LHAやZIPのようなものは
可逆圧縮なので画質が落ちませんが処理に恐ろしく時間がかかります。
(30枚の画像を1秒で圧縮/展開する必要があります)
Jpegのような非可逆圧縮ならかなりサイズを押させることもできますが、
まず文字なんかはつぶれて見れないでしょうね。
可逆(画質の落ちない)圧縮だけならば
特許という壁を作るもの、抜けるもの、色々と方法がありますが
「リアルタイム」でとなるとサイズは半分まで落とせるかどうかではないかと。

特殊なハードウェアを用いないでソフト(しかもVB)でやろうという
心意気は天晴れですが、現実にはかなりキツイってことが
わかっていただけるかと思います。

「変化したところだけ送る」「滑らかさは努力目標(っていうか無視)」が
現実的な仕様だと思いますよ。

編集 削除
Toshihiko  2004-12-02 23:31:09  No: 87075  IP: [192.*.*.*]

具体的なご返答ありがとうございます。

画質にもよりますが、ファイルに出力しないでJPGに変換できる方法があるのでしたら、それでも十分です。

リアルタイムというのも、動画のようにとまではいきませんが連続に見ていてどういう動きをしているのかわかる程度のコマ送りになれば十分です。

編集 削除
VBer  2004-12-03 01:17:23  No: 87076  IP: [192.*.*.*]

JPEG処理を自分で作成する気があるなら
http://workarea.homeip.net/
の『画像処理に関する原始譜及び仕様書等の文書』のところで
JPEGの企画書とCのサンプルソースコードを入手することができます。

まあ、そこまでして。。。。って思いますけど。

編集 削除
Toshihiko  2004-12-03 11:32:57  No: 87077  IP: [192.*.*.*]

ご親切にありがとうございます。

ちょっとこれはむずかしすぎますね。
実際VBではないですが、フリーの『Remote GUI』やメッセの『リモートアシスタンス』などあるので、DLLを使えば何かしら方法があると思ったんですけど、無理なんですかね。

編集 削除