I am trying to use the pngquant compression algorithm to compress PNG images on the fly using WAMP. They provide a PHP example that (I think) is supposed to use the command line binary for Windows, which I have put in the system32
folder and I can access from anywhere on the command line.
I have taken their example and traced the problem to the $compressed_png_content = shell_exec("pngquant --quality=$min_quality-$max_quality - < ".escapeshellarg( $path_to_png_file));
line. I have simplified it to var_dump(shell_exec('pngquant - < test.png'));
but it only outputs the first 5 characters even though passthru('pngquant - < test.png');
seems to send the correct output to the user as a string. exec('pngquant - < test.png',$output); var_dump($output);
also seems to capture the correct output but in a form of an array, which I don't really know how to convert back into an image file. I want to capture the output in a variable so I can use further compression algorithms and manipulations and send it to the user as a downloadable file.
I have read up on the diferences between system() vs exec() vs shell_exec() vs passthru() vs proc_open() vs popen(). Shell_exec() seems to be the correct choice, however it says on php.net that shell_exec()'s outputs a string. Could that be a problem? How do I correctly capture the pngquant - < test.png
command output to a variable?
Use a PHP wrapper (php-pngquant) for PNGQuant instead, I've come across with the same issue, and this non-official wrapper has finally saved me.
function compress_image($source_path, $destination_path, $quality){
$instance = new PNGQuant();
// Change the path to the binary of pngquant, for example in windows would be (with an example path):
$instance->setBinaryPath("E:\\wamp64\\www\\testing\\pngquant\\pngquant.exe")
// Other options of PNGQuant here
->execute();
// Set the path to the image to compress
$result = $instance->setImage($source_path)
// Overwrite output file if exists, otherwise pngquant will generate output ...
->overwriteExistingFile()
// As the quality in pngquant isn't fixed (it uses a range)
// set the minimum quality to 60
->setQuality(60, $quality)
// Retrieve RAW data from pngquant
->getRawOutput();
$exit_code = $result["statusCode"];
// if exit code is equal to 0 then everything went right !
if($exit_code == 0){
$rawImage = imagecreatefromstring($result["imageData"]);
// Example Save the PNG Image from the raw data into a file or do whatever you want.
imagepng($rawImage , $destination_path);
echo "Image succesfully compressed, do something with the raw Data";
}else{
echo "Something went wrong (status code $exit_code) with description: ". $instance->getErrorTable()[(string) $exit_code];
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With