お世話になります。
過去ログをみたところ、画像の送信についてはサンプルを見つけることができましたが、受信部分のサンプルを見つけることができませんでした。またGoogleなどで検索したところ、一度ファイルに保存したあとでの送信方法は見つけることができました。
ですが、今回ファイルに保存しないでなめらかにリアルタイムに、画面キャプチャ画像を送信し、受信できるシステムにしてみたいと思っています。
送信側はクライアントで受信側がサーバにする予定です。
ご教授ください。
いろいろありすぎて回答に困ってしまう質問ですね。
問題を整理しましょう。
1.基本的なTCP/IPの通信の方法が分からないのですか?
2.画面キャプチャをするところが分からないのですか?
3.画面キャプチャした画像のビットマップハンドルの取得の仕方が分からないのですか?
3.リアルタイムにしたいため画面キャプチャのデータを圧縮・解凍する方法が分からないのですか?
あと開発環境なんかも書いたほうが良いですね。
返答ありがとうございます。
えと、キャプチャのサンプルをよく見かけるので、今回は特別必要とはしていません。ですが、送受信の部分でやりやすくなるようなキャプチャ方法があればそれも教えて頂きたいです。
画面キャプチャの圧縮・解凍については是非教えて頂きたいと思います。
そして、TCP/IPの通信方法は今回もっとも聞きたい部分です。一度に送信できるデータ量が64kbまでなどど聞きます。文字データの送受信はある程度理解していますが、画像はまったくわかりません。ですので、その方法をお願いします。
追加です。
開発環境ですが、VB6です。
使用OSはWinXPですが、このソフトはWin98系でもNT系でも動くようにしたいと思っています。
一度に質問をしすぎて申し訳ないと思いますが、どうかよろしくお願い致します。
そこまで分からないなら…とりあえず、1MB以上のデータを送受信できるTCPを使ったライブラリを構築することをオススメするぞ。
どうすればいいのかが、分かるはずだ。
ヒント:
TCPはデータをストリームで送ってくるから、「100バイトを一回で送った」から、
「100バイト一回に届く」わけじゃ「ない」、
最悪複数回に分けられて「最終的に100バイト届く」通信規約だ。
…まぁ、実際には100バイトくらいなら一回で送りきれるんだがな。
あとは…まぁ、ヘルプ読んでくれ。
わかりました。ではデータの送信については自分でがんばってみます。
画像圧縮については引き続きお願いします。一応ランレングス法の圧縮のサンプルは見つけましたが、キャプチャー画像(1280*1024)だと3.8MBから2.8MBまでしか小さくならなかったので”なめらかにリアルタイム”にするにはちょっと難しいと思います。
一度保存するのならJPGにできますが、保存なしでなめらかに送受信できるくらいまで圧縮する方法あるのでしょうか?
キャプチャー画像ってデスクトップとかの画面でしょうか?
変化したところだけを送信すればデータ量も少なくなって良いのでは
キャプチャ画像は、画面全体の物です。デスクトップを始め、タスクバー、ウインドウなど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
なめらかにという感じにもよりますが、一度試しに作ってみたらどうですか?
周期的に画像を送信するのかイベント発生時に画像を送信するかによっても
なめらかにという意味が違ってくるような気がしますね。
周期的にだと画面の変更がなくても常に画像を送っていなければならないので
かなりの高負荷になりそうな予感がしますが。
そうですね。
変化したところだけを送るやり方はちょっとわかりませんが、変化したら送るということなら、自分でもできそうですのでやってみます。
あと、どういう物にしたいかの具体例として、MSNメッセンジャーのリモートアシスタンスのような物にしてみたいと思っています。
・サイズ1280*1024の映像を画質を落とさずに
・ネットワークで送って
・滑らか(おそらく30fpsぐらい?)で表示する
ってこれはかなりキツイ処理ですね。
まず、1280x1024でフルカラーの画像だと1フレーム3MBで
30fpsだとその30倍、一秒間に100MB近くになります。
ビットレートで言えば800,000,000bpsぐらいですか。
これだけで普通の環境では非圧縮では
送れないであろうことがわかると思います。
次に圧縮ですが、LHAやZIPのようなものは
可逆圧縮なので画質が落ちませんが処理に恐ろしく時間がかかります。
(30枚の画像を1秒で圧縮/展開する必要があります)
Jpegのような非可逆圧縮ならかなりサイズを押させることもできますが、
まず文字なんかはつぶれて見れないでしょうね。
可逆(画質の落ちない)圧縮だけならば
特許という壁を作るもの、抜けるもの、色々と方法がありますが
「リアルタイム」でとなるとサイズは半分まで落とせるかどうかではないかと。
特殊なハードウェアを用いないでソフト(しかもVB)でやろうという
心意気は天晴れですが、現実にはかなりキツイってことが
わかっていただけるかと思います。
「変化したところだけ送る」「滑らかさは努力目標(っていうか無視)」が
現実的な仕様だと思いますよ。
具体的なご返答ありがとうございます。
画質にもよりますが、ファイルに出力しないでJPGに変換できる方法があるのでしたら、それでも十分です。
リアルタイムというのも、動画のようにとまではいきませんが連続に見ていてどういう動きをしているのかわかる程度のコマ送りになれば十分です。
JPEG処理を自分で作成する気があるなら
http://workarea.homeip.net/
の『画像処理に関する原始譜及び仕様書等の文書』のところで
JPEGの企画書とCのサンプルソースコードを入手することができます。
まあ、そこまでして。。。。って思いますけど。
ご親切にありがとうございます。
ちょっとこれはむずかしすぎますね。
実際VBではないですが、フリーの『Remote GUI』やメッセの『リモートアシスタンス』などあるので、DLLを使えば何かしら方法があると思ったんですけど、無理なんですかね。