C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[16]: 画像データの送受信


(過去ログ 32 を表示中)

[トピック内 18 記事 (1 - 18 表示)]  << 0 >>

■15537 / inTopicNo.1)  画像データの送受信
  
□投稿者/ れれれ (46回)-(2008/03/14(Fri) 18:24:19)

分類:[C#] 

2008/03/14(Fri) 18:24:44 編集(投稿者)

お世話になっていますれれれです。

Tcp/IPで画像の送受信をするプログラムを今考えています。
クライアントが「A」というデータを送るとサーバが「A」に対応する画像をクライアントに送ります。
そしてクライアントが「A」の画像を加工して、その加工された画像をサーバに「A」として上書き保存するプログラムです。

サーバにある画像をbitmapからbyte[]に変換することは出来ました。
クライアントが送られてくるbyte[]を画像に変換するにはどうすればいいのでしょうか?
クライアント側に送られてくる画像データは毎回異なるので画像データをためるbyte[]の大きさを自動で決めてくれるようなことができればいいのですが
引用返信 編集キー/
■15538 / inTopicNo.2)  Re[1]: 画像データの送受信
□投稿者/ Jitta on the way (56回)-(2008/03/14(Fri) 18:30:31)
No15537 (れれれ さん) に返信
> 2008/03/14(Fri) 18:24:44 編集(投稿者)
>
> お世話になっていますれれれです。
>
> Tcp/IPで画像の送受信をするプログラムを今考えています。
> クライアントが「A」というデータを送るとサーバが「A」に対応する画像をクライアントに送ります。
> そしてクライアントが「A」の画像を加工して、その加工された画像をサーバに「A」として上書き保存するプログラムです。
>
> サーバにある画像をbitmapからbyte[]に変換することは出来ました。
> クライアントが送られてくるbyte[]を画像に変換するにはどうすればいいのでしょうか?
> クライアント側に送られてくる画像データは毎回異なるので画像データをためるbyte[]の大きさを自動で決めてくれるようなことができればいいのですが

先(あるいは一緒)に大きさを送ればいいのでは?

HTTP の通信なども、同じように、長さ不定ですよね。なのに、なぜ、そのデータをとれるのでしょう。あるいは、データが終わったことを、どうやって知るのでしょう。
引用返信 編集キー/
■15541 / inTopicNo.3)  Re[2]: 画像データの送受信
□投稿者/ やじゅ (243回)-(2008/03/14(Fri) 19:07:18)
> ■No15537 (れれれ さん) に返信
>
>クライアントが送られてくるbyte[]を画像に変換するにはどうすればいいのでしょうか?

「Winsock 画像データの送信」で検索してみると、何かヒントがあるはず。
引用返信 編集キー/
■15551 / inTopicNo.4)  Re[3]: 画像データの送受信
□投稿者/ 出水 (9回)-(2008/03/14(Fri) 21:55:59)
httpと一緒くたにするのは良くない気が…

バイナリデータの送信は、終了のデリミタをつけることが出来ないんで
最初に4バイト、送信サイズを送るという取り決めをすればいいです

送信はこんな感じ
var tcp = new System.Net.Sockets.TcpClient();
var sm = tcp.GetStream();

var bitmap = new byte[10000];
var bnum = System.BitConverter.GetBytes(bitmap.Length);
sm.Write(bnum, 0, bnum.Length);
sm.Write(bitmap, 0, bitmap.Length);

で、受信はこんな感じ

var bary= new byte[4];
sm.Read(bary, 0, 4);
int datasize = System.BitConverter.ToInt32(bary, 0);
int readsize = 0;
var bitmap = new byte[datasize];
while(readsize < datasize) readsize += sm.Read(bitmap, readsize, datasize - readsize);

引用返信 編集キー/
■15555 / inTopicNo.5)  Re[4]: 画像データの送受信
□投稿者/ も (13回)-(2008/03/15(Sat) 04:23:42)
bitmapをシリアル化する・・・のはだめかな
引用返信 編集キー/
■15557 / inTopicNo.6)  Re[5]: 画像データの送受信
□投稿者/ れれれ (47回)-(2008/03/15(Sat) 09:59:06)
とりあえず作ってみましたがまだ動きません。

