Search code examples
phpimage-processingresizegdscale

PHP resize image proportionally to a bigger size


I'm currently working on a script that shows thumbnails from a website on a mobile app, and I'm having problems with the "retina display". If the original image is big enough, I show a thumbnail with the double of the required size, and if it is not, I show it on the required size. Now, my function checks if it can be resized proportionally and if it can't, I resize it to the "min-width" or "min-height" and crop it from the center.

Here is the problem: if it detects that the image can't be shown on the double of size, "scale up" the cropped size until it reaches the limits of the original size, and I can't find a way to scale it right. (My main problem is that I'm not really good at maths :P).

For a more simple lecture:

  • This is the original size of the image: 600 x 301
  • This is the required/cropped size: 320 x 180
  • This is the size I want to get: 535 x 301. I got it from Photoshop, and is the result of scaling 320x180 up until it finds the limit of the original size.

PS: I know GD, so I only need the formula to calculate the size.


Solution

  • The same algorithm that scales down can also scale up. This is untested code, and it is only designed to scale down, but if you remove the "scale down" tests it might do the trick for you.

    <?php // RAY_image_resize_and_crop.php
    error_reporting(E_ALL);
    
    
    // RESIZE AN IMAGE PROPORTIONALLY AND CROP TO THE CENTER
    
    
    function resize_and_crop($original_image_url, $thumb_image_url, $thumb_w, $thumb_h, $quality=75)
    {
        // ACQUIRE THE ORIGINAL IMAGE: http://php.net/manual/en/function.imagecreatefromjpeg.php
        $original = imagecreatefromjpeg($original_image_url);
        if (!$original) return FALSE;
    
        // GET ORIGINAL IMAGE DIMENSIONS
        list($original_w, $original_h) = getimagesize($original_image_url);
    
        // RESIZE IMAGE AND PRESERVE PROPORTIONS
        $thumb_w_resize = $thumb_w;
        $thumb_h_resize = $thumb_h;
        if ($original_w > $original_h)
        {
            $thumb_h_ratio  = $thumb_h / $original_h;
            $thumb_w_resize = (int)round($original_w * $thumb_h_ratio);
        }
        else
        {
            $thumb_w_ratio  = $thumb_w / $original_w;
            $thumb_h_resize = (int)round($original_h * $thumb_w_ratio);
        }
        if ($thumb_w_resize < $thumb_w)
        {
            $thumb_h_ratio  = $thumb_w / $thumb_w_resize;
            $thumb_h_resize = (int)round($thumb_h * $thumb_h_ratio);
            $thumb_w_resize = $thumb_w;
        }
    
        // CREATE THE PROPORTIONAL IMAGE RESOURCE
        $thumb = imagecreatetruecolor($thumb_w_resize, $thumb_h_resize);
        if (!imagecopyresampled($thumb, $original, 0,0,0,0, $thumb_w_resize, $thumb_h_resize, $original_w, $original_h)) return FALSE;
    
        // ACTIVATE THIS TO STORE THE INTERMEDIATE IMAGE
        // imagejpeg($thumb, 'RAY_temp_' . $thumb_w_resize . 'x' . $thumb_h_resize . '.jpg', 100);
    
        // CREATE THE CENTERED CROPPED IMAGE TO THE SPECIFIED DIMENSIONS
        $final = imagecreatetruecolor($thumb_w, $thumb_h);
    
        $thumb_w_offset = 0;
        $thumb_h_offset = 0;
        if ($thumb_w < $thumb_w_resize)
        {
            $thumb_w_offset = (int)round(($thumb_w_resize - $thumb_w) / 2);
        }
        else
        {
            $thumb_h_offset = (int)round(($thumb_h_resize - $thumb_h) / 2);
        }
    
        if (!imagecopy($final, $thumb, 0,0, $thumb_w_offset, $thumb_h_offset, $thumb_w_resize, $thumb_h_resize)) return FALSE;
    
        // STORE THE FINAL IMAGE - WILL OVERWRITE $thumb_image_url
        if (!imagejpeg($final, $thumb_image_url, $quality)) return FALSE;
        return TRUE;
    }
    
    
    // USE CASE
    echo '<a target="_blank" href="RAY_orig_600x374.jpg">Original 600x374</a><br/>';
    
    resize_and_crop('RAY_orig_600x374.jpg', 'RAY_temp_100x100.jpg', 100, 100);
    echo '<a target="_blank" href="RAY_temp_100x100.jpg">100x100</a><br/>';
    
    resize_and_crop('RAY_orig_600x374.jpg', 'RAY_temp_200x100.jpg', 200, 100);
    echo '<a target="_blank" href="RAY_temp_200x100.jpg">200x100</a><br/>';
    
    resize_and_crop('RAY_orig_600x374.jpg', 'RAY_temp_200x300.jpg', 200, 300);
    echo '<a target="_blank" href="RAY_temp_200x300.jpg">200x300</a><br/>';