How to compare two different images, send the difference via tcp then merge the difference with image on client?

StackOverflow https://stackoverflow.com/questions/22176065

  •  03-06-2023
  •  | 
  •  

Question

I have the code to send and receive images via TCP that works. However, because I am sending whole images each time the bandwidth use is huge and will make my program completely unusable on slower internet connections.

To reduce the bandwidth, it is clear I only want to send the difference between the current image and the previous one. I was hoping you could provide me with some information on how to do this, or which libraries, if any, to use. I have my send and receive threads below that I am currently using to send and receive images. The use for my program is as a screen-sharing application.

Sending Image:

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);
            }
        }

Receiving Image:

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);
            }
        }

Thanks for your help in advance.

Was it helpful?

Solution

After doing some more searching on the internet, I found this:

Finding difference between images - By Bryan Cook Using that code to find the differences between the images I sent those differences across (using screenshotBMP.Save(ssMemStream, ImageFormat.Gif), rather than .JPEG), this of course save the transparency in the memory stream as black so on the receiving end you have to make sure (for the image difference that is sent) that you do receiveImage.MakeTransparency(Color.Black) otherwise if you try to overlay the difference onto the previous image you'll just get a black screen.

I managed to reduce the image received from 12Mbps down to 2Mbps, I know there is still a little more to go for slower connections though.

All credit goes to Bryan Cook for the code I just used it in a different context.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top