Thursday, December 15, 2011

How to use WPF in a web service?


Using WPF in a web service might seem bizarre, but consider the following scenarios:
  1. You need to burn in a watermark into images requested from web application,
  2. You want to apply a red-eye reduction process to photographs takes from a mobile application, or
  3. You want to apply a Jason Bourne night effect to images in a web mapping application.
We recently implemented something similar to the third scenario (see blog, source, live app). A client web application written in JavaScript, Flex or Silverlight could apply an image rendering effects by parsing an image’s url through a proxy service. The proxy service, using WPF, would apply a bitmap effect and return a modified image. This technique adds the power of WPF to thin client at the cost of minimal network latency.
Below is a detailed description of this proxy web service.
The following class is an ASP.NET generic web handler called “invert”. When published it will be accessible as ../virtualdirectory/invert.ashx. and will perform a color negative effect on parsed images. Because our server is accommodating multiple effects, one effect per handler, the web context is handed to static method to reduce the amount of redundant code.
public class Invert : IHttpHandler {
    public void ProcessRequest(HttpContext context) {
        Shader.Process(context, ShaderType.Invert);
    }
    public bool IsReusable {
        get { return false; }
    }
}
The code below is performing a number of important tasks. Firstly, because this proxy is published on the internet we need to add some restrictions so that it is only used as intended. The proxy will only entertain requests from web applications published on the maps.esri.com domain and it will only process images hosted on the services.arcgisonline.com domain. If the proxy request is legitimate, the remote image is downloaded and passed to a new background thread. The key is the creation of a background thread with a single-threaded apartment which is required to use COM and hence WPF.  The proxy (or IIS) process is put only hold as the WPF operation is underway.  The background thread returns a new image as an array of bytes which are then passed back to the client.
public class Shader {
    public static void Process(HttpContext context, ShaderType effect) {
        // Only accept request from apps from this domain!
        if (!context.Request.UrlReferrer.ToString().ToLowerInvariant().
                Contains("maps.esri.com")) {
            context.Response.StatusCode = 403;
            context.Response.End();
            return;
        }
            
        // Check for query string
        string query = Uri.UnescapeDataString(context.Request.QueryString.ToString());
        if (string.IsNullOrEmpty(query)) {
            context.Response.StatusCode = 403;
            context.Response.End();
            return;
        }
 
        // Filter requests
        if (!query.ToLowerInvariant().Contains("services.arcgisonline.com")) {
            context.Response.StatusCode = 403;
            context.Response.End();
            return;
        }
 
        // Create web request
        WebRequest webRequest = WebRequest.Create(new Uri(query));
        webRequest.Method = context.Request.HttpMethod;
 
        // Send the request to the server
        WebResponse serverResponse = null;
        try {
            serverResponse = webRequest.GetResponse();
        }
        catch (WebException webException) {
            context.Response.StatusCode = 500;
            context.Response.StatusDescription = webException.Status.ToString();
            context.Response.Write(webException.Response);
            context.Response.End();
            return;
        }
 
        // Exit if invalid response
        if (serverResponse == null) {
            context.Response.End();
            return;
        }
 
        // Configure reponse        context.Response.ContentType = serverResponse.ContentType;
        Stream stream = serverResponse.GetResponseStream();
 
        // Read response
        byte[] buffer = new byte[32768];
        int size = 0;
        int chunk;
        while ((chunk = stream.Read(buffer, size, buffer.Length - size)) > 0) {
            size += chunk;
            if (size != buffer.Length) { continue; }
            int nextByte = stream.ReadByte();
            if (nextByte == -1) { break; }
 
            // Resize the buffer
            byte[] newBuffer = new byte[buffer.Length * 2];
            Array.Copy(buffer, newBuffer, buffer.Length);
            newBuffer[size] = (byte)nextByte;
            buffer = newBuffer;
            size++;
        }
        serverResponse.Close();
        stream.Close();
 
        // Shrink buffer
        byte[] bytes = new byte[size];
        Array.Copy(buffer, bytes, size);
 
        // If the request is not a JPEG image then return data
        if (!serverResponse.ContentType.ToLowerInvariant().Contains("image/jpg")) {
            context.Response.OutputStream.Write(bytes, 0, bytes.Length);
            context.Response.End();
            return;
        }
 
        // Create class to send to STA backgroung thread
        ShaderWorker work = new ShaderWorker() {
            Source = bytes,
            ShaderEffect = effect
        };
 
        // Execute background thread
        Thread worker = new Thread(new ThreadStart(work.Execute));
        worker.SetApartmentState(ApartmentState.STA);
        worker.Name = "CreateImageWorker";
        worker.Start();
        worker.Join();
 
        // Return processed stream
        context.Response.OutputStream.Write(work.Target, 0, work.Target.Length);
        context.Response.End();
    }
}
This enumerator lists available pixel shaders. These shaders (or “effects”) were downloaded from the Windows Presentation Foundation Pixel Shader Effects Library.
public enum ShaderType {
    Emboss,
    Invert,
    Monochrome,
    Mosaic,
    Pixelate,
    Tint
}
And lastly, this is were the magic happens. This class is executed from the main IIS thread as a single-apartment thread as explained above. The source image is loaded as a generic BitmapImage in an Image, rendered with an effect and then exported to a new byte array.
public class ShaderWorker {
    public ShaderType ShaderEffect { private get; set; }
    public byte[] Source { private get; set; }
    public byte[] Target { get; private set; }
    public void Execute() {
        // Create bitmapimage
        MemoryStream m = new MemoryStream(this.Source);
        BitmapImage b = new BitmapImage();
        b.BeginInit();
        b.DecodePixelWidth = 256;
        b.DecodePixelHeight = 256;
        b.StreamSource = m;
        b.EndInit();
        b.Freeze();
 
        // Create image element
        Image i = new Image() {
            Source = b
        };
 
        // Assign shade effect
        switch (this.ShaderEffect) {
            case ShaderType.Emboss:
                i.Effect = new EmbossedEffect();
                break;
            case ShaderType.Invert:
                i.Effect = new InvertEffect();
                break;
            case ShaderType.Monochrome:
                i.Effect = new MonochromeEffect();
                break;
            case ShaderType.Mosaic:
                i.Effect = new MosaicEffect();
                break;
            case ShaderType.Pixelate:
                i.Effect = new PixelateEffect();
                break;
            case ShaderType.Tint:
                i.Effect = new TintEffect();
                break;
        }
 
        // Assign element size        i.Arrange(
            new System.Windows.Rect(
                new System.Windows.Size(256, 256)
            )
        );
        i.UpdateLayout();
 
