Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning an Image from OperationContract method (WCF service)

Tags:

c#

image

wcf

I'm trying to get an Image from a WCF service.

I have an OperationContract function that returns an Image to the client, but when I call it from the client, I get this exception:

The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.9619978'.

Client:

private void btnNew_Click(object sender, EventArgs e)
{
    picBox.Picture = client.GetScreenShot();
}

Service.cs:

public Image GetScreenShot()
{
    Rectangle bounds = Screen.GetBounds(Point.Empty);
    using (Bitmap bmp = new Bitmap(bounds.Width,bounds.Height))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
        }
        using (MemoryStream ms = new MemoryStream())
        {
            bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Png);
            return Image.FromStream(ms);
        }
    }
}

IScreenShot Interface:

[ServiceContract]
public interface IScreenShot
{
    [OperationContract]
    System.Drawing.Image GetScreenShot();
}

So why is this happening and how do I fix it?

like image 227
Murhaf Sousli Avatar asked Dec 20 '22 21:12

Murhaf Sousli


2 Answers

I've figured it out.

  • First use TransferMode.Streamed or StreamedResponse (depends on your need).
  • Return the stream, and don't forget to set Stream.Postion = 0 so you start reading the stream from the beginning.

In the service:

public Stream GetStream()
{
    Rectangle bounds = Screen.GetBounds(Point.Empty);
    using (Bitmap bmp = new Bitmap(bounds.Width, bounds.Height))
    {
        using (Graphics g = Graphics.FromImage(bmp))
        {
            g.CopyFromScreen(Point.Empty, Point.Empty, bounds.Size);
        }
        MemoryStream ms = new MemoryStream();
        bmp.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
        ms.Position = 0;  // This is very important
        return ms;
    }
}

Interface:

[ServiceContract]
public interface IScreenShot
{
    [OperationContract]
    Stream GetStream();
}

On the client side:

public partial class ScreenImage: Form
{
    ScreenShotClient client;
    public ScreenImage(string baseAddress)
    {
        InitializeComponent();
        NetTcpBinding binding = new NetTcpBinding(SecurityMode.None);
        binding.TransferMode = TransferMode.StreamedResponse;
        binding.MaxReceivedMessageSize = 1024 * 1024 * 2;
        client = new ScreenShotClient(binding, new EndpointAddress(baseAddress));
    }

    private void btnNew_Click(object sender, EventArgs e)
    {
        picBox.Image = Image.FromStream(client.GetStream());
    }
}
like image 172
Murhaf Sousli Avatar answered Dec 23 '22 09:12

Murhaf Sousli


You can use Stream to return large data/Images.

Sample Example(returning Image as Stream) from MSDN

like image 28
Tilak Avatar answered Dec 23 '22 09:12

Tilak