Resize/crop/pad a picture to a fixed size

前端 未结 11 1795
孤城傲影
孤城傲影 2020-11-27 14:58

I need to resize a picture to a fixed size. But it has to keep the factors between the width and height.

Say I want to resize a picture from 238 (w) X 182 (

11条回答
  •  半阙折子戏
    2020-11-27 15:52

    This solution is basically the same as Can Berk Güder's, but after having spent some time writing and commenting, I felt like posting.

    This function creates a thumbnail that is exactly as big as the size you give it. The image is resized to best fit the size of the thumbnail. If it does not fit exactly in both directions, it's centered in the thumnail. Extensive comments explain the goings-on.

    function thumbnail_box($img, $box_w, $box_h) {
        //create the image, of the required size
        $new = imagecreatetruecolor($box_w, $box_h);
        if($new === false) {
            //creation failed -- probably not enough memory
            return null;
        }
    
    
        //Fill the image with a light grey color
        //(this will be visible in the padding around the image,
        //if the aspect ratios of the image and the thumbnail do not match)
        //Replace this with any color you want, or comment it out for black.
        //I used grey for testing =)
        $fill = imagecolorallocate($new, 200, 200, 205);
        imagefill($new, 0, 0, $fill);
    
        //compute resize ratio
        $hratio = $box_h / imagesy($img);
        $wratio = $box_w / imagesx($img);
        $ratio = min($hratio, $wratio);
    
        //if the source is smaller than the thumbnail size, 
        //don't resize -- add a margin instead
        //(that is, dont magnify images)
        if($ratio > 1.0)
            $ratio = 1.0;
    
        //compute sizes
        $sy = floor(imagesy($img) * $ratio);
        $sx = floor(imagesx($img) * $ratio);
    
        //compute margins
        //Using these margins centers the image in the thumbnail.
        //If you always want the image to the top left, 
        //set both of these to 0
        $m_y = floor(($box_h - $sy) / 2);
        $m_x = floor(($box_w - $sx) / 2);
    
        //Copy the image data, and resample
        //
        //If you want a fast and ugly thumbnail,
        //replace imagecopyresampled with imagecopyresized
        if(!imagecopyresampled($new, $img,
            $m_x, $m_y, //dest x, y (margins)
            0, 0, //src x, y (0,0 means top left)
            $sx, $sy,//dest w, h (resample to this size (computed above)
            imagesx($img), imagesy($img)) //src w, h (the full size of the original)
        ) {
            //copy failed
            imagedestroy($new);
            return null;
        }
        //copy successful
        return $new;
    }
    

    Example usage:

    $i = imagecreatefromjpeg("img.jpg");
    $thumb = thumbnail_box($i, 210, 150);
    imagedestroy($i);
    
    if(is_null($thumb)) {
        /* image creation or copying failed */
        header('HTTP/1.1 500 Internal Server Error');
        exit();
    }
    header('Content-Type: image/jpeg');
    imagejpeg($thumb);
    

提交回复
热议问题