Package: pilbox
PilboxPilbox is an image processing application server built on Python’sTornado web frameworkusing
thePython 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.SetupDependenciesPython >= 2.7Pillow 5.2.0Tornado 5.1.0OpenCV 2.x(optional)PycURL 7.x(optional, but
recommended; required for proxy requests and requests over TLS)Image Libraries: libjpeg-dev, libfreetype6-dev, libwebp-dev,
zlib1g-dev, liblcms2-devPilbox highly recommends installinglibcurlandpycurlin order
to get better HTTP request performance as well as additional features
such as proxy requests and requests over TLS. Installed versions oflibcurlshould be a minimum of7.21.1andpycurlshould be a
minimum of7.18.2. Furthermore, it is recommended that thelibcurlinstallation be built with asynchronous DNS resolver
(threaded or c-ares), otherwise it may encounter various problems with
request timeouts (for more information, seeCURLOPT_CONNECTTIMEOUT_MSand comments incurl_httpclient.py)InstallPilbox can be installed with pip$ pip install pilboxOr easy_install$ easy_install pilboxOr from source$ git clone https://github.com/agschwender/pilbox.gitRunningTo run the application, issue the following command$ python -m pilbox.appBy 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
Usage: pilbox/app.py [OPTIONS]

Options:

  --allowed_hosts            list of allowed hosts (default [])
  --allowed_operations       list of allowed operations (default [])
  --background               default hexadecimal bg color (RGB or ARGB)
  --ca_certs                 filename of CA certificates in PEM format
  --client_key               client key
  --client_name              client name
  --config                   path to configuration file
  --content_type_from_image  override content type using image mime type
  --debug                    run in debug mode
  --expand                   default to expand when rotating
  --filter                   default filter to use when resizing
  --help                     show this help information
  --implicit_base_url        prepend protocol/host to url paths
  --max_operations           maximum operations to perform (default 10)
  --max_requests             max concurrent requests (default 40)
  --max_resize_height        maximum resize height (default 15000)
  --max_resize_width         maximum resize width (default 15000)
  --operation                default operation to perform
  --optimize                 default to optimize when saving
  --port                     run on the given port (default 8888)
  --position                 default cropping position
  --preserve_exif            default behavior for Exif information
  --progressive              default to progressive when saving
  --proxy_host               proxy hostname
  --proxy_port               proxy port
  --quality                  default jpeg quality, 1-99 or keep
  --retain                   default adaptive retain percent, 1-99
  --timeout                  timeout of requests in seconds (default 10)
  --user_agent               user agent
  --validate_cert            validate certificates (default True)
  --workers                  number of worker processes (0 = auto) (default 0)CallingTo use the image processing 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 to300x300using thecropmode. The below is the list of parameters
