Due Tuesday 3/20 at start of class.
In this lab, you'll get some experience developing a client and server that can communicate using SOAP. We'll depart for a bit from the code you've been developing for previous labs, although you'll re-integrate it when we get to Project 1.
To turn in: Please place a copy of your code in your cs682 submit directory. Also, please place a README in the submit directory containing all instructions needed to run your code.
In this assignment, we'll develop a simple SOAP-based web service to list, process, transform, and share images. You may do this assignment using whatever language, image processing toolkit, and SOAP library you like. I will provide illustrations using PIL and SOAPpy. If you're using Java, Apache Axis is the SOAP library to use. If you're using Ruby, the built-in SOAP library looks pretty good.
Recall that SOAP takes a procedural approach to web services. A server exposes a set of functions to clients, who consume them as if they were working with local functions. This is in contrast to REST, which takes a data-oriented approach to web services.
We'll later be extending this lab when we develop out P2P server.
On data, URLs, and serializationThroughout this lab, we'll be sending URLs of images between client and server, rather than the images themselves. There are a few reasons for this - for example, images can be quite large when serialized and images can get corrupted in the conversion to a base64 string. Instead, we'll send references to images using URLs.
Building a SOAP serverWe'll begin by building a simple SOAP server, based on the hello world example provided with SOAPpy. You can find the code here.
We start by defining a method called hello() that returns a string. Then, inside main, we create a SOAPServer, register the 'hello' function with it, and then start the server.
Building a SOAP ClientNext, let's look at the client. The code can be found here. Again, we import SOAPpy, then create a SOAPProxy. It takes as input a URL that matches the hostname and port we registered the server with. (you may not want to use localhost) We then invoke the 'hello' method.
Working with ImagesHello world is fine, but not very interesting. Let's build a SOAP server that can do remote processing of images. We'll provide the server with a URL. It will fetch the image at that URL, process it, and then return a URL referencing the processed image.
Here's a start for a client. You can find the code here.
#!/usr/bin/python import SOAPpy import Image if __name__ == '__main__' : server = SOAPpy.SOAPProxy("http://localhost:8080/") url = server.rotate('http://www.cs.usfca.edu/~brooks/me-primary.jpg', 90) print urlThe client sends a URL and an amount to rotate the picture. The server returns a URL indicating the rotated picture.
Now for the server - it's a bit more complex, but not much. The code can be found here.
#!/usr/bin/python import SOAPpy import Image from StringIO import StringIO import urllib import os destdir = "/home/web/brooks" destURL = "http://www.cs.usfca.edu/~brooks/" def rotate(url, degrees) : ## rotate the image im = Image.open(StringIO(urllib.urlopen(url).read())) newIm = im.rotate(degrees) ## get the filename index = url.rfind('/') fname = url[index+1:] base = url[:index] (prefix, extension) = fname.split('.') newname = prefix + "rotated" + "." + extension ## write the file. newIm.save(destdir + "/" + newname) os.chmod(destdir + "/" + newname, 0755) ## send back the URL return destURL + newname if __name__ == '__main__' : server = SOAPpy.SOAPServer(("localhost", 8080)) server.registerFunction(rotate) server.serve_forever()We create a rotate() function that takes as input a URL and the degrees to rotate it. We then read the contents of the URL into an image (using StringIO as a buffer), and rotate it. We write the new image out to a file and send the URL referencing that file back to the client.
The assignmentWrite a client and server that can perform the following image operations. All functions should take a URL as input and return the URL of the modified image.
- rotate(image, ndegrees) - rotates image clockwise by n degrees
- resize(image, newX, newY) - resizes image to be newX x newY pixels.
- scale (image, percentage) - scales the image by the given percentage.
- thumbnail(image, width, height) - returns a thumbnail if the image of dimension width x height.
- blur(image) - apply standard blur filter.
- sharpen(image) - apply standard sharpen filter.
- normalize(image) - apply autocontrast.
- equalize(image) - Apply equalization to uniformly distribute grayscale.
- crop(image, (left, Upper, right, lower)) - crop image according to the dimensions provided in the tuple.
- grayscale(image) - convert image to grayscale