Efficient way to send images via WCF?

You should be aware for this points:

  • Transport: TCP/binary message encoding will be fastest way to transfer your image data
  • Image capture: you can rely on P/Invoke to access your screen data, as this can be faster and more memory consuming. Some examples: Capturing the Screen Image in C# [P/Invoke], How to take a screen shot using .NET [Managed] and Capturing screenshots using C# (Managed)
  • You should to reduce your image data before send it;
    • choose your image format wisely, as some formats have native compression (as JPG)
    • an example should be Find differences between images C#
    • sending only diff image, you can crop it and just send non-empty areas
  • Try to inspect your WCF messages. This will help you to understand how messages are formatted and will help you to identify how to make that messages smaller.

Just after passing through all this steps and being satisfied with your final code, you can download VncSharp source code. It implements the RFB Protocol (Wikipedia entry), "a simple protocol for remote access to graphical user interfaces. Because it works at the framebuffer level it is applicable to all windowing systems and applications, including X11, Windows and Macintosh. RFB is the protocol used in VNC (Virtual Network Computing)."


I worked on a similar project a while back. This was my general approach:

  • Rasterized the captured bitmap to tiles of 32x32
  • To determine which tiles had changed between frames I used unsafe code to compare them 64-bits at a time
  • On the set of delta tiles I applied one of the PNG filters to improve compressability and had the best results with the Paeth filter
  • Used DeflateStream to compress the filtered deltas
  • Used BinaryMessageEncoding custom binding to the service to transmit the data in Binary in stead of the default Base64 encoded version

Some client-side considerations. When dealing with large amounts of data being transferred through a WCF service I found that some parameters of the HttpTransportBinding and the XmlDictionaryRenderQuotas were set to pretty conservative values. So you will want to increase them.