Tuesday, March 4, 2014

PHP Image Server

One of my latest projects requires an image server which had to fulfill these two API requirements:

  • Storing: Accept a URL as an image source then provide a token to address the cached/stored image.
  • Reading: Accept a token to provide an image in a specified resolution and/or format.
Some secondary features required:
  • The read API should provide a method to crop and resize images.
  • For the purposes of my project, I require the machine to...
    • accept JPEG, GIF, PNG, and SVG
    • only serve JPG's
This image store facility is only going to be used by an automated robot, so no pretty human interface is required.

Download

The code is on GitHub. Download and modify as you please.

Basic API format

  • Storing:
    /store/secret-key/base64_encoded_URL
  • Reading:
    /key/token/size

Storing an Image

Calling the API with parameters something like this:

http://localhost/imagemachine/store/123/aHR0cHM6Ly91cGxvYWQud2lraW1lZGlhLm9yZy93aWtpcGVkaWEvY29tbW9ucy9iL2IwL05ld1R1eC5zdmc=
Where store is the action, 123 is the secret key to store images, and the last parameter is the base64 encoded result of "https://upload.wikimedia.org/wikipedia/commons/b/b0/NewTux.svg"
Should result in JSON looking something like this:
{
 status: "ok",
 msg: "stored",
 guid: "de683d6b2e298de8e831b2f632132269"
}
The above means that the imageserver has decoded the URL, downloaded it, saved it in JPEG format (configurable), and returned a key for you to address that image in the future. The key is simply a hash of the URL passed in.

Reading an Image

Calling the API with parameters something like this (using the token from above):

http://localhost/imagemachine/~/de683d6b2e298de8e831b2f632132269
Will return an image in the default size and cropping.
The read key in this example is simply set to a tilde (~) as security for reading images out of this store is of no concern. To specify a size/cropping scheme, append one of the predefined sizes as another parameter:
http://localhost/imagemachine/~/de683d6b2e298de8e831b2f632132269/s
Where s has been setup as a "small" version of the image.

Demo Settings File

<?php
$settings = array(
// one key is used for reading images (so that this can be public facing, but still prevent people from uploading)
'key_read' => '~',
// a separate secret key for storage. we don't want just any old monkey uploading images.
'key_store' => '123',
// a system path to a place to save all images uploaded to this server
'storage_url' => 'f:/image_store/',
// A set of predefined sizes allowed by our server - This is mainly here to prevent nasty people requesting images with random sizes
'sizes' => array(
'l' => array('cropping' => 'best', 'perimiter' => 800*4, 'quality' => 80),
'm' => array('cropping' => 'crop', 'length' => 240, 'quality' => 75),
's' => array('cropping' => 'crop', 'length' => 50, 'quality' => 30)
),
// If no size is specified, which size should we serve up?
'default_size' => 'm',
// the document extension/format to store all files in.
'image_storage_extension' => 'jpg', // this is required for imagemagick to know which file format to store in
'image_serve_type' => IMAGETYPE_JPEG, // options: IMAGETYPE_JPEG, IMAGETYPE_GIF, IMAGETYPE_PNG // used by SimpleImage.php when processing images on read requests
'quality' => 75, // used by SimpleImage.php when serving images (and saving the cached image)
// A valid path to ImageMagicks convert executable - write it here as though you were executing it in your systems console
'imageMagickConvert' => 'C:/Progra~1/ImageMagick-6.8.8-Q16/convert',
// 'imageMagickConvert' => '/usr/bin/convert',
// Logging options
'logging_enabled' => true
// some more options specific to logging in the source code - not relevant in this blog post
);
?>
view raw settings.php hosted with ❤ by GitHub

My Experience on a Hosted Solution

I use the GridService product offered by MediaTemple for my hosting. I followed this article to get the ImageMagick PECL working. But ended up discovering that the extension was quite limited compared to the native console convert. So I fell back to using PHP's exec.

1 comment:

Sandra said...

As a programmer, there is a tool, I would like to suggest, that tool is
url-decode.com/tool/base64-encode
That link also contains the tool, related to encode and decode (URL, base64), converter, developer tools, IP related tools, and many more. You must check it out.