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", 50);
    • imagewebp($img, "COMPRESSED.WEBP", 50);

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!

 

 

TABLE OF CONTENTS

 

DOWNLOAD & NOTES

Here is the download link to the example code, so you don’t have to copy-paste everything.

 

EXAMPLE CODE DOWNLOAD

Source code on GitHub Gist

Just click on “download zip” or do a git clone. I have released it under the MIT license, so feel free to build on top of it or use it in your own project.

 

SORRY FOR THE ADS...

But someone has to pay the bills, and sponsors are paying for it. I insist on not turning Code Boxx into a "paid scripts" business, and I don't "block people with Adblock". Every little bit of support helps.

Buy Me A Coffee Code Boxx eBooks

 

 

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 = imagecreatefrompng("demo.png");
imagepalettetotruecolor($img);
 
// (B) COMPRESS IMAGE
// (B1) BY REDUCING QUALITY
imagejpeg($img, "demoA.jpg", 50);
 
// (B2) BY CHANGING IMAGE FILE TYPE & REDUCING QUALITY
imagewebp($img, "demoA.webp", 50);
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 = imagecreatefrompng("demo.png");
imagepalettetotruecolor($img);
 
// (B) RESIZE IMAGE
$img = imagescale($img, 200, 200);
 
// (C) COMPRESS IMAGE
imagewebp($img, "demoB.webp", 50);
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/demo.png", "D:/http/demoC.jpg");
packi("D:/http/demo.png", "D:/http/demoC.png", 200, 0); // max width 200
packi("D:/http/demo.png", "D:/http/demoC.gif", 0, 200); // max height 200
packi("D:/http/demo.png", "D:/http/demoC.webp", 200, 400); // max width 200, max height 400
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.

 

 

EXTRAS

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

 

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!