Blog, PHP, PHP Development

How to Compress Image Without Losing Visible Quality in PHP

Compress image is one of the inseparable jobs from websites and it is important to increase page speed load.

High-quality images take time to load on the webpage depending on the number of images. This issue affects SEO and performance. Compressing images is one of the optimized options to increase performance.

This compression must not reduce the quality of images badly. Webpages images quality is as important as performance. Then we have to compress them as possible.

In this tutorial, you will learn how to compress image size without losing visible quality while uploading with PHP.

Compress Images Contents

Image Upload Form

Image upload form is a form created by HTML code. Go to your root folder and create “compressimage” folder. In this folder create index.html file.

Inside the index file, add following codes

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Compress Image - Honar Systems</title>
</head>
<body>
<form method='post' action='compress.php' enctype='multipart/form-data'>
    <input type='file' name='imagefile'>
    <input type='submit' value='Upload' name='upload'>
</form>
</body>
</html>

You can see our upload form in the body section. DO NOT forget the enctype attribute. We have to add this attribute when we want to upload a file.

As you see in action, we added a PHP file address. Then go to your folder and create “compress.php” file alongside the index file.

Compression PHP File

Open your compress.php file and add following code inside it.

<?php
/**
 * Created by Honar Systems
 * Author: Hossein Bahonar
 * Website: honarsystems.com
 */

//check if file uploaded
if (isset($_POST['upload'])) {
    //get uploaded file name. eg: myimage.jpg
    $uploaded_image_name = basename($_FILES['imagefile']['name']);
    $target_file = 'img/' . $uploaded_image_name;
    //get absolute path of file like C:/myhost/compressimage/img/myimage.jpg
    $image_absolute_path = $_SERVER['DOCUMENT_ROOT'] . pathinfo($_SERVER['PHP_SELF'])['dirname'] . '/img/' . $uploaded_image_name;
    //get absolute path of file with added compressed word like C:/myhost/compressimage/img/myimage_compressed.jpg
    $output_file = pathinfo($image_absolute_path)['dirname'] . '/' . basename($uploaded_image_name, '.' . pathinfo($uploaded_image_name, PATHINFO_EXTENSION)) . '_compressed.' . pathinfo($uploaded_image_name, PATHINFO_EXTENSION);
    //move uploaded file to img directory. you can change uploaded file name
    if (move_uploaded_file($_FILES["imagefile"]["tmp_name"], $target_file)) {
        //get uploaded image information like dimension, file type and etc
        $info = getimagesize($image_absolute_path);
        list($uploadWidth, $uploadHeight) = $info;

        if ($info['mime'] == 'image/jpeg') {
            $timage = imagecreatefromjpeg($image_absolute_path);
            if (imagejpeg($timage, $output_file, 60)) {
                echo "Hooray, uploaded image has been compressed";
            } else {
                echo "Sorry, there was an error compressing your file.";
            }
        } elseif ($info['mime'] == 'image/gif') {
            $img = imagecreatefromstring(file_get_contents($image_absolute_path));
            imagetruecolortopalette($img, false, 16);
            if (imagegif($img, $output_file)) {
                echo "Hooray, uploaded image has been compressed";
            } else {
                echo "Sorry, there was an error compressing your file.";
            }
        } elseif ($info['mime'] == 'image/png') {
            $timage = imagecreatefrompng($image_absolute_path);
            $targetImage = imagecreatetruecolor($uploadWidth, $uploadHeight);
            imagealphablending($targetImage, false);
            imagesavealpha($targetImage, true);
            imagecopyresampled($targetImage, $timage,
                0, 0,
                0, 0,
                $uploadWidth, $uploadHeight,
                $uploadWidth, $uploadHeight);

            if (imagepng($targetImage, $output_file, 9)) {
                echo "Hooray, uploaded image has been compressed";
            } else {
                echo "Sorry, there was an error compressing your file.";
            }
        }
    } else {
        echo "Sorry, there was an error uploading your file.";
    }
}

What Is the PHP Code?

First section is comment and is our introduction.

if (isset($_POST['upload']))

Inside the if, we check if upload button in submitted or not.

$uploaded_image_name = basename($_FILES['imagefile']['name']);

Here we get the uploaded file name and just the name, not the file path. For example, myimage.jpg. Remember that, imagefile in $_FILES must be exactly the same as in the HTML form.

$target_file = 'img/' . $uploaded_image_name;

Defining the target file name. Here go to your folder and create “img” folder to store images. You can change the target file name to what you prefer in this line.

$image_absolute_path = $_SERVER['DOCUMENT_ROOT'] . pathinfo($_SERVER['PHP_SELF'])['dirname'] . '/img/' . $uploaded_image_name;

This line defines the absolute path of the uploaded file.

Keep in mind that, sometimes compression functions don’t work with file URL. Then we have to use an absolute path.

$output_file = pathinfo($image_absolute_path)['dirname'] . '/' . basename($uploaded_image_name, '.' . pathinfo($uploaded_image_name, PATHINFO_EXTENSION)) . '_compressed.' . pathinfo($uploaded_image_name, PATHINFO_EXTENSION);

This code defines the compressed file absolute path.

if (move_uploaded_file($_FILES["imagefile"]["tmp_name"], $target_file))

Move uploaded file from the temp folder to your img folder and check it if it is done or not.

$info = getimagesize($image_absolute_path);
list($uploadWidth, $uploadHeight) = $info;

Get image information like dimension, file type, and list them.

if ($info['mime'] == 'image/jpeg')
elseif ($info['mime'] == 'image/gif')
elseif ($info['mime'] == 'image/png')

Checks file types. If file type is jpeg then do following orders.

$timage = imagecreatefromjpeg($image_absolute_path);
if (imagejpeg($timage, $output_file, 60)) {
    echo "Hooray, uploaded image has been compressed";
} else {
    echo "Sorry, there was an error compressing your file.";
}

You can change the quality of the compressed image by change 60 to whatever you prefer. This number will be between 0 to 100.

If file type is gif then do following orders.

$img = imagecreatefromstring(file_get_contents($image_absolute_path));
imagetruecolortopalette($img, false, 16);
if (imagegif($img, $output_file)) {
    echo "Hooray, uploaded image has been compressed";
} else {
    echo "Sorry, there was an error compressing your file.";
}

You can change the number of colors of the compressed image by change 16 to whatever you prefer.

If file type is png then do following orders.

$timage = imagecreatefrompng($image_absolute_path);
$targetImage = imagecreatetruecolor($uploadWidth, $uploadHeight);
imagealphablending($targetImage, false);
imagesavealpha($targetImage, true);
imagecopyresampled($targetImage, $timage,
     0, 0,
     0, 0,
     $uploadWidth, $uploadHeight,
     $uploadWidth, $uploadHeight);

if (imagepng($targetImage, $output_file, 9)) {
    echo "Hooray, uploaded image has been compressed";
} else {
    echo "Sorry, there was an error compressing your file.";
}

You can change the quality of the compressed image by change 9 to whatever you prefer. This number will be between 0 to 9. But remember that this number works vice versa. It means that by increasing the number, the quality will be reduced.

Download the Compress Image Project

You can download the project from here.