server側
                Int32 port = 1234;
                IPAddress localAddr = IPAddress.Parse("127.0.0.1");
                TcpListener server = new TcpListener(localAddr, port);
                server.Start();

                TcpClient client = server.AcceptTcpClient();

                NetworkStream ns = client.GetStream();
               System.IO.MemoryStream ms = new System.IO.MemoryStream();
                byte[] resBytes = new byte[256];
                int resSize;
                do
                {
                    resSize = ns.Read(resBytes, 0, resBytes.Length);
                    if (resSize == 0)
                        return;

                    ms.Write(resBytes, 0, resSize);
                }
                while (ns.DataAvailable);
                string resMsg = enc.GetString(ms.ToArray());
                if (resMsg == "image")
                {
                    
                    Bitmap bitmap = new Bitmap(@"C:\\Documents and Settings\\user\\デスクトップ\\image.jpeg");
                    System.IO.MemoryStream msimg = new System.IO.MemoryStream();
                    bitmap.Save(msimg, System.Drawing.Imaging.ImageFormat.Bmp);
                    byte[] byteData = new byte[msimg.Length];
                    byteData = msimg.ToArray();
                    byte[] bytesize = BitConverter.GetBytes(msimg.Length);
                    ns.Write(bytesize, 0, bytesize.Length);
                    ns.Write(byteData, 0, byteData.Length);
                }
                    

client側
////////////////クライアントがサーバにデータ要求////////////
            byte[] buffer;
            Int32 port = 1234;
            TcpClient clinet = new TcpClient();
            NetworkStream ns = clinet.GetStream();
            clinet.Connect("127.0.0.1", port);
            string subject = "英語";
            byte[] data = System.Text.Encoding.UTF8.GetBytes(subject);
            NetworkStream stream = clinet.GetStream();
            stream.Write(data, 0, data.Length);
//////////////////////////////////////////////////////////////////

///////////////サーバからくる画像データをpicturebox1に表示////////////
            byte[] bytesize = new byte[4];
            ns.Read(bytesize, 0, 4);
            int datasize = BitConverter.ToInt32(bytesize, 0);
            int readsize = 0;
            byte[] bitmap = new byte[datasize];
            while (readsize < datasize)
                readsize += ns.Read(bitmap, readsize, datasize - readsize);
            MemoryStream ms = new MemoryStream(bitmap);
            Bitmap bmp = Bitmap.FromStream(ms); //コンパイルエラーエラー	1	型 'System.Drawing.Image' を 'System.Drawing.Bitmap' に暗黙的に変換できません。明示的な変換が存在します。(cast が不足していないかどうかを確認してください)	
            Graphics g = Graphics.FromImage(bmp);
            g.DrawImage(bmp, 0, 0, 640, 480);
            g.Dispose();

            pictureBox1.Invalidate();


流れとしては

1.サーバ起動
2.クライアントがサーバに画像データ要求
3.サーバがクライアントに画像データ送信
4.クライアント側でその画像を加工しサーバに送信
です

ダメなところがあったら指摘お願いします。

引用返信 編集キー/
■15558 / inTopicNo.7)  Re[6]: 画像データの送受信
□投稿者/ やじゅ (244回)-(2008/03/15(Sat) 10:18:58)
やじゅ さんの Web サイト
No15557 (れれれ さん) に返信
> MemoryStream ms = new MemoryStream(bitmap);
> Bitmap bmp = Bitmap.FromStream(ms); //コンパイルエラー
>

コンパイルエラーくらいなんとかしましょうよ、って間違ってたりして。
Bitmap.FromStream(new Bitmap(ms));
引用返信 編集キー/
■15782 / inTopicNo.8)  Re[7]: 画像データの送受信
□投稿者/ れれれ (48回)-(2008/03/21(Fri) 20:02:40)
クライアントのほうを出水さんの返信と
http://www.atmarkit.co.jp/bbs/phpBB/viewtopic.php?topic=33131&forum=7
を参考にして以下のように書いて見ました

            byte[] bytesize = new byte[4];
            ns.Read(bytesize, 0, 4);
            int datasize = BitConverter.ToInt32(bytesize, 0);
            int readsize = 0;
            byte[] bitmap = new byte[datasize];
            while (readsize < datasize)
                readsize += ns.Read(bitmap, readsize, datasize - readsize);
            MemoryStream ms = new MemoryStream(bitmap);
