简体   繁体   中英

What's best performance way to constantly change image on WP7?

I'm trying to make my own type of remote desktop for WP7. I have a WCF service that returns an image on what's on the target machine's screen.

Here's the WCF Server Code:

    // Method to load desktop image
Bitmap image = new Bitmap( ViewSize.Width, ViewSize.Height );
Graphics g = Graphics.FromImage( image );

g.CopyFromScreen( Position.X, Position.Y, 0, 0, ViewSize );

g.Dispose( );
return image;

// Convert image to byte[] which is returned to client
using ( MemoryStream ms = new MemoryStream( ) )
{
    Bitmap image = screenGrabber.LoadScreenImage( );
    image.Save( ms, ImageFormat.Jpeg );
    imageArray = ms.ToArray( );
}

Here's the code for the WP7 client:

    MemoryStream stream = new MemoryStream( data );
BitmapImage image = new BitmapImage( );

image.SetSource( stream );
BackgroundImage.Source = image;

The BackgroundImage variable is an Image control.

I'm noticing this freeze on the emulator after a short while, and will eventually crash from an OutOfMemoryException. This is already pretty slow ( images show up a good half second later than what's on the screen ), and I'm wondering if there's a better/faster way of doing this? Any help would be great. Thanks in advance.

I think I can shed some light on your OutOfMemoryException. Are you aware of the IDisposable interface? The MemoryStream type is IDisposable so you must invoke Dispose on it to ensure that it is garbage collected and any resources it holds are freed. Your code should be as follows:

using(MemoryStream stream = new MemoryStream( data ))
{
  BitmapImage image = new BitmapImage( );
  image.SetSource( stream );
}

Regarding performance, real remote desktop (RDP) applications do not send the entire screen image every time something changes, they send partial updates in order to minimize bandwidth usage.

If you are going to go for a full screen refresh each time, make sure it is suitably scaled and compressed.

ColinE is right but there is a nuance. If you use his code it will automatically dispose the image once it has been set as the source. The result of this will either be an error indicating that you have trried to update the UI from a non UI thread or result in a problem when trying to visualize an allready disposed Bitmap.

Instead I would opt to keep a refrence to the current image, then change the image then use the refrence to the previous current image to dispose that image. Don't have access to an IDE atm but something alongst the lines of (assuming the code runs in the UI thread, otherwise you will have to also ensure that the code is evoked there).

MemoryStream stream = new MemoryStream( data ); BitmapImage image = new BitmapImage( );
image.SetSource( stream );

IDisposable toDispose = (IDisposable) BackgroundImage.Source;

BackgroundImage.Source = image;

toDispose.Dispose();

Also if you dan't want to reinvent to much of the wheel have a look at VNC, VNC# is a libary for it and it gives you a reasonable understanding of how others have done desktop remoting before

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM