【问题标题】:How to compare two different images, send the difference via tcp then merge the difference with image on client?如何比较两个不同的图像,通过 tcp 发送差异然后将差异与客户端上的图像合并?
【发布时间】:2023-09-28 14:19:01
【问题描述】:

我有代码可以通过有效的 TCP 发送和接收图像。但是,因为每次带宽使用量很大时我都会发送整个图像,并且会使我的程序在较慢的互联网连接上完全无法使用。

为了减少带宽,很明显我只想发送当前图像和前一个图像之间的差异。我希望您能提供一些有关如何执行此操作或使用哪些库(如果有)的信息。我在下面有我目前用来发送和接收图像的发送和接收线程。我的程序的用途是作为屏幕共享应用程序。

发送图片:

public void SendSS()
        {
            try
            {


                while (!mainFrm.ssStop)
                {
                    ssTcpClient = new TcpClient();
                    ssTcpClient.Connect(mainFrm.contactIP, 1500);

                    //Set up TCP connection.          
                    if (ssTcpClient.Connected)
                    {
                        //Connected. Capture screen image.
                        labelText("Connected. Now sending desktop to technician.");
                        Image screenShotBMP = GrabScreen();
                        MemoryStream ssmemStream = new MemoryStream();
                        screenShotBMP.Save(ssmemStream, ImageFormat.Jpeg);         
                        NetworkStream ns = ssTcpClient.GetStream();

                        //Convert image to data.
                        byte[] bytesToSend = ssmemStream.GetBuffer();

                        //Store data in stream and send via port.                        
                        ns.Write(bytesToSend, 0, bytesToSend.Length);
                        ns.Flush();

                        //Dispose of image to avoid memory leakage.
                        screenShotBMP.Dispose();
                        ssTcpClient.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "SendSS()", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

接收图像:

public void ReceiveSS()
        {
            try
            {

                ssTcpListener = new TcpListener(IPAddress.Any, 1500);
                tcpReceiver = new TcpClient();
                while (!mainFrm.ssStop)
                {
                    //Start listening for connection.
                    //Accept any incoming connection requests on port 1500.
                    ssTcpListener.Start();
                    tcpReceiver = ssTcpListener.AcceptTcpClient();
                    if (tcpReceiver.Connected)
                    {
                        //TCP connected. Receive images from contact.
                        labelText("Connected. Now receiving desktop from client.");
                        NetworkStream receivedNs = new  NetworkStream(tcpReceiver.Client);

                        //Put image into picturebox.
                        Bitmap image = new Bitmap(receivedNs);
                        pboScrnShr.BackgroundImage = image;

                        receivedNs.Flush();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "ReceiveSS()", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

提前感谢您的帮助。

【问题讨论】:

  • 您可能会搜索“delta encoding”或“delta compression”,但当然您必须先将图像转换为未压缩的形式(例如 BMP、PNM.. 但不是 JPEG、PNG..)在计算增量之前。

标签: c# image tcp compare send


【解决方案1】:

在互联网上进行了更多搜索后,我发现了这个:

Finding difference between images - By Bryan Cook 使用该代码查找我发送的图像之间的差异(使用 screenshotBMP.Save(ssMemStream, ImageFormat.Gif),而不是 .JPEG),这当然将内存流中的透明度保存为黑色,以便接收最后,您必须确保(对于发送的图像差异)您确实收到了 Image.MakeTransparency(Color.Black),否则如果您尝试将差异叠加到前一张图像上,您只会得到黑屏。

我设法将接收到的图像从 12Mbps 降低到 2Mbps,但我知道对于较慢的连接还有更多的空间。

所有功劳归功于 Bryan Cook 我刚刚在不同上下文中使用的代码。

【讨论】: