Image Processing
Processing images is a common need in social apps. Whether it’s generating thumbnails, resizing photos, or adding effects, Iron.io can help you offload and scale out the effort.
Want to get right to the good stuff? Download the code from Github.
Processing images is a key part of most social, retail, and mobile applications. Almost every application that uses photos needs to perform some manipulation on them to get them into a useful format.
Let’s say you have a lot of images coming into your app in certain sizes and formats. How do you convert them to thumbnails, resize them, apply color filters, or perform other transformations automatically without a lot of effort? It’s easy to do these things programmatically using the ImageMagick libraries. These types of jobs are best done in the background—no reason to eat up front-end cycles and make users wait. The issue, then, is setting up the environment and scalable infrastructure to run the processing on—that’s where IronWorker comes in.
Managing servers to handle intermittent requests is not much fun. And if you convert batches of images at a time, it could take hours running on self-managed infrastructure. With IronWorker and the ImageMagick code libraries, that effort can be scaled-out on demand, without you having to manage a thing.
Requirements
The examples we’ll create here use the following gems. Your specific use case may vary, but these are generally a good starting point.
open-uri
RMagick
aws
subexec
mini_magick
The ImageMagick binary libraries are already installed in the IronWorker system environment. You’ll probably need to include client libraries to interface with the binary libraries, however. You can find more information on including gems on the Merging Gems page.
Writing the Worker
The first step for any worker is to write (and test!) the code on your local machine. IronWorker’s environment is simply a Linux sandbox, so any code that runs on your system, assuming you properly package it, should run exactly the same on the IronWorker cloud.
Passing Information
It’s generally best to pass IDs or URLs to images in the payload of the worker, as opposed to the images themselves—workers have a limited data payload size, and there’s less opportunity for corruption of data. The worker will then use this unique identifier to retrieve the files to be processed and bring them into your worker’s environment.
In this, example, an image URL is passed in to the worker as a data param. The file is written to the temporary, private storage each worker is given. You can see the System Environment page for more information about the amount of memory and storage available to each worker.
Retrieving the Image
Retrieving the image is a simple matter of downloading it over HTTP:
Storing the Image
After processing the image, you’re going to want to store it somewhere else
—IronWorker’s storage is only temporary, and it’s completely wiped after
the worker finishes running. This means that you don’t have to worry about
cleaning up your environment after your task is done, but it also means that
you need to store the files somewhere before the worker finishes running. In
this example, we’re going to upload them to Amazon S3
using the aws
gem. Note that @aws_access
, @aws_secret
, and @aws_s3_bucket
will all need to be included in the task’s payload.
Manipulating the Image
Let’s create a sample set of functions that process the image in various ways. (ImageMagick is an incredibly comprehensive library, so this is just a small sample of what’s possible.)
We’ll use the following variables in these sample functions:
Variable | Meaning |
---|---|
filename | The path to the file you're manipulating. The file needs to be in your worker's environment. |
width | The width, in pixels, of the post-manipulation image. |
height | The height, in pixels, of the post-manipulation image. |
format | The image format to output the post-manipulation image in. |
Resizing Images
Generating a Thumbnail
Making a Sketch of an Image
Normalizing Image Colors
Putting It All Together
We’ve built all the tools, let’s tie them together in a single worker now.
Uploading the Worker
Uploading the worker is pretty simple. We’re going to use the IronWorker command line tool, to make life easier.
Save the following as image_processor.worker
:
Now to upload the worker, just navigate to the directory with the .worker
file and the worker script, and run:
Processing Images With the Worker
To process images with the worker, you just need to queue a task with the necessary parameters (your AWS credentials and the URL for the image).
Here’s an example from the command line:
You can also queue tasks from within your application:
On Github
You can find all the code for this example worker on Github. Feel free to copy, edit, and run it on IronWorker! :)
Next Steps
Any article on ImageMagick will necessarily omit a lot of the power that the library provides—there are just too many options and commands. If you’re interested in doing more with ImageMagick, check out the official documentation on the ImageMagick website for a much more in-depth look at the possibilities.
For those using ImageMagick from Ruby, we recommend the MiniMagick gem —it’s a wrapper for the command line utility that uses less memory than the RMagick gem.