如何使用C#显示接收的图像?

时间:2017-04-04 07:44:06

标签: c# c++ sockets tcp

我同时拥有C#应用程序和C ++应用程序。在C ++应用程序中,我将桌面屏幕捕获为BITMAP,并通过TCP套接字将图像发送到C#应用程序。我可以通过TCP发送捕获的图像,但是我无法在C#应用程序中显示接收到的图像。请看代码:

在C ++应用程序中,用于发送图像的代码(How can I convert BITMAPINFOHEADER into Byte array using c++):

发送(theSocket,(char *)& bi,sizeof(bi),0); 发送(theSocket,lpbitmap,dwBmpSize,0);

在C#应用程序中:

private void startListening()
    {
        int port = 0;
        port = Convert.ToInt32(textBox1.Text.ToString());

        Console.WriteLine("Server is starting...");
        byte[] data = new byte[1024];
        IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);

        Socket newsock = new Socket(AddressFamily.InterNetwork,
                        SocketType.Stream, ProtocolType.Tcp);

        newsock.Bind(ipep);
        newsock.Listen(10);
        label1.Invoke((MethodInvoker)delegate
        {
            label1.Visible = true;
            label1.Text = "Waiting for a client...";
        });


        Socket client = newsock.Accept();
        IPEndPoint newclient = (IPEndPoint)client.RemoteEndPoint;

        label1.Invoke((MethodInvoker)delegate
        {
            label1.Text = "Connected to client. Recieving image...";
        });

        try
        {
            while (true)
            {
                data = ReceiveVarData(client);

                using (MemoryStream ms = new MemoryStream(data))
                {

                    bytesRead = ms.Read(data, 0, data.Length);
                    if (bytesRead > 0)
                    {
                        try
                        {
                            Image img = Image.FromStream(ms);
                            pictureBox1.Invoke((MethodInvoker)delegate
                            {
                                pictureBox1.Image = img;
                                pictureBox1.Refresh();
                            });
                        }
                        catch (ArgumentException e)
                        {
                            Console.WriteLine("something broke");
                        }
                    }
                }

                if (data.Length == 0)
                    newsock.Listen(10);
            }
        }
        catch (Exception)
        {
            this.Invoke((MethodInvoker)delegate
            {
                this.Close();
            });
        }

        client.Close();
        newsock.Close();
    }


 private byte[] ReceiveVarData(Socket client)
    {
        int total = 0;
        int recv;
        byte[] datasize = new byte[4];
        byte[] data=null;
        try
        {
            recv = client.Receive(datasize, 0, 4, 0);
            int size = BitConverter.ToInt32(datasize, 0);
            int dataleft = size;
            data = new byte[size];
            while (total < size)
            {
                recv = client.Receive(data, total, dataleft, 0);
                if (recv == 0)
                {
                    break;
                }
                total += recv;
                dataleft -= recv;
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show("Client disconnected.");
            this.Invoke((MethodInvoker)delegate
            {
                this.Close();
            });
        }
        return data;
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var t = new Thread(startListening);
        t.IsBackground = true;
        t.Start();
    }

1 个答案:

答案 0 :(得分:0)

.NET不会从流中读取BITMAPINFOHEADER。它期望流数据与普通文件格式匹配,但BITMAPINFOHEADER严格来说是内存格式。您需要在流中包含BITMAPFILEHEADER(紧接在BITMAPINFOHEADER之前),才能成功呈现.NET能够处理的BMP文件格式流。

那就是说,如果你能帮助的话,我不会建议你。通过以众所周知的文件格式(如PNG或JPEG)对图像数据进行编码来压缩图像数据会好得多。这将解决编码问题,同时显着减少您传输的数据量(从而改善传输延迟)。据推测,在您的C ++方面,您可以访问一些可以为您生成PNG或JPEG数据的图像处理库。