        // Render image element to a new bitmap
        RenderTargetBitmap r = new RenderTargetBitmap(256, 256, 96, 96,
                                                      PixelFormats.Default);
        r.Render(i);
 
        // Create a new memory stream
        MemoryStream memoryStream = new MemoryStream();
 
        // Export bitmap to the stream
        JpegBitmapEncoder encoder = new JpegBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(r));
        encoder.Save(memoryStream);
 
        // Export the stream to a byte array
        byte[] bytes = memoryStream.ToArray();
        memoryStream.Close();
 
        // Shutdown rendering thread (if alive)
        if (r.Dispatcher.Thread.IsAlive) {
            r.Dispatcher.InvokeShutdown();
        }
 
        // Store processed image (as a byte array)
        this.Target = bytes;
    }
}
In summary, this post describes the technique of using WPF in a web service to perform advanced rendering. In theory, this technique is not restricted to image processing but could also be used to generate graphics of charts, diagrams and even three dimensional scenes. During limited testing it is obvious that this technique introduces network latency, particularly when the service has been dormant. And what is still unknown is whether the rendering is performed in hardware (i.e. GPU) or software (i.e. CPU). Please comment below if you know the answer to this or know of a definitive test for GPU vs. CPU.

18 comments:

  1. Great article! To answer your question, RenderTargetBitmap always uses the software renderer, which may be to advantage on most servers without gpus.

    Microsoft may tell you this isn't a technically supported scenario, but it works none the less! You may alternatively look at D2D as it supports software And hw rendering on the server, but v1 does not support shaders. vNext does but unknown if it is win8 only.

    ReplyDelete
  2. Hi Jeremiah, thanks for the clarification and tip.

    ReplyDelete
  3. can you please send me code at aajay78@hotmail.com

    ReplyDelete
  4. Thank You for sharing your article. I like it. We provide TIBCO Online Training in Hyderabad.

    ReplyDelete
  5. GIS Training Program by GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.


    GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.
    GIS Training Institute

    Dear Trainee,

    We,GEOSYS ENTERPRISE SOLUTION PVT.LTD. are cordially inviting you for the
    training program in ArcGIS Desktop,Arc Objects,ArcGIS Server, ArcGIS Online, ArcGIS Web API for JavaScript and many other GIS courses. Our department has conducted so many training programs successfully in the above fields.
    So please utilise our training programs for their future growth.


    Courses:

    GIS-Data Development Training(ArcGIS Desktop) : 30days
    GIS – Data Development Course

    GIS-Application Development Training(Arc Objects) : 30days
    GIS – Application Development Course

    ArcGIS Server: 30days
    server


    ArcGIS Online: 30days
    online



    ArcGIS Web API for JavaScript: 30days

    Thanking you,

    Regards

    GEOSYS ENTERPRISE SOLUTIONs PVT. LTD.

    Contact: +919493880670, +914065522333 Email: info@geosys.co.in

    Website: www.geosys.co.in
    GIS Training In Hyderabad

    ReplyDelete
  6. GIS Training Program by GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.


    GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.
    GIS Training Institute

    Dear Trainee,

    We,GEOSYS ENTERPRISE SOLUTION PVT.LTD. are cordially inviting you for the
    training program in ArcGIS Desktop,Arc Objects,ArcGIS Server, ArcGIS Online, ArcGIS Web API for JavaScript and many other GIS courses. Our department has conducted so many training programs successfully in the above fields.
    So please utilise our training programs for their future growth.


    Courses:

    GIS-Data Development Training(ArcGIS Desktop) : 30days
    GIS – Data Development Course

    GIS-Application Development Training(Arc Objects) : 30days
    GIS – Application Development Course

    ArcGIS Server: 30days
    server


    ArcGIS Online: 30days
    online



    ArcGIS Web API for JavaScript: 30days

    Thanking you,

    Regards

    GEOSYS ENTERPRISE SOLUTIONs PVT. LTD.

    Contact: +919493880670, +914065522333 Email: info@geosys.co.in

    Website: www.geosys.co.in
    GIS Training In Hyderabad

    ReplyDelete
  7. GIS Training Program by GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.

    GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.
    GIS Training Institute

    Dear Trainee,

    We,GEOSYS ENTERPRISE SOLUTION PVT.LTD. are cordially inviting you for the
    training program in ArcGIS Desktop,Arc Objects,ArcGIS Server, ArcGIS Online, ArcGIS Web API for JavaScript and many other GIS courses. Our department has conducted so many training programs successfully in the above fields.
    So please utilise our training programs for their future growth.


    Courses:

    GIS-Data Development Training(ArcGIS Desktop) : 30days
    GIS – Data Development Course
    GIS-Application Development Training(Arc Objects) : 30days
    GIS – Application Development Course
    ArcGIS Server: 30days
    ArcGIS Server
    ArcGIS Online: 30days
    ArcGIS Online
    ArcGIS Web API for JavaScript: 30days

    Thanking you,

    Regards

    GEOSYS ENTERPRISE SOLUTIONs PVT. LTD.

    Contact: +919493880670, +914065522333 Email: info@geosys.co.in

    Website: www.geosys.co.in

    ReplyDelete
  8. GIS Training Program by GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.

    GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.
    GIS Training Institute

    Dear Trainee,

    We,GEOSYS ENTERPRISE SOLUTION PVT.LTD. are cordially inviting you for the
    training program in ArcGIS Desktop,Arc Objects,ArcGIS Server, ArcGIS Online, ArcGIS Web API for JavaScript and many other GIS courses. Our department has conducted so many training programs successfully in the above fields.
    So please utilise our training programs for their future growth.


    Courses:

    GIS-Data Development Training(ArcGIS Desktop) : 30days
    GIS-Application Development Training(Arc Objects) : 30days
    ArcGIS Server: 30days
    ArcGIS Online: 30days
    ArcGIS Web API for JavaScript: 30days

    Thanking you,

    Regards

    GEOSYS ENTERPRISE SOLUTIONs PVT. LTD.

    Contact: +919493880670, +914065522333 Email: info@geosys.co.in

    Website: www.geosys.co.in

    ReplyDelete
  9. GIS Training Program by GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.

    GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.
    GIS Training Institute

    Dear Trainee,

    We,GEOSYS ENTERPRISE SOLUTION PVT.LTD. are cordially inviting you for the
    training program in ArcGIS Desktop,Arc Objects,ArcGIS Server, ArcGIS Online, ArcGIS Web API for JavaScript and many other GIS courses. Our department has conducted so many training programs successfully in the above fields.
    So please utilise our training programs for their future growth.


    Courses:

    GIS-Data Development Training(ArcGIS Desktop) : 30days
    GIS – Data Development Course
    GIS-Application Development Training(Arc Objects) : 30days
    GIS – Application Development Course
    ArcGIS Server: 30days
    ArcGIS Server
    ArcGIS Online: 30days
    ArcGIS Online
    ArcGIS Web API for JavaScript: 30days

    Thanking you,

    Regards

    GEOSYS ENTERPRISE SOLUTIONs PVT. LTD.

    Contact: +919493880670, +914065522333 Email: info@geosys.co.in

    Website: www.geosys.co.in
    GIS Training

    ReplyDelete
  10. GIS Training Program by GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.

    GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.
    GIS Training Institute

    Dear Trainee,

    We,GEOSYS ENTERPRISE SOLUTION PVT.LTD. are cordially inviting you for the
    training program in ArcGIS Desktop,Arc Objects,ArcGIS Server, ArcGIS Online, ArcGIS Web API for JavaScript and many other GIS courses. Our department has conducted so many training programs successfully in the above fields.
    So please utilise our training programs for their future growth.


    Courses:

    GIS-Data Development Training(ArcGIS Desktop) : 30days
    GIS – Data Development Course
    GIS-Application Development Training(Arc Objects) : 30days
    GIS – Application Development Course
    ArcGIS Server: 30days
    ArcGIS Server
    ArcGIS Online: 30days
    ArcGIS Online
    ArcGIS Web API for JavaScript: 30days

    Thanking you,

    Regards

    GEOSYS ENTERPRISE SOLUTIONs PVT. LTD.

    Contact: +919493880670, +914065522333 Email: info@geosys.co.in

    Website: www.geosys.co.in
    GIS Training

    ReplyDelete
  11. GIS Training Program by GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.

    GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.
    GIS Training Institute

    Dear Trainee,

    We,GEOSYS ENTERPRISE SOLUTION PVT.LTD. are cordially inviting you for the
    training program in ArcGIS Desktop,Arc Objects,ArcGIS Server, ArcGIS Online, ArcGIS Web API for JavaScript and many other GIS courses. Our department has conducted so many training programs successfully in the above fields.
    So please utilise our training programs for their future growth.


    Courses:

    GIS-Data Development Training(ArcGIS Desktop) : 30days
    GIS – Data Development Course
    GIS-Application Development Training(Arc Objects) : 30days
    GIS – Application Development Course
    ArcGIS Server: 30days
    ArcGIS Server
    ArcGIS Online: 30days
    ArcGIS Online
    ArcGIS Web API for JavaScript: 30days

    Thanking you,

    Regards

    GEOSYS ENTERPRISE SOLUTIONs PVT. LTD.

    Contact: +919493880670, +914065522333 Email: info@geosys.co.in

    Website: www.geosys.co.in
    GIS Training

    ReplyDelete
  12. GEOSYS ENTERPRISE SOLUTIONS PVT. LTD.
    We,GEOSYS ENTERPRISE SOLUTION PVT.LTD. are cordially inviting you for the
    training program in ArcGIS Desktop,Arc Objects,ArcGIS Server, ArcGIS Online, ArcGIS Web API for JavaScript and many other GIS courses. Our department has conducted so many training programs successfully in the above fields. Geosys is the best GIS Training Center in Hyderabad.
    So please utilise our training programs for their future growth.

    Courses:
    GIS-Data Development (ArcGIS Desktop) : 30days
    GIS-Application Development (Arc Objects) : 30days
    ArcGIS Server: 30days
    ArcGIS Online: 30days
    ArcGIS Web API for JavaScript: 30days

    Thanking you,
    Regards
    GEOSYS ENTERPRISE SOLUTIONs PVT. LTD.
    Contact: +919493880670, +914065522333 Email: info@geosys.co.in
    www.geosys.co.in
    Geosys GIS Training

    ReplyDelete
  13. Geosys GIS-Application Development Course is a collection of GIS components and developer resources that can be embedded, allowing you to add dynamic mapping and GIS capabilities to existing applications or build new custom mapping applications.
    Developers use GIS-Application Development Course to deploy GIS data, maps, and Geoprocessing scripts in desktop or mobile applications using application programming interfaces (APIs) for COM, .NET, Java, and C++.
    GIS-Application Development Course

    ReplyDelete
  14. Geosys provides comprehensive HR Solutions through a single window across various domains to enhance the success of your organization. Our customized HR Solutions are formulated based on organization needs hence, they are best suited for the business. Our services are designed to make a difference to human resource management through our unique methodologies.
    Geosys Consulting Services:
    Policies Development
    Recruitment
    contract staffing
    Training and Development
    Perfomance Management system
    Employee engagement
    Geosys Consulting services

    ReplyDelete
  15. Geosys GIS - Data Development Course will help you to understand what a Geographic Information System is and why organizations around the world rely on GIS technology. You will learn how GIS maps are different from other types of paper and digital maps, what makes the data used in a GIS unique, and how to use GIS software to obtain information and create meaningful maps. In our Customized course curriculum, You will be given hands on exercises and activities, you will work with GIS software and see how a GIS supports in problem solving in many different contexts.
    GIS-Data Development Course

    ReplyDelete
  16. This course imparts fundamental GIS Development concepts with a focus on developing custom GIS applications using the Microsoft .NET Framework.
    This course provides the foundational knowledge and skills needed to take Developing Applications Using the Microsoft .NET Framework, Extending the GIS Applications, and Developing Web Applications using the Microsoft .NET Framework
    Geosys is the best GIS training institute in hyderabad. We Provide Training & Placement Assistance Also. New Batch Start from 3rd August 2017
    Geosys Enterprise Solutions Pvt. Ltd, 6-3-841/A/2/C1, Arun Aditya Building, Ameerpet,Hyderabad-500016, India Phone: 9581817878
    GIS Application Development Course

    ReplyDelete