views:

48

answers:

2

(Preamble: This seems like such a typical thing to want to do that I was surprised I didn't immediately find examples and tutorials about it. So I thought it would be valuable to have as a StackOverflow question. Pointers to related examples and tutorials will certainly be welcome answers.)

To make this concrete, the goal is a webservice that accepts data in JSON format via a POST request. The data is simply an array of single-digit integers, e.g., [3, 2, 1].

On the server are images named 0.png, 1.png, 2.png, etc. The webservice takes the images corresponding to those specified in the JSON array and composes them into a montage, using the standard ImageMagick command line tool. For example,

montage 3.png 2.png 1.png 321.png

creates a new single image, 321.png, composed of 3.png, 2.png, and 1.png, all in a row.

The accepted answer will be in the form of complete PHP code that implements the above. (I'll write it if no one beats me to it.)

+1  A: 

some hints, i won't write the complete code for you:

  • to get your array back on php-side, there is json_decode. ise it like this:

    $images = json_decode($_POST['whatever']);
  • to get the command for montage, do something like this (note: you should valitate all input you get via post, i'm going to leave this out and focus on th "complicated" parts):

    $cmd = "montage";
    foreach($images as $image){
      $cmd .= " ".$image.".png";
    }
    $cmd .= " temp.png";
  • now you can execute your command using exec or one of his friends:

    exec($cmd);
  • at least, set a png-header and use readfile or something similar to get you "tmp.png"

oezi
+1  A: 

Thanks to oezi for providing all the pieces. Here's the complete PHP program:

<?php
$nums = json_decode($_REQUEST['nums']);

# Lambda functions are a little less ridiculous in php 5.3 but this is the best
# way I know how to do this in php 5.2:
function f($x) { return "$x.png"; }
$cmd = "montage " . implode(" ", array_map("f", $nums)) . " tmp.png";

exec($cmd);

header('Content-type: image/png');
readfile('tmp.png');
?>

Try it out like so:

http://yootles.com/nmontage/go.php?nums=[2,4,6]

You should get this:

246

(That's GET instead of POST of course, but the php program accepts either.)

dreeves
+1 nice use of array_map - i thougt about something similar too, but thought it would be too much "overhead" for such a small thing. it's not, like your code proves.
oezi