G Gr
G Gr

Reputation: 6090

WCF/REST Get image into picturebox?

So I have wcf rest service which succesfuly runs from a console app, if I navigate to: http://localhost:8000/Service/picture/300/400 my image is displayed note the 300/400 sets the width and height of the image within the body of the html page.

The code looks like this:

namespace WcfServiceLibrary1
{
    [ServiceContract]
    public interface IReceiveData
    {
        [OperationContract]
        [WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "picture/{width}/{height}")]
        Stream GetImage(string width, string height);
    }
    public class RawDataService : IReceiveData
    {
        public Stream GetImage(string width, string height)
        {
                int w, h;

                if (!Int32.TryParse(width, out w))
                {
                    w = 640;
                }
                // Handle error
                if (!Int32.TryParse(height, out h))
                {
                    h = 400;
                }
            Bitmap bitmap = new Bitmap(w, h); 
            for (int i = 0; i < bitmap.Width; i++)
            {
                for (int j = 0; j < bitmap.Height; j++)
                {
                    bitmap.SetPixel(i, j, (Math.Abs(i - j) < 2) ? Color.Blue : Color.Yellow);
                }
            }
            MemoryStream ms = new MemoryStream();
            bitmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);
            ms.Position = 0;
            WebOperationContext.Current.OutgoingResponse.ContentType = "image/jpeg";
            return ms;
        }
    }
}

What I want to do now is use a client application "my windows form app" and add that image into a picturebox. Im abit stuck as to how this can be achieved as I would like the width and height of the image from my wcf rest service to be set by the width and height of the picturebox. I have tryed this but on two of the lines have errors and im not even sure if it will work as the code for my wcf rest service seperates width and height with a "/" if you notice in the url.

    string uri = "http://localhost:8080/Service/picture";
    private void button1_Click(object sender, EventArgs e)
    {

        StringBuilder sb = new StringBuilder();
        sb.AppendLine("<picture>");
        sb.AppendLine("<width>" + pictureBox1.Image.Width + "</width>");
        // the url looks like this http://localhost:8080/Service/picture/300/400 when accessing the image so I am trying to set this here
        sb.AppendLine("<height>" + pictureBox1.Image.Height + "</height>");
        sb.AppendLine("</picture>");
        string picture = sb.ToString();
        byte[] getimage = Encoding.UTF8.GetBytes(picture); // not sure this is right
        HttpWebRequest req = WebRequest.Create(uri); //cant convert webrequest to httpwebrequest
        req.Method = "GET";
        req.ContentType = "image/jpg";
        req.ContentLength = getimage.Length; 
        MemoryStream reqStrm = req.GetRequestStream(); //cant convert IO stream to IO Memory stream
        reqStrm.Write(getimage, 0, getimage.Length); 
        reqStrm.Close();
        HttpWebResponse resp = req.GetResponse(); // cant convert web respone to httpwebresponse
        MessageBox.Show(resp.StatusDescription);
        pictureBox1.Image = Image.FromStream(reqStrm);
        reqStrm.Close();
        resp.Close();
    }

So just wondering if some one could help me out with this futile attempt at adding a variable image size from my rest service to a picture box on button click.

This is the host app aswell:

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string baseAddress = "http://" + Environment.MachineName + ":8000/Service";
            ServiceHost host = new ServiceHost(typeof(RawDataService), new Uri(baseAddress));
            host.AddServiceEndpoint(typeof(IReceiveData), new WebHttpBinding(), "").Behaviors.Add(new WebHttpBehavior());
            host.Open();
            Console.WriteLine("Host opened");
            Console.ReadLine();

Upvotes: 3

Views: 2741

Answers (2)

Opsimath
Opsimath

Reputation: 1997

WRT your comment about the width and height parameters being separated by '/'s in your request URL a more RESTful approach would be to pass them as parameters, e.g. the URL would look like:

http://localhost:8000/Service/picture?width=480&height=640

and your WebInvoke would look like:

[WebInvoke(Method = "GET", BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Xml, UriTemplate = "picture?width={width}&height={height}")]

The GetImage method need not change, the parameters will be populated the same as they were with the original UriTemplate.

Upvotes: 1

Clemens
Clemens

Reputation: 128098

A WinForms-based method to get the image with variable width and height would look like this:

public Image GetImage(int width, int height)
{
    string uri = string.Format("http://localhost:8000/Service/picture/{0}/{1}", width, height);
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(uri);

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    {
        using (Stream stream = response.GetResponseStream())
        {
            return new Bitmap(stream);
        }
    }
}

You might put the image to a PictureBox like this:

private void Form1_Load(object sender, EventArgs e)
{
    pictureBox.Image = GetImage(400, 500); // or any other size here
}

In WPF you would do something like this:

public ImageSource GetImage(int width, int height)
{
    string uri = string.Format("http://localhost:8000/Service/picture/{0}/{1}", width, height);
    return BitmapFrame.Create(new Uri(uri));
}

Upvotes: 3

Related Questions