HTTP Thumbnailer
HTTP API server for image thumbnailing and format conversion.
It is using ImageMagick or GraphicsMagick via RMagick gem as the image processing library.
Features
- thumbnailing images with different aspect ratio keeping methods
- identification of image foramt and size
- support of many input and output formats
- efficient API for generating multiple thumbnails from single input image with just one request
- many image scaling and loading performance optimizations
- efficient memory usage
- memory limits and disk memory offloading support
- based on Unicorn HTTP server with UNIX socket communication support
Changelog
1.1.0
- added identification API for image mime type and size identification
- stripping user meta data from input image further reducing output image size
- providing image size headers for input image and all generated thumbnails
- X-Input-Image-Content-Type header is now deprecated in favour of X-Input-Image-Content-Type
- not using ImageMagick for input image mime type resolution since it is accessing disk and behaves very inefficiently
Installing
You will need the following system packages installed: imagemagick
, pkg-config
and make
.
For PNG support install libpng
. You may want to consult ImageMagick installation guide for more information on supported formats and required libraries.
For Arch Linux you can use this commands:
pacman -S imagemagick
pacman -S libpng
pacman -S pkg-config
pacman -S make
Then you can install the gem as usual:
gem install httpthumbnailer
Optionally install Ruby client library and tool:
gem install httpthumbnailer-client
Usage
Getting started
# install httpthumbnailer (see above)
# install httpthumbnailer-client
gem install httpthumbnailer-client
# start thumbnailing server in foreground (to stop hit Ctlr-C)
httpthumbnailer --foreground --verbose
# in another console thumbnail to standard output
cat ~/Pictures/compute.jpg | httpthumbnailer-client -t crop,100,200,png > thumbnail.png
# generate multiple thumbnails
cat ~/Pictures/compute.jpg | httpthumbnailer-client -t crop,100,200,jpeg,quality:100 -t pad,200,200,png thumbnail1.jpg thumbnail2.png
In this example we use httpthumbnailer-client gem CLI tool that will use HTTP API of the server to generate thumbnails.
Running the server
HTTP Thumbnailer uses worker based server model thanks to Unicorn HTTP server gem.
To start the thumbnailer use httpthumbnailer
command.
By default it will start in background and will spawn CPU core number + 1 number of worker processes.
It will be listening on localhost port 3100.
To start in foreground with verbose output use httpthumbnailer --verbose --foreground
.
To see available switches and options use httpthumbnailer --help
.
When running in background the master server process will store it's PID in httpthumbnailer.pid
file. You can change pid file location with --pid-file
option.
If running as root you can use --user
option to specify user with whose privileges the worker processes will be running.
Logging
httpthumbnailer
logs to httpthumbnailer.log
file in current directory by default. You can change log file location with --log-file
option and verbosity with --verbose
or --debug
switch.
Additionally httpthumbnailer
will log requests in common NCSA format to httpthumbnailer_access.log
file. Use --access-log-file
option to change location of access log.
Supported operations
As operation type you can select one of the following options:
- fit - fit image within given dimensions keeping aspect ratio
- crop - cut image to fit within given dimensions keeping aspect ratio
- pad - fit scale image and pad image with background colour to given dimensions keeping aspect ratio
- limit - fit scale image to given dimensions if it is larger than that dimensions
Supported formats
List of supported formats can be displayed with httpthumbnailer --formats
.
Optionally format input
can be used to use the same thumbnail format as input image.
Thumbnail width and height
Width and height values are interpreted depending on operation.
input
string can be used for width and/or height to use input image width or height.
Thumbnail options
Following options can be used with thumbnail specification:
- quality - set output image quality; this is format specific: for JPEG 0 is maximum compression and 100 is maximum quality, for PNG first digit is zlib compression level and second one is filter level
- background-color - color in HTML notation or textual description ('red', 'green' etc.) used for background when processing transparent images or padding; by default white background is used
API
Single thumbnail API
To generate single thumbnail send input image with PUT request to URI in format:
/thumbnail/<operation type>,<width>,<height>,<format>[,<option key>:<option value>]*
Server will respond with thumbnail data with correct Content-Type header value.
For example the URI may look like this:
/thumbnail/pad,100,100,png,background-color:green
For detailed information about the API see cucumber features.
Multipart API
To generate multiple thumbnails of single image send that image with PUT request to URI in format:
/thumbnails/<operation type>,<width>,<height>,<format>[,<option key>:<option value>]*[/<operation type>,<width>,<height>,<format>[,<option key>:<option value>]*]*
Server will respond with multi-part content with each part containing Content-Type header and thumbnail data corresponding to format defined in the URI.
For example the URI may look like this:
/thumbnails/crop,16,16,png/crop,4,8,jpg/pad,16,32,jpeg
HTTP Thumbnailer will generate 3 thumbnails:
- 16x16 cropped PNG
- 4x8 cropped JPEG
- 16x32 colour padded JPEG
For detailed information about the API see cucumber features.
Identification API
You can identify image mime type, width and height with PUT request to URI in format:
/identify
Server will respond with JSON containing contentType, width and height fields:
{"mimeType":"image/jpeg","width":1239,"height":1750}
For detailed information about the API see cucumber features.
Ruby API client
To make it easier to use this server httpthumbnailer-client gem provides useful class.
Memory limits
Each worker uses ImageMagick memory usage limit feature.
By default it will use up to 128MiB of RAM and up to 1GiB of disk backed virtual memory.
To change this defaults use --limit-memory
option for RAM limit and --limit-disk
to control file backed memory mapping limit in MiB.
Status codes
HTTP Thumbnailer will respond with different status codes on different situations. If all goes well 200 OK will be returned otherwise:
400
- requested thumbnail method is not supported
- at least one image dimension is zero in thumbnail spec
- missing option key or value in thumbnail spec
- missing argument in in thumbnail spec
- bad argument value
413
- request body is too long
- input image is too big to fit in memory
- memory or pixel cache limit has been exceeded
415
- unsupported media type - see Supported formats section
500
- unexpected error has occurred - see the log file
Multipart API
In multipart API when error relates to single thumbnail Content-Type: plain/text
header will be used for that part.
In addition Status
header will be set for failing part with number corresponding to above status codes.
The body will contain description of the error.
Statistics API
HTTP Thumbnailer comes with statistics API that shows various runtime collected statistics.
It is set up under /stats
URI. You can also request single stat with /stats/<stat name>
request.
Example:
$ curl 127.0.0.1:3100/stats
total_requests: 119
total_errors: 1
calling: 1
writing: 0
total_images_loaded: 115
total_images_reloaded: 30
total_images_downscaled: 30
total_thumbnails_created: 147
images_loaded: 0
max_images_loaded: 3
max_images_loaded_worker: 3
total_images_created: 312
total_images_destroyed: 312
total_images_created_from_blob: 115
total_images_created_initialize: 53
total_images_created_resize: 101
total_images_created_crop: 13
total_images_created_sample: 30
total_write_multipart: 16
total_write: 101
total_write_part: 48
total_write_error: 1
total_write_error_part: 0
$ curl 127.0.0.1:3100/stats/total_write_multipart
16
See also
HTTP Image Store service is configurable image storage and processing HTTP API server that uses this service as thumbnailing backend.
Known Issues
- When 413 error is reported due to memory limit exhaustion the disk offloading won't work any more and only requests that can fit in the memory can be processed without getting 413 - this is due to a bug in ImageMagick v6.8.6-8 (2013-08-06 6.8.6-8) or less
- Mime type generated for images may not be the official mime type assigned for given format; please let me know of any inconsistencies or send a patch to get better output in efficient way
Contributing to HTTP Thumbnailer
- Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
- Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
- Fork the project
- Start a feature/bugfix branch
- Commit and push until you are happy with your contribution
- Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
- Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
Copyright
Copyright (c) 2013 Jakub Pastuszek. See LICENSE.txt for further details.