Pilbox is an image resizing application server built on Python's Tornado web framework using the Python Imaging Library (Pillow). It is not intended to be the primary source of images, but instead acts as a proxy which requests images and resizes them as desired.
- Python 2.7
- Pillow 2.1.0
- Tornado 3.1
- OpenCV 2.x
- Image Libraries: libjpeg-dev, libfreetype6, libfreetype6-dev, zlib1g-dev
Packaged with Pilbox is a Vagrant configuration file which installs all necessary dependencies on a virtual box. See the Vagrant documentation for installation instructions. Once installed, the following will start a virtual machine.
$ vagrant up
To access the virtual machine itself, simply...
$ vagrant ssh
To run the application, issue the following command
$ python -m pilbox.app
By default, this will run the application on port 8888 and can be accessed by visiting:
http://localhost:8888/
To see a list of all available options, run
$ python -m pilbox.app --help
When running via Vagrant, the application is automatically started on port 8888 on 192.168.100.100, i.e.
http://192.168.100.100:8888/
To use the image resizing service, include the application url as you would any other image. E.g. this image url
<img src="http://i.imgur.com/zZ8XmBA.jpg" />
Would be replaced with this image url
<img src="http://localhost:8888/?url=http%3A%2F%2Fi.imgur.com%2FzZ8XmBA.jpg&w=300&h=300&mode=crop" />
This will request the image served at the supplied url and resize it to 300x300 using the crop mode. The following is the list of parameters that can be supplied to the service
- url: The url of the image to be resized
- w: The desired width of the image
- h: The desired height of the image
- mode: The resizing method: clip, crop (default), fill and scale
- clip: Resize to fit within the desired region, keeping aspect ratio
- crop: Resize so one dimension fits within region, center, cut remaining
- fill: Fills the clipped space with a background color
- scale: Resize to fit within the desired region, ignoring aspect ratio
- bg: Background color used with fill mode, 3- or 6-digit hexadecimal number
- pos: The crop position
- top-left: Crop from the top left
- top: Crop from the top center
- top-right: Crop from the top right
- left: Crop from the center left
- center: Crop from the center
- right: Crop from the center right
- bottom-left: Crop from the bottom left
- bottom: Crop from the bottom center
- bottom-right: Crop from the bottom right
- face: Identify faces and crop from the midpoint of their position(s)
- client: The client name
- sig: The signature
The url
, and either w
or h
parameters are required. If only one dimension is specified, the application will determine the other dimension using the aspect ratio. mode
is optional and defaults to crop
. bg
is optional and defaults to fff
. pos
is optional and defaults to center
. client
is required only if the client_name
is defined within the configuration file. Likewise, sig
is required only if the client_key
is defined within the configuration file. See the signing section for details on how to generate the signature.
To run all tests, issue the following command
$ python -m pilbox.test.runtests
To run individual tests, simply indicate the test to be run, e.g.
$ python -m pilbox.test.runtests pilbox.test.signature_test
In order to secure requests so that unknown third parties cannot easily use the resize service, the application can require that requests provide a signature. To enable this feature, set the client_key
option. The signature is a hexadecimal digest generated from the client key and the query string using the HMAC-SHA1 message authentication code (MAC) algorithm. The below python code provides an example implementation.
import hashlib
import hmac
def derive_signature(key, qs):
m = hmac.new(key, None, hashlib.sha1)
m.update(qs)
return m.hexdigest()
The signature is passed to the application by appending the sig
paramater to the query string; e.g. x=1&y=2&z=3&sig=c9516346abf62876b6345817dba2f9a0c797ef26
. Note, the application does not include the leading question mark when verifying the supplied signature. To verify your signature implementation, see the pilbox.signature
command described in the tools section.
To verify that your client application is generating correct signatures, use the signature command.
$ python -m pilbox.signature --key=abcdef "x=1&y=2&z=3"
Query String: x=1&y=2&z=3
Signature: c9516346abf62876b6345817dba2f9a0c797ef26
Signed Query String: x=1&y=2&z=3&sig=c9516346abf62876b6345817dba2f9a0c797ef26
The application allows the use of the resize functionality via the command line.
$ python -m pilbox.image --width=300 --height=300 http://i.imgur.com/zZ8XmBA.jpg > /tmp/foo.jpg
If a new mode is added or a modification was made to the libraries that would change the current expected output for tests, run the generate test command to regenerate the expected output for the test cases.
$ python -m pilbox.test.genexpected
The application itself does not include any caching. It is recommended that the application run behind a CDN for larger applications or behind varnish for smaller ones.
- Add backends (S3, file system, etc...) if necessary