Running a website that allows image uploads? But things are getting out of hand with large images? Now you need to do some image compression, save some space, and speed up the loading.
An easy way to compress images in PHP is to use the GD library:
- Create an image object from the original image –
$img = imagecreatefromjpeg("ORIGINAL.JPG");
- Compress the image –
imagejpeg($img, "COMPRESSED.JPG", 30);
The last parameter of imagejpeg()
is the image quality, a number from 0 to 100. A lower number will result in smaller file size, but lower image quality.
That covers the quick-and-dirty solution for people who are working with JPG files. But how about the other formats? What if we need to resize the image as well? Read on for a simple image compress library that I have created – Read on!
ⓘ I have included a zip file with all the example source code at the start of this tutorial, so you don’t have to copy-paste everything… Or if you just want to dive straight in.
QUICK SLIDES
TABLE OF CONTENTS
DOWNLOAD & EXAMPLES
First, here is the download link to the example source code as promised.
QUICK NOTES
- Ensure that the GD extension
extension=gd
(gd2
prior to PHP8) is enabled in thephp.ini
file. - Open
img-compressor.php
, change the default settings inA1
if you want.
EXAMPLE CODE DOWNLOAD
Click here to download the source code, I have released it under the MIT license, so feel free to build on top of it or use it in your own project.
EXAMPLE 1) SIMPLE IMAGE COMPRESS
// (A) LOAD LIBRARY
require "img-compressor.php";
// (B) EASY COMPRESS
// DEFAULT WILL OUTPUT TO BIRB.WEBP, 30 QUALITY
echo $_IC->pack("birb.jpg") ? "OK" : $_IC->error;
// (C) SPECIFY PATH & FILE NAME
echo $_IC->pack("birb.jpg", "d:/packed.jpg") ? "OK" : $_IC->error;
To use the image compress library:
- Load the library –
require "img-compressor.php"
. - Simply call
$_IC->pack(SOURCE)
to compress images, this will use the default settings in the library. Take note, this returns aboolean
. If it isfalse
, you can check the error message in$_IC->error
. - You can also specify the output file path/format –
$_IC->pack(SOURCE, TARGET)
. Of course, onlyjpg
andwebp
are compressed…
EXAMPLE 2) COMPRESS IMAGE SETTINGS
<?php
// (A) LOAD LIBRARY
require "img-compressor.php";
// (B) CHANGE DEFAULT SETTINGS
// $_IC->SET(FORMAT, QUALITY, MAX SIZE)
$_IC->set("jpg", 50, 300);
// (C) WILL OUTPUT TO PACKED.JPG, 50 QUALITY, MAX 300 PX WIDTH/HEIGHT
echo $_IC->pack("birb.jpg", "packed.jpg") ? "OK" : $_IC->error;
If you want to change the settings during runtime, just call $_IC->set()
.
EXAMPLE 3) COMPRESS UPLOADED FILES
<!-- (A) HTML UPLOAD FORM -->
<form method="post" enctype="multipart/form-data">
<input type="file" name="upload" accept=".png,.gif,.jpg,.jpeg,.bmp,.webp" required>
<input type="submit" name="submit" value="Upload Image">
</form>
<?php
// (B) DEAL WITH IMAGE UPLOAD
if (isset($_FILES["upload"])) {
// (B1) SAVE UPLOADED IMAGE
move_uploaded_file($_FILES["upload"]["tmp_name"], $_FILES["upload"]["name"]);
// (B2) COMPRESS
require "img-compressor.php";
echo $_IC->pack($_FILES["upload"]["name"], "uploaded.webp")
? "OK" : $_IC->error;
// (B3) REMOVE ORIGINAL - IF YOU DON'T NEED IT
unlink($_FILES["upload"]["name"]);
}
?>
Just upload the file “as usual”, then call the library to compress it.
PHP IMAGE COMPRESS LIBRARY
All right, let us now get into a little more detail on how the PHP image compress library work.
PART A) PROPERTIES & SETTINGS
// (A) PROPERTIES
// (A1) DEFAULT SETTINGS
private $format = "webp"; // COMPRESSED FILE FORMAT
private $quality = 30; // COMPRESSED QUALITY (0 TO 100)
private $maxSize = 0; // MAX ALLOWED WIDTH/HEIGHT (0 FOR NONE)
// (A2) FLAGS
public $error = "";
private $allow = ["jpeg", "jpg", "gif", "png", "bmp", "webp"];
This entire section should be pretty self-explanatory.
$format
The default output format. Recommended to usejpg
orwebp
.$quality
As in the introduction, the image quality. This only applies tojpg
orwebp
… If you do not know already know the difference between lossy and lossless images, I will leave some links below.$maxSize
Restrict the maximum width/height of the image.$error
Used to hold error messages.$allow
The allowed image file types… Just don’t mess with these. These are the file types that GD can handle.
PART B) COMPRESS IMAGE
// (B) COMPRESS IMAGE
function pack ($source, $target=null) {
// (B1) CHECK SOURCE IMAGE
if (!is_readable($source)) {
$this->error = "Cannot read $source";
return false;
}
// (B2) CHECK SOURCE IMAGE FILE TYPE
$sInfo = pathinfo($source, PATHINFO_ALL);
$sInfo["extension"] = !isset($sInfo["extension"]) ? "" : strtolower($sInfo["extension"]) ;
if (!in_array($sInfo["extension"], $this->allow)) {
$this->error = "Invalid input image - " . $sInfo["extension"];
return false;
}
// (B3) CHECK TARGET (COMPRESSED) IMAGE
$target = $target===null ? $sInfo["filename"].".". $this->format : $target ;
$tInfo = pathinfo($target, PATHINFO_ALL);
$tInfo["extension"] = !isset($tInfo["extension"]) ? "" : strtolower($tInfo["extension"]) ;
if (!in_array($tInfo["extension"], $this->allow)) {
$this->error = "Invalid output image - " . $tInfo["extension"];
return false;
}
// (B4) GD OPEN SOURCE IMAGE
$gdOpen = "imagecreatefrom" . ($sInfo["extension"]=="jpg" ? "jpeg" : $sInfo["extension"]);
$img = $gdOpen($source);
if ($img===false) {
$this->error = "Failed to open $source";
return false;
}
// (B5) RESIZE IMAGE IF NECESSARY
if ($this->maxSize!=0) {
// (B5-1) GET SOURCE IMAGE SIZE & ORIENTATION
$srcW = imagesx($img);
$srcH = imagesy($img);
if ($srcW > $srcH) { $srcO = "L"; }
else if ($srcH > $srcW) { $srcO = "P"; }
else { $srcO = "S"; }
// (B5-2) RESIZE
if (($srcO=="L" || $srcO=="S") && $srcW > $this->maxSize) {
$newW = $this->maxSize;
$newH = floor(($this->maxSize / $srcW) * $srcH);
$img = imagescale($img, $newW, $newH);
}
if ($srcO=="P" && $srcH > $this->maxSize) {
$newW = floor(($this->maxSize / $srcH) * $srcW);
$newH = $this->maxSize;
$img = imagescale($img, $newW, $newH);
}
}
// (B6) GD SAVE & COMPRESS IMAGE (IF JPG OR WEBP)
$gdWrite = "image" . ($tInfo["extension"]=="jpg" ? "jpeg" : $tInfo["extension"]);
$pass = ($tInfo["extension"]=="jpg" || $tInfo["extension"]=="jpeg" || $tInfo["extension"]=="webp")
? $gdWrite($img, $target, $this->quality) : $gdWrite($img, $target);
if (!$pass) {
$this->error = "Failed to write to $target";
return false;
}
// (B7) ALL GOOD!
return true;
}
What actually happens behind the scene. Not going to explain line-by-line, but a quick summary:
- (B1 To B3) Check if the image source file can be read, check if valid image file formats are used.
- (B4) Open and read the source image into an object.
- (B5) Resize the image if necessary… Sadly, this is very Mathematical in nature.
- Get the original image size.
- Check the orientation of the image.
- Calculate the new dimensions if the original image is too big.
- (B6 & B7) Save the image object into a file.
PART C) CHANGE SETTINGS
// (C) CHANGE SETTINGS
function set ($format, $quality, $maxSize) {
$this->format = $format;
$this->quality = $quality;
$this->maxSize = $maxSize;
}
If you do not know this, you need to go back to basic OOP lessons…
USEFUL BITS & LINKS
That’s all for this guide, and here is a small section on some extras and links that may be useful to you.
THE TRANSPARENT BACKGROUND DISAPPEARED!?
For the uninitiated – Only webp
, png
, and gif
supports a transparent background.
THE IMAGE IS NOT COMPRESSED!?
There are 2 types of image formats in general – Lossy and lossless. Only the lossy types can be compressed – jpeg
and webp
. Read this to learn more.
LINKS & REFERENCES
- How To Resize Images In PHP – Code Boxx
- How to Add Text to Images In PHP – Code Boxx
- Simple Drag-and-drop File Upload With PHP – Code Boxx
- GD Manual – PHP
INFOGRAPHIC CHEAT SHEET

THE END
Thank you for reading, and we have come to the end of this guide. I hope that it has helped you with your project, and if you want to share anything with this guide, please feel free to comment below. Good luck and happy coding!