38

I'm using a solution for assembling image files to a zip and streaming it to browser/Flex application. (ZipStream by Paul Duncan, http://pablotron.org/software/zipstream-php/).

Just loading the image files and compressing them works fine. Here's the core for compressing a file:

// Reading the file and converting to string data
$stringdata = file_get_contents($imagefile);

// Compressing the string data
$zdata = gzdeflate($stringdata );

My problem is that I want to process the image using GD before compressing it. Therefore I need a solution for converting the image data (imagecreatefrompng) to string data format:

// Reading the file as GD image data
$imagedata = imagecreatefrompng($imagefile);
// Do some GD processing: Adding watermarks etc. No problem here...

// HOW TO DO THIS??? 
// convert the $imagedata to $stringdata - PROBLEM!

// Compressing the string data
$zdata = gzdeflate($stringdata );

Any clues?

3 Answers 3

52

One way is to tell GD to output the image, then use PHP buffering to capture it to a string:

$imagedata = imagecreatefrompng($imagefile);
ob_start();
imagepng($imagedata);
$stringdata = ob_get_contents(); // read from buffer
ob_end_clean(); // delete buffer
$zdata = gzdeflate($stringdata);
Sign up to request clarification or add additional context in comments.

1 Comment

I tried this and for some reason it fails with nested ob_start. I found M.i.X's answer below to be a better solution.
26

The php://memory stream can be used when output-buffer juggling is unwanted. https://www.php.net/manual/en/wrappers.php.php

$imagedata = imagecreatefrompng($imagefile);

// processing

$stream = fopen('php://memory','r+');
imagepng($imagedata,$stream);
rewind($stream);
$stringdata = stream_get_contents($stream);

// Compressing the string data
$zdata = gzdeflate($stringdata );

3 Comments

This is a much better answer than ob_start() hackery. Thanks!
Not sure why but this doesn't work on Windows under PHP 5.6.18. "10 is not a valid stream resource"
Beautiful way. Much better than using ob_*
23
// ob_clean(); // optional
ob_start();
imagepng($imagedata);
$image = ob_get_clean();

1 Comment

ob_get_clean() essentially executes both ob_get_contents() and ob_end_clean(), so this solution is slightly more elegant that the accepted answer above.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.