////////////////////////////////MemoryStreamに画像データの書き込み完了
///////////////////////////////以下MemoryStreamに書かれたbyte[]をビットマップに変換
            try
            {
                
                Image img = Image.FromStream(ms);      //例外エラー 使用されたパラメータが有効ではありません。
                Graphics g = Graphics.FromImage(img);
                g.DrawImage(img, 0, 0, 640, 480);
                g.Dispose();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

bitmapをbyte[]変換は多くの記事があるのですがbyte[]をbitmap変換は記事が少なくて困っています。
どうかご教授お願いします。

引用返信 編集キー/
■15792 / inTopicNo.9)  Re[8]: 画像データの送受信
□投稿者/ やじゅ (263回)-(2008/03/22(Sat) 03:17:49)
やじゅ さんの Web サイト
No15782 (れれれ さん) に返信
> Image img = Image.FromStream(ms); //例外エラー 使用されたパラメータが有効ではありません。
> bitmapをbyte[]変換は多くの記事があるのですがbyte[]をbitmap変換は記事が少なくて困っています。
> どうかご教授お願いします。

例外エラーが出ているってことは、データ生成部分が悪いのかも知れませんね。
http://smdn.invisiblefulmoon.net/ikimasshoy/dotnettips/tips031.html
引用返信 編集キー/
■15806 / inTopicNo.10)  Re[9]: 画像データの送受信
□投稿者/ れれれ (49回)-(2008/03/22(Sat) 17:05:35)
No15792 (やじゅ さん) に返信
            byte[] bytesize = new byte[4]; //サーバから送られる画像データのサイズ情報を入れる配列
            ns.Read(bytesize, 0, 4);
            int datasize = BitConverter.ToInt32(bytesize, 0);
            int readsize = 0;
            byte[] bitmap = new byte[datasize];

この
            byte[] bytesize = new byte[4];
            ns.Read(bytesize, 0, 4);
を
            byte[] bytesize = new byte[10];
            ns.Read(bytesize, 0, 10);
とすると画像が送られて、pictureboxに表示されました。
ありがとうございます。(640*480のカラービットマップなので4つのバイト配列に画像サイズデータ情報が入りきらなかった?)

引用返信 編集キー/
■15807 / inTopicNo.11)  Re[10]: 画像データの送受信
□投稿者/ Azulean (33回)-(2008/03/22(Sat) 17:18:59)
2008/03/22(Sat) 17:19:26 編集(投稿者)

MemoryStream.Lengthはlong型であり、8バイト必要でしょう。
http://msdn2.microsoft.com/ja-jp/library/system.io.memorystream.length.aspx

int型でやりとりするのであれば、サーバー側の時点で切り捨てては?
int streamLength = (int)msimg.Length;
byte[] bytesize = BitConverter.GetBytes(streamLength);

#それでも2バイト余分に読み込もうとしているのが気になるけれど…。
引用返信 編集キー/
■15809 / inTopicNo.12)  Re[11]: 画像データの送受信
□投稿者/ 出水 (15回)-(2008/03/22(Sat) 17:33:43)
4Byteのsigned intを使っているので、送信できる最大サイズは2GBです
1MB程度のBitmapではあふれるわけはないです

一応解決したなら良いのですが、原因は調べておいたほうが良さそうです

#なんとなく、違うサイズのBitmapだと不具合を起こしそうな予感
引用返信 編集キー/
■15810 / inTopicNo.13)  Re[12]: 画像データの送受信
□投稿者/ Azulean (35回)-(2008/03/22(Sat) 17:43:37)
> 4Byteのsigned intを使っているので、送信できる最大サイズは2GBです
> 1MB程度のBitmapではあふれるわけはないです
サイズを表すバイト列の長さがサーバー側とクライアント側で一致していないだけです。

サーバー側
System.IO.MemoryStream msimg = new System.IO.MemoryStream();
byte[] bytesize = BitConverter.GetBytes(msimg.Length); // longのGetBytesなので8バイト
ns.Write(bytesize, 0, bytesize.Length);

クライアント側
byte[] bytesize = new byte[4];
ns.Read(bytesize, 0, 4); // 4バイトしか読んでいない