that can be supplied to the service.General Parametersurl: The url of the image to be resizedop: The operation to perform: noop, region, resize (default), rotatenoop: No operation is performed, image is returned as it is
receivedregion: Select a sub-region from the imageresize: Resize the imagerotate: Rotate the imagefmt: The output format to save as, defaults to the source formatgif: Save as GIFjpeg: Save as JPEGpng: Save as PNGwebp: Save as WebPtiff: Save as TIFFbg: Background color used with images that have transparency;
useful when saving to a format that does not support transparencyRGB: 3- or 6-digit hexadecimal numberARGB: 4- or 8-digit hexadecimal number, only relevant for PNG
imagesopt: The output should be optimized, only relevant to JPEGs and PNGsexif: Keep originalExifdata in the processed image, only relevant for JPEGprog: Enable progressive output, only relevant to JPEGsq: The quality, (1-99) or keep, used to save the image, only relevant
to JPEGsResize Parametersw: The desired width of the imageh: The desired height of the imagemode: The resizing method: adapt, clip, crop (default), fill and scaleadapt: Resize using crop if the resized image retains a supplied
percentage of the original image; otherwise fillclip: Resize to fit within the desired region, keeping aspect
ratiocrop: Resize so one dimension fits within region, center, cut
remainingfill: Fills the clipped space with a background colorscale: Resize to fit within the desired region, ignoring aspect
ratiobg: Background color used with fill mode (RGB or ARGB)RGB: 3- or 6-digit hexadecimal numberARGB: 4- or 8-digit hexadecimal number, only relevant for PNG
imagesfilter: The filtering algorithm used for resizingnearest: Fastest, but often images appear pixelatedbilinear: Faster, can produce acceptable resultsbicubic: Fast, can produce acceptable resultsantialias: Slower, produces the best resultspos: The crop positiontop-left: Crop from the top lefttop: Crop from the top centertop-right: Crop from the top rightleft: Crop from the center leftcenter: Crop from the centerright: Crop from the center rightbottom-left: Crop from the bottom leftbottom: Crop from the bottom centerbottom-right: Crop from the bottom rightface: Identify faces and crop from the midpoint of their
position(s)x,y: Custom center point position ratio, e.g. 0.0,0.75retain: The minimum percentage (1-99) of the original image that
must still be visible in the resized image in order to use crop modeRegion Parametersrect: The region as x,y,w,h; x,y: top-left position, w,h:
width/height of regionRotate Parametersdeg: The desired rotation angle degrees0-359: The number of degrees to rotate (clockwise)auto: Auto rotation based on Exif orientation, only relevant to JPEGsexpand: Expand the size to include the full rotated imageSecurity-related Parametersclient: The client namesig: The signatureTheurlparameter is always required as it dictates the image that
will be manipulated.opis optional and defaults toresize. It
also supports a comma separated list of operations, where each operation
is applied in the order that it appears in the list. Depending on the
operation, additional parameters are required. All image manipulation
requests acceptexif,fmt,opt,progandq.exifis optional and default to0(not preserved).fmtis optional
and defaults to the source image format.optis optional and
defaults to0(disabled).progis optional and default to0(disabled).qis optional and defaults to90. To ensure
security, all requests also support,clientandsig.clientis required only if theclient_nameis defined within the
configuration file. Likewise,sigis required only if theclient_keyis defined within the configuration file. See theSigningsection for details on how to generate the signature.For resizing, either theworhparameter is required. If only
one dimension is specified, the application will determine the other
dimension using the aspect ratio.modeis optional and defaults tocrop.filteris optional and defaults toantialias.bgis optional and defaults to0fff.posis optional and defaults
tocenter.retainis optional and defaults to75.For region sub-selection,rectis required. For rotating,degis
required.expandis optional and defaults to0(disabled). It is
recommended that this feature not be used as it typically does not
produce high quality images.Note, all built-in defaults can be overridden by setting them in the
configuration file. See theConfigurationsection
for more details.ExamplesThe following images show the various resizing modes in action for an
original image size of640x428that is being resized to500x400.AdaptThe adaptive resize mode combines bothcropandfillresize modes
to ensure that the image always matches the requested size and a minimum
percentage of the image is always visible. Adaptive resizing will first
calculate how much of the image will be retained if crop is used. Then,
if that percentage is equal to or above the requested minimum retained
percentage, crop mode will be used. If it is not, fill will be used. The
first figure uses aretainvalue of80to illustrate the
adaptive crop behavior.Whereas the second figure requires a minimum of99to illustrate the
adaptive fill behaviorClipThe image is resized to fit within a500x400box, maintaining aspect
ratio and producing an image that is500x334. Clipping is useful
when no portion of the image can be lost and it is acceptable that the
image not be exactly the supplied dimensions, but merely fit within the
dimensions.CropThe image is resized so that one dimension fits within the500x400box. It is then centered and the excess is cut from the image. Cropping
is useful when the position of the subject is known and the image must
be exactly the supplied size.FillSimilar to clip, fill resizes the image to fit within a500x400box.
Once clipped, the image is centered within the box and all left over
space is filled with the supplied background color. Filling is useful
when no portion of the image can be lost and it must be exactly the
supplied size.ScaleThe image is clipped to fit within the500x400box and then
stretched to fill the excess space. Scaling is often not useful in
production environments as it generally produces poor quality images.
This mode is largely included for completeness.SigningIn 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 theclient_keyoption. 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 thesigparameter 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 thepilbox.signaturecommand described in theToolssection.ConfigurationAll options that can be supplied to the application via the command
line, can also be specified in the configuration file. Configuration
files are simply python files that define the options as variables. The
below is an example configuration.# General settings
port = 8888

# One worker process per CPU core
workers = 0

# Set client name and key if the application requires signed requests. The
# client must sign the request using the client_key, see README for
# instructions.
client_name = "sample"
client_key = "3NdajqH8mBLokepU4I2Bh6KK84GUf1lzjnuTdskY"

# Set the allowed hosts as an alternative to signed requests. Only those
# images which are served from the following hosts will be requested.
allowed_hosts = ["localhost"]

# Request-related settings
max_requests = 50
timeout = 7.5

# Set default resizing options
background = "ccc"
filter = "bilinear"
mode = "crop"
position = "top"

# Set default rotating options
expand = False

# Set default saving options
format = None
optimize = 1
quality = "90"ToolsTo 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=c9516346abf62876b6345817dba2f9a0c797ef26The 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.jpgIf 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.genexpectedDeployingIt is strongly encouraged that pilbox not be directly accessible to
the internet. Instead, it should only be accessible via a web server,
e.g. NGINX or Apache, or some other application that is designed to
handle direct traffic from the internet.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.Defaults for the application have been optimized for quality rather than
performance. If you wish to get higher performance out of the
application, it is recommended you use a less computationally expensive
filtering algorithm and a lower JPEG quality. For example, add the
following to the configuration.# Set default resizing options
filter = "bicubic"
quality = 75If you wish to improve performance further and are using an x86 platform, you may want to consider usingPillow-SIMD. Follow the steps inInstallationand it should function as a drop-in replacement forPillow. To avoid any incompatibility issues, use the same version ofPillow-SIMDas is being used forPillow.Another setting that’s helpful for fine-tuning performance and memory
usage is theworkerssetting to set the number of Tornado worker
processes. The default setting of0spawns one worker process per
CPU core which can lead to high memory usage and reduced performance
due to swapping on low-memory configurations. For Heroku deployments
limiting the number of worker processes to 2-3 for the lower-end dynos
helped smooth out application response time.ExtensionWhile it is generally recommended to use Pilbox as a standalone server, it can also be used as a library. To extend from it and build a custom image processing server, use the following example.#!/usr/bin/env python

