Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pngquant PHP example isn't working

Tags:

php

pngquant

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?

like image 277
André Casal Avatar asked Oct 30 '22 05:10

André Casal


1 Answers

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];
    }
}   
like image 195
Dexter Bengil Avatar answered Nov 15 '22 07:11

Dexter Bengil