Image compression like TinyPNG

Every web-based project requires to optimize uploaded images. Main problem is that images can be heavy and page loading speed can be increased up to few seconds. For example, WordPress solved this by resizing images to few sizes. Sometimes even image is resized to smallest size possible it still takes time to load.

I was looking for image compression solutions without losing image quality. As I was using Laravel for this project, guys at Image Intervention did an amazing job with image manipulation but there was missing image compression. On the other side guys at TinyPNG also did great job but I wanted to avoid their API because they give 500 images to compress for free pre month. After a little research I’ve figure it out that best solution for image compression are imagemagic and pngquant.

Left and right image looks identical but image on the right is compressed using imagemagic and it is  20% lighter than image on the left. There is no difference that human eye can tell but there is a big difference in loading them.

You need to install imagemagic and pngquant libraries on your web server. You can do it with following commands:

sudo apt-get install imagemagick
sudo apt-get install pngquant

For jpg images I’m using imagemagick and for png obvious pngquant. I’m using this libraries with PHP exec function.

exec('convert -strip -interlace Plane -quality 85% source destination');
exec('pngquant source');

Complete function that I’m using on this and other projects looks like this:

public static function compress($localFileUrl, $options = array()) {

    $file = [];
    $file['ext'] = pathinfo($localFileUrl, PATHINFO_EXTENSION);
    $file['original'] = $localFileUrl;

    if(!in_array($file['ext'],array("jpeg","jpg","png"))) {
        return ["status" => false, "message" => "File extension is not allowed"];
    }

    try {

        if($file['ext'] == "jpeg" || $file['ext'] == "jpg") { // JPG: ImageMagic

            $file['name'] = sha1(uniqid(mt_rand(), true)).".".$file['ext'];
            $file['source'] = $options["dir"]."/".$file['name'];

            exec('convert -strip -interlace Plane -quality 85% '.$file['original'].' '.$file['source']);

        } else if ($file['ext'] == "png") { // PNG: PngQuant

            exec('pngquant '.$file['original']);

            $file['source'] = str_replace(".png","-fs8.png",$file['original']);

        }

        return ["status" => true, "message" => "Successfully compressed", "data" => array("file" => $file)];

    } catch (\Exception $e) {
        return ["status" => false, "message" => $e->getMessage()];
    }
}

Full stack web developer & entrepreneur. Failed with two startups so far. Blogging about technology, business and entrepreneurship from personal experience.

Leave a Reply

Next ArticleThings we learned from Pinpic failure