Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Efficient JPEG Image Resizing in PHP

Tags:

php

image

jpeg

gd

What's the most efficient way to resize large images in PHP?

I'm currently using the GD function imagecopyresampled to take high resolution images, and cleanly resize them down to a size for web viewing (roughly 700 pixels wide by 700 pixels tall).

This works great on small (under 2 MB) photos and the entire resize operation takes less than a second on the server. However, the site will eventually service photographers who may be uploading images up to 10 MB in size (or images up to 5000x4000 pixels in size).

Doing this kind of resize operation with large images tends to increase the memory usage by a very large margin (larger images can spike the memory usage for the script past 80 MB). Is there any way to make this resize operation more efficient? Should I be using an alternate image library such as ImageMagick?

Right now, the resize code looks something like this

function makeThumbnail($sourcefile, $endfile, $thumbwidth, $thumbheight, $quality) {     // Takes the sourcefile (path/to/image.jpg) and makes a thumbnail from it     // and places it at endfile (path/to/thumb.jpg).      // Load image and get image size.     $img = imagecreatefromjpeg($sourcefile);     $width = imagesx( $img );     $height = imagesy( $img );      if ($width > $height) {         $newwidth = $thumbwidth;         $divisor = $width / $thumbwidth;         $newheight = floor( $height / $divisor);     } else {         $newheight = $thumbheight;         $divisor = $height / $thumbheight;         $newwidth = floor( $width / $divisor );     }      // Create a new temporary image.     $tmpimg = imagecreatetruecolor( $newwidth, $newheight );      // Copy and resize old image into new image.     imagecopyresampled( $tmpimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height );      // Save thumbnail into a file.     imagejpeg( $tmpimg, $endfile, $quality);      // release the memory     imagedestroy($tmpimg);     imagedestroy($img); 
like image 753
maxsilver Avatar asked Aug 15 '08 19:08

maxsilver


People also ask

How do I resize a JPEG to a specific size?

Select the entire image using the Select button in the Home tab and choose Select All. A dashed line will appear around the edge. Open the Resize and Skew window by navigating to the Home tab and selecting the Resize button. Use the Resize fields to change the size of the image either by percentage or by pixels.

How do I resize an image without losing quality?

The higher the resolution, the more pixels there are in the image, and the better the quality. If you want to resize an image without losing quality, you need to make sure that the "Resample Image" checkbox is unchecked. This checkbox tells Photoshop to change the number of pixels in the image.

Does resizing images reduce quality?

Does resizing an image affect its quality? It definitely can! Typically, making an image smaller will not impact the quality, but an image can suffer quality loss when scaled beyond its original size.


2 Answers

People say that ImageMagick is much faster. At best just compare both libraries and measure that.

  1. Prepare 1000 typical images.
  2. Write two scripts -- one for GD, one for ImageMagick.
  3. Run both of them a few times.
  4. Compare results (total execution time, CPU and I/O usage, result image quality).

Something which the best everyone else, could not be the best for you.

Also, in my opinion, ImageMagick has much better API interface.

like image 189
Grzegorz Gierlik Avatar answered Sep 19 '22 14:09

Grzegorz Gierlik


Here's a snippet from the php.net docs that I've used in a project and works fine:

<? function fastimagecopyresampled (&$dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h, $quality = 3) {     // Plug-and-Play fastimagecopyresampled function replaces much slower imagecopyresampled.     // Just include this function and change all "imagecopyresampled" references to "fastimagecopyresampled".     // Typically from 30 to 60 times faster when reducing high resolution images down to thumbnail size using the default quality setting.     // Author: Tim Eckel - Date: 09/07/07 - Version: 1.1 - Project: FreeRingers.net - Freely distributable - These comments must remain.     //     // Optional "quality" parameter (defaults is 3). Fractional values are allowed, for example 1.5. Must be greater than zero.     // Between 0 and 1 = Fast, but mosaic results, closer to 0 increases the mosaic effect.     // 1 = Up to 350 times faster. Poor results, looks very similar to imagecopyresized.     // 2 = Up to 95 times faster.  Images appear a little sharp, some prefer this over a quality of 3.     // 3 = Up to 60 times faster.  Will give high quality smooth results very close to imagecopyresampled, just faster.     // 4 = Up to 25 times faster.  Almost identical to imagecopyresampled for most images.     // 5 = No speedup. Just uses imagecopyresampled, no advantage over imagecopyresampled.      if (empty($src_image) || empty($dst_image) || $quality <= 0) { return false; }     if ($quality < 5 && (($dst_w * $quality) < $src_w || ($dst_h * $quality) < $src_h)) {         $temp = imagecreatetruecolor ($dst_w * $quality + 1, $dst_h * $quality + 1);         imagecopyresized ($temp, $src_image, 0, 0, $src_x, $src_y, $dst_w * $quality + 1, $dst_h * $quality + 1, $src_w, $src_h);         imagecopyresampled ($dst_image, $temp, $dst_x, $dst_y, 0, 0, $dst_w, $dst_h, $dst_w * $quality, $dst_h * $quality);         imagedestroy ($temp);     } else imagecopyresampled ($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);     return true; } ?> 

http://us.php.net/manual/en/function.imagecopyresampled.php#77679

like image 44
2 revs, 2 users 74% Avatar answered Sep 20 '22 14:09

2 revs, 2 users 74%