import tornado.gen

from pilbox.app import PilboxApplication, ImageHandler, \
    start_server, parse_command_line


class CustomApplication(PilboxApplication):
    def get_handlers(self):
        return [(r"/(\d+)x(\d+)/(.+)", CustomImageHandler)]


class CustomImageHandler(ImageHandler):
    def prepare(self):
        self.args = self.request.arguments.copy()

    @tornado.gen.coroutine
    def get(self, w, h, url):
        self.args.update(dict(w=w, h=h, url=url))

        self.validate_request()
        resp = yield self.fetch_image()
        self.render_image(resp)

    def get_argument(self, name, default=None):
        return self.args.get(name, default)


if __name__ == "__main__":
    parse_command_line()
    start_server(CustomApplication())ContributionTo contribute to the project or to make and test your own changes,
fork and then clone the project.$ git clone https://github.com/YOUR-USERNAME/pilbox.gitPackaged with Pilbox is aVagrantconfiguration file which installs all necessary dependencies on a
virtual box usingAnsible. See theVagrant documentationand theAnsible
documentationfor installation instructions. Once installed, the following will start
and provision a virtual machine.$ vagrant up
$ vagrant provisionThis will have installed pilbox in/var/www/pilboxon the virtual
machine. To access the virtual machine itself, simply…$ vagrant sshWhen 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 run pilbox manually, execute the following.$ sudo /etc/init.d/pilbox stop
$ python -m pilbox.appTo run all tests, issue the following command from the installed
pilbox directory.$ python -m pilbox.test.runtestsTo run individual tests, simply indicate the test to be run, e.g.$ python -m pilbox.test.runtests pilbox.test.signature_testChangelog0.1: Image resizing fit0.1.1: Image cropping0.1.2: Image scaling0.2: Configuration integration0.3: Signature generation0.3.1: Signature command-line tool0.4: Image resize command-line tool0.5: Facial recognition cropping0.6: Fill resizing mode0.7: Resize using crop position0.7.1: Resize using a single dimension, maintaining aspect ratio0.7.2: Added filter and quality options0.7.3: Support python 30.7.4: Fixed cli for image generation0.7.5: Write output in 16K blocks0.8: Added support for ARGB (alpha-channel)0.8.1: Increased max clients and write block sizes0.8.2: Added configuration for max clients and timeout0.8.3: Only allow http and https protocols0.8.4: Added support for WebP0.8.5: Added format option and configuration overrides for mode and
format0.8.6: Added custom position support0.9: Added rotate operation0.9.1: Added sub-region selection operation0.9.4: Added Pilbox as a PyPI package0.9.10: Converted README to reStructuredText0.9.14: Added Sphinx docs0.9.15: Added implicit base url to configuration0.9.16: Added validate cert to configuration0.9.17: Added support for GIF format0.9.18: Fix for travis builds on python 2.6 and 3.30.9.19: Validate cert fix0.9.20: Added optimize option0.9.21: Added console script entry point1.0.0: Modified for easier library usage1.0.1: Added allowed operations and default operation1.0.2: Modified to allow override of http content type1.0.3: Safely catch image save errors1.0.4: Added progressive option1.1.0: Proxy server support1.1.1: Added JPEG auto rotation based on Exif orientation1.1.2: Added keep JPEG quality option and set JPEG subsampling to keep1.1.3: Fixed auto rotation on JPEG with missing Exif data1.1.4: Exception handling around invalid Exif data1.1.5: Fixed image requests without content types1.1.6: Support custom applications that need command line arguments1.1.7: Support adapt resize mode1.1.8: Added preserve Exif flag1.1.9: Increased Pillow version to 2.8.11.1.10: Added ca_certs option1.1.11: Added support for TIFF1.2.0: Support setting background when saving a transparent imageBackwards incompatible: default background property changed to0fff. To restore previous behavior, set background in config
toffff.1.2.1: Added max operations config property1.2.2: Added max resize width and height config properties1.2.3: Added user_agent option1.3.0: Increased Pillow to 2.9.0 and Tornado to 4.5.11.3.1: Fix pilbox.image CLI for python 3.01.3.2: Fix GIF P-mode to JPEG conversion1.3.3: Increase Pillow version to 5.2.0 and Tornado version to 5.1.01.3.4: Added worker config property to set number of Tornado
processes