Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Php webservice that takes JSON via POST and spits back an image

(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.)

like image 343
dreeves Avatar asked Oct 14 '22 22:10

dreeves


2 Answers

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"

like image 161
oezi Avatar answered Nov 03 '22 03:11

oezi


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
(source: yootles.com)

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

like image 44
dreeves Avatar answered Nov 03 '22 04:11

dreeves