引用返信 編集キー/
■15837 / inTopicNo.14)  Re[13]: 画像データの送受信
□投稿者/ れれれ (50回)-(2008/03/23(Sun) 18:24:32)
No15810 (Azulean さん) に返信
>>4Byteのsigned intを使っているので、送信できる最大サイズは2GBです
>>1MB程度のBitmapではあふれるわけはないです
> サイズを表すバイト列の長さがサーバー側とクライアント側で一致していないだけです。
>
> サーバー側
> System.IO.MemoryStream msimg = new System.IO.MemoryStream();
> byte[] bytesize = BitConverter.GetBytes(msimg.Length); // longのGetBytesなので8バイト
> ns.Write(bytesize, 0, bytesize.Length);
>
> クライアント側
> byte[] bytesize = new byte[4];
> ns.Read(bytesize, 0, 4); // 4バイトしか読んでいない
>

確かにクライアントを8バイトにしても受信できました。
7バイトでは4バイトと同様出来ませんでした。
引用返信 編集キー/
■15843 / inTopicNo.15)  Re[14]: 画像データの送受信
□投稿者/ 倉田 有大 (161回)-(2008/03/23(Sun) 23:48:47)
> 確かにクライアントを8バイトにしても受信できました。
> 7バイトでは4バイトと同様出来ませんでした。

あれ、なんで8バイトと10バイトでよめるのじゃ?
引用返信 編集キー/
■15864 / inTopicNo.16)  Re[15]: 画像データの送受信
□投稿者/ れれれ (51回)-(2008/03/24(Mon) 16:58:26)
2008/03/24(Mon) 16:59:33 編集(投稿者)
No15843 (倉田 有大 さん) に返信

> あれ、なんで8バイトと10バイトでよめるのじゃ?

確かに10バイトで読めない時がありました

送る画像のサイズが27355だった時


                        byte[] bytesize = new byte[10];
                        ns.Read(bytesize, 0, 10);
                        int datasize = BitConverter.ToInt32(bytesize, 0);
                        int readsize = 0;
                        byte[] bitmapdata = new byte[datasize];
                        while (readsize < datasize)//無限ループ
                            readsize += ns.Read(bitmapdata, readsize, datasize - readsize);

readsizeが27353でとまってしまいプログラムが止まりました。
1回whileループの処理でreadsizeが0から26278になりました。2回目のループで27353になり無限ループです。

8バイトにすると1回目のループで0から26280になり2回目で27355になりループを抜け出しました。
10バイトで画像が送れたのは単純に偶然だと思います。

理由はわかりません

引用返信 編集キー/
■15865 / inTopicNo.17)  Re[15]: 画像データの送受信
□投稿者/ れれれ (52回)-(2008/03/24(Mon) 16:59:42)
No15843 (倉田 有大 さん) に返信

> あれ、なんで8バイトと10バイトでよめるのじゃ?

確かに10バイトで読めない時がありました

送る画像のサイズが27355だった時


                        byte[] bytesize = new byte[10];
                        ns.Read(bytesize, 0, 10);
                        int datasize = BitConverter.ToInt32(bytesize, 0);
                        int readsize = 0;
                        byte[] bitmapdata = new byte[datasize];
                        while (readsize < datasize)//無限ループ
                            readsize += ns.Read(bitmapdata, readsize, datasize - readsize);

readsizeが27353でとまってしまいプログラムが止まりました。
1回whileループの処理でreadsizeが0から26278になりました。2回目のループで27353になり無限ループです。

8バイトにすると1回目のループで0から26280になり2回目で27355になりループを抜け出しました。
10バイトで画像が送れたのは単純に偶然だと思います

引用返信 編集キー/
■15877 / inTopicNo.18)  Re[16]: 画像データの送受信
□投稿者/ PATIO (50回)-(2008/03/24(Mon) 19:25:17)
> MemoryStream.Lengthはlong型であり、8バイト必要でしょう。

これをみて、そうだっけとC#入門講座を見直す奴がここに一人。
あうあう。32bitOSのC++に慣れているとついlongが32bitになってしまう。
C#の場合は違うと言うのをちゃんと覚えとかないと。
やっぱり使わないとうろ覚えになりますねぇ。

引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -