2014/06/13

画像の転送例

とても単純に画像データ(ビットマップ)を直接送る例です。今回作成したクラスの使い方は次の通り :

(1) TransportableBitmapクラス
転送できるビットマップのクラス。Bitmapを指定して生成する。
var tb = new TransportableBitma(bitmap);

(2)  ReceivableBitmapクラス
受信できるビットマップのクラス。受信後にキャストしてビットマップを取得する。

var rb = new ReceivableBitmap();
// 通信が完了したことを認識した後
Bitmap bitmap = (Bitmap)rb;

今回は簡単のためエラー処理を全く行っていないが実際には、画像の変換時に行うべきである。また、受信完了時はイベントに通知できるようにしたほうが有用なため、ReceivableBitmapクラスに受信イベントを追加するとよいだろう。

サンプルの動作風景:


以下ソース:
using System;
using System.Drawing;
using System.Drawing.Imaging;

/*
 * ビットマップの転送例
 */

namespace cstest {
    class TransportableBitmap {
        public TransportableBitmap(Bitmap bitmap) {
            this.bitmap = bitmap;
        }

        public void sendTo(string host, int port, int local_port) {
            System.Net.Sockets.UdpClient udp =
                 new System.Net.Sockets.UdpClient(local_port);
           
            // ビットマップのデータ取得
            var data = (byte[])(new ImageConverter()).ConvertTo(bitmap, typeof(byte[]));

            udp.Send(data, data.Length, host, port);
           
            //UDP接続を終了
            udp.Close();
        }

        // Bitmapにキャストできるようにする
        public static explicit operator Bitmap(TransportableBitmap tb) {
            return tb.bitmap;
        }

        Bitmap bitmap;
    }

    class ReceivableBitmap {
        public ReceivableBitmap() {

        }

        public async System.Threading.Tasks.Task receive(string host, int port, int local_port) {
            System.Net.Sockets.UdpClient udp =
                 new System.Net.Sockets.UdpClient(local_port);
            // 受信の非同期待機
            var result = await udp.ReceiveAsync();
            // データを画像クラスに変換
            var image = (Image)(new ImageConverter()).ConvertFrom(result.Buffer);
            bitmap = new Bitmap(image);

            System.Console.WriteLine("受信完了");
        }

        // このクラスをBitmapにキャストできるようにする
        public static explicit operator Bitmap (ReceivableBitmap rb) {
            return rb.bitmap;
        }

        Bitmap bitmap;
    }

    public class Program {
        public static void Main() {
            Console.WriteLine("モードの選択(送信1 / 受信 2) : ");
            int mode = int.Parse(Console.ReadLine());

            if(mode == 1) {
                Console.WriteLine("送信するファイル名 : ");
                string file_name = Console.ReadLine();

                var image = (Bitmap)Image.FromFile(file_name);
                var tb = new TransportableBitmap(image);

                tb.sendTo("127.0.0.1", 2002, 2001);
            }
            else {
                Console.WriteLine("受信待機中…");
                var rb = new ReceivableBitmap();
                rb.receive("127.0.0.1", 2001, 2002);

                Console.WriteLine("受信完了後に何か押してください。");
                Console.ReadLine();

                // 画像を表示
                Form1 form1 = new Form1();
                form1.showPicture((Bitmap)rb);

                // 待機
                System.Windows.Forms.Application.Run(form1);
            }
        }
    }
}