How To Compress Images In PHP (Simple Examples)

Welcome to a tutorial on how to compress images in PHP. So you need to do some image compression to save some disk space? Probably to speed up the loading as well?

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 by either changing the file format and/or reducing the quality.
    • imagejpeg($img, "COMPRESSED.JPG", 30);
    • imagewebp($img, "COMPRESSED.WEBP");

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.

 

 

TLDR – QUICK SLIDES

Fullscreen Mode – Click Here

 

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 the php.ini file.
If you spot a bug, feel free to comment below. I try to answer short questions too, but it is one person versus the entire world… If you need answers urgently, please check out my list of websites to get help with programming.

 

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.

 

 

PHP COMPRESS IMAGE

All right, let us now get into the examples of how to compress images in PHP – Using the GD extension.

 

PART 1) SIMPLE IMAGE COMPRESSION

1-simple.php
// (A) IMAGE OBJECT
$img = imagecreatefromjpeg("birb.jpg");
 
// (B) COMPRESS IMAGE
// (B1) BY REDUCING QUALITY
imagejpeg($img, "demoA.jpg", 30);
 
// (B2) BY CHANGING IMAGE FILE TYPE & REDUCING QUALITY
imagewebp($img, "demoA.webp", 30);
echo "DONE";

For you guys who are new, I will keep things as simple as possible. There are 2 “basic types” of images:

  • Lossless – Doesn’t suffer quality loss when compressed, but usually large in file size. E.G. BMP, TIFF, RAW.
  • Lossy – Suffers quality loss when compressed (blurry image), but usually small in file size. E.G. JPG, WEBP.

So when it comes to “image compression”, we are usually referring to lossy images. The lower the image quality, the smaller the file size; The higher the quality, the larger the file size. It is pretty much a game of balancing how much to bring the quality down VS the file size. To “compress” an image in the simplest form, we just have to take the quality down.

  1. imagecreatefromjpeg(IMAGE FILE) Creates an image object from the given file. Take note, there are respective functions to open different image types – imagecreatefrompng() imagecreatefromwebp imagecreatefrombmp().
  2. imagejpeg(IMAGE OBJECT, FILE, QUALITY) Save to specified file, QUALITY is a number from 0 (lowest) to 100 (highest). Similarly, imagewebp(IMAGE OBJECT, FILE, QUALITY).

 

 

PART 2) RESIZING IMAGES

2-resize.php
<?php
// (A) IMAGE OBJECT
$img = imagecreatefromjpeg("birb.jpg");
 
// (B) RESIZE IMAGE
$img = imagescale($img, 400, 267);
 
// (C) COMPRESS IMAGE
imagewebp($img, "demoB.webp", 30);
echo "DONE";

To further bring the file size down, we can permanently resize the image. GD2 provides a very simple function to do that – imagescale(IMAGE OBJECT, WIDTH, HEIGHT). Yep, that’s all.

P.S. Do this at your own discretion… Once resized, there will be a quality loss.

 

 

PART 3) IMAGE COMPRESS FUNCTION – RESIZE & COMPRESS

3-packi.php
function packi ($from, $to, $mw=null, $mh=null, $quality=null) {
  // (A) CHECKS
  // (A1) SOURCE IMAGE IS READABLE
  if (!is_readable($from)) { exit("Cannot read $from"); }
 
  // (A2) ALLOWED IMAGE FILE FORMATS
  $extFrom = strtolower(pathinfo($from, PATHINFO_EXTENSION));
  $extTo = strtolower(pathinfo($to, PATHINFO_EXTENSION));
  if (!in_array($extFrom, ["jpeg", "jpg", "gif", "png", "bmp", "webp"])) { exit("$from - Invalid file format"); }
  if (!in_array($extTo, ["jpeg", "jpg", "gif", "png", "webp"])) { exit("$from - Invalid file format"); }
 
  // (B) OPEN SOURCE IMAGE
  $fn = "imagecreatefrom" . ($extFrom=="jpg" ? "jpeg" : $extFrom);
  $img = $fn($from);
 
  // (C) RESIZE IMAGE
  if ($mw!=null || $mh!=null) {
    // (C1) SOURCE IMAGE DIMENSIONS
    $sw = imagesx($img);
    $sh = imagesy($img);
 
    // (C2) RESIZE RATIO
    if ($mw != null && $sw>$mw) { $rw = $mw / $sw; } else { $rw = 1; }
    if ($mh != null && $sh>$mh) { $rh = $mh / $sh; } else { $rh = 1; }
 
    // (C3) RESIZE USING THE SMALLER RATIO
    if ($rw!=1 || $rh!=1) {
      $rr = $rw<$rh ? $rw : $rh ;
      $img = imagescale($img, floor($rr * $sw), floor($rr * $sh));
    }
  }
 
  // (D) SAVE & COMPRESS IMAGE
  // jpg : 0 to 100
  // webp : -1 (default), 0 to 100
  // png : -1 (default), 0 (none) to 9
  // gif : na (no compression)
  if ($extTo=="gif") { imagegif($img, $to); }
  else {
    if ($extTo=="jpg" && ($quality==null || !is_numeric($quality) || $quality<0 || $quality>100)) { $quality = 30; }
    if ($extTo=="webp" && ($quality==null || !is_numeric($quality) || $quality<-1 || $quality>100)) { $quality = -1; }
    if ($extTo=="png" && ($quality==null || !is_numeric($quality) || $quality<-1 || $quality>9)) { $quality = -1; }
    $fn = "image" . ($extTo=="jpg" ? "jpeg" : $extTo);
    $fn($img, $to, $quality);
  }
  return true;
}
 
// (E) GO!
packi("D:/http/birb.jpg", "D:/http/demoC.jpg");
packi("D:/http/birb.jpg", "D:/http/demoC.png", 400, 0); // max width 400
packi("D:/http/birb.jpg", "D:/http/demoC.gif", 0, 200); // max height 200
packi("D:/http/birb.jpg", "D:/http/demoC.webp", 400, 200); // max width 400, max height 200
echo "DONE";

For you guys who just want “a function to compress images”, I got you covered. Just use packi(SOURCE IMAGE, SAVE TO, MAX WIDTH, MAX HEIGHT, QUALITY).

  • SOURCE IMAGE The original image.
  • SAVE TO Save to this file, can be jpg webp png gif.
  • MAX WIDTH & MAX HEIGHT Optional, will resize the original image if it exceeds these settings.
  • QUALITY Save quality, optional.
    • JPG From 0 (lowest) to 100 (highest).
    • WEBP From 0 (lowest) to 100 (highest), -1 for default.
    • PNG From 0 (no compression) to 9, -1 for default.
    • GIF None. Cannot be compressed.

 

 

EXTRA 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.

 

COMPRESSION MAY NOT ALWAYS END WELL

Take note of the screenshot in the last example, the PNG file actually ends up larger than the original. So to manage your expectation, changing the image dimensions/type/compression may not always end up with good results. But if it works 90% of the time, then it’s worth the effort to implement the compression.

 

LAZY LOADING

Lastly, a small extra for you guys who wants to “speed up loading”. Just set the images to lazy loading. That is, the images will only load as the user scrolls down, when the image is on the screen. Very easy, just add lazy to the image tag – <img lazy src="IMAGE">.

 

 

LINKS & REFERENCES

 

INFOGRAPHIC CHEAT SHEET

How To Compress Images In PHP (click to enlarge)

 

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!

Leave a Comment

Your email address will not be published. Required fields are marked *