3

I am using PHP to generate images and this works fine. I am having trouble displaying these images however:

My image generator is a PHP file that takes tons of parameters and loads of data to generate the image. Because of the excessive amounts that has to be passed to the generator, using the GET container does not work for me, so the data is sent via a POST request. The result of this request is the raw image data.

I am using

$result = post_request('http://myurl.com/graphx/generator.php', $data);
if($result['status'] == 'ok') {
    echo "<img src=\"data:image/png;base64,".
        base64_encode($result['content'])."\"/>\n";
}

to display my image. This works for very small images, but as they get bigger (300px*300px for example), the image is not displayed anymore (it seems to be cut somewhere).

Is my approach reasonable?

Is there any workaround for the size issue?

Update:

When I let the generator save the image to a file, the created file contains the image as I want it to be. Also, if convert my generator into a GET-generator, the following code works properly as well:

$data = http_build_query($data);
echo "<img src=\"http://myurl.com/graphx/get_generator.php?{$data}\"/>\n";

So it definitely seems to be a problem with either the POST request, or the conversion into the base64 format. I'm using the POST request as shown here.

nikolas
  • 8,707
  • 9
  • 50
  • 70
  • What is the output of the $result for the bigger images ? Are you able to get the content key in that case ? – Stewie Jan 11 '12 at 14:47
  • @Stewie I am able to get the content key, and it contains `base64` data, but it seems to be capped at a certain length. – nikolas Jan 11 '12 at 14:55

3 Answers3

3

I'd suggest having your page be structured like this:

main page:

<img src="imageproxy.php" />

imageproxy.php:

<?php
$result = post_request('http://myurl.com/graphx/generator.php', $data);
header('Content-type: image/png');
if($result['status'] == 'ok') {
    echo $result['content']);
} else {
    readfile('error_message_image.png');
}

instead of trying to work with data uris and length limits, just have your proxy script output the actual raw image data and treat it as an image in your client-side html.

Marc B
  • 356,200
  • 43
  • 426
  • 500
1

Why don't you base64 the parameters and put THAT in the GET request, and do a simple:

<img src="/path/to/php.php?p=eyJ0aGlzIjoiaXMiLCJhIjoiYmVhdXRpZnVsIiwic2V0Ijoib2YiLCJwYXJhbWV0ZXJzIjoiISEifQ==" />

Then on the php.php base64_decode($p) and return the image.

Even better on php.php, use X-Sendfile mod of apache (https://tn123.org/mod_xsendfile/) and perhaps cache the image as well locally so that you don't have to recreate it all the time

Edit:

I don't know exactly how many parameters we are talking about here. If you go and see What is the maximum length of a URL in different browsers? you will see that experience has shown that a URI is pretty much around 2000 characters.

So it depends if your base64 encoded string is less that that you are safe. Otherwise you could think of alternative ways of encoding. Perhaps yEnc or base85?

Even further you could do store a serialized object (containing the parameters needed) on a local storage (ie RDBMS), link it with an id and pass that id around. When php.php get's the id, looks it up on the storage retrieves the parameters creates the image and so on.

Community
  • 1
  • 1
mobius
  • 5,104
  • 2
  • 28
  • 41
  • I'm especially interested in the first suggestion: would this help me? I'm, to be honest, not that adept with GET requests over HTTP, am I able to send unlimited amounts of data when encoding it to `base64` and sending it as a single parameter? – nikolas Jan 11 '12 at 15:23
  • Which would still fail. GET queries have a limited length and will truncate a 'large' image somewhere down the line. – Marc B Jan 11 '12 at 15:25
  • I will edit my post to reply to both @MarcB and nijansen cause I am running out of space. – mobius Jan 11 '12 at 15:31
1

According to http://en.wikipedia.org/wiki/Data_URI_scheme IE 8 (and presumably below if they support it) "limits data URIs to a maximum length of 32 KB". This could be what you are seeing if it only reads the first 32k of whatever you are sending it.

Chris
  • 27,210
  • 6
  • 71
  • 92
  • That's very useful information. Then how do I get around this 32KB limit? – nikolas Jan 11 '12 at 15:28
  • I think that Marc B's answer is probably the best way to go. Do what you are doing at the moment but extract that code to another page that just has the image stuff so it can return an image. – Chris Jan 11 '12 at 15:29