Resize/crop/pad a picture to a fixed size

前端 未结 11 1769
孤城傲影
孤城傲影 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:48

    I think there is a little confusion.. If you only want to resize it, keeping the original ratio, the right operation is:

    $ratio = $originalWidth / $originalHeight;
    if(//you start from the width, and want to find the height){
     $newWidth = $x;
     $newHeight = $x / $ratio;
    }else if(//you start from the height, and want to find the width){
     $newHeight = $x;
     $newWidth = $x * $ratio;
    }
    

    Else, if the prefixed newWidth and newHeight cant be changed, and the thumb ratio is different from the original ratio, the only way is to crop or add borders to the thumb.

    If your'e on to take the cut way, this function can help you (i wrote years ago in 5 minutes, maybe need some improvement.. it works only with jpg, for example ;):

        function thumb_cut($nomeimage, $source_path, $destination_path, $new_width, $new_height){
          list($width, $height, $type, $attr) = getimagesize($source_path.$nomeimage);
          if($type == 2){
            if($width > $new_width){
              $new_width = $width;
              $new_height = $height;
            }
            $compression = 100;
            $destimg = imagecreatetruecolor($new_width,$new_height) or die("Problems creating the image");
            $srcimg = ImageCreateFromJPEG($source_path.$nomeimage) or die("problem opening the image");
            $w = ImageSX($srcimg);
            $h = ImageSY($srcimg);
            $ro = $new_width/$new_height;
            $ri = $w/$h;
            if($ro<$ri){
              $par = "h";
            }else{
              $par = "w";
            }
            if($par == "h"){
              $ih = $h;
              $conv = $new_width/$new_height;
              $iw = $conv*$ih;
              $cw = ($w/2)-($iw/2);
              $ch = ($h/2)-($ih/2);
            }else if($par == "w"){
              $iw = $w;
              $conv = $new_height/$new_width;
              $ih = $conv*$iw;
              $cw = ($w/2)-($iw/2);
              $ch = ($h/2)-($ih/2);
            }
            ImageCopyResampled($destimg,$srcimg,0,0,$cw,$ch,$new_width,$new_height,$iw,$ih) or die("problems with resize");
            ImageJPEG($destimg,$destination_path.$nomeimage,$compression) or die("problems with storing new image");
          }
        }
    
    0 讨论(0)
  • 2020-11-27 15:48

    The technique is to:

    1. resize the image so that one dimension matches while the other exceeds the desired dimensions
    2. take out the desired size image from the center of resized image.

    Lastly if you are puzzled about how to do the resize math, remember that if proportions of source and destination images are same, this relation holds:

    SourceWidth / SourceHeight = DestinationWidth / DestinationHeight
    

    If you know three parameters, you can calculate the fourth one easily.

    I wrote an article about this:
    Crop-To-Fit an Image Using ASP/PHP

    0 讨论(0)
  • 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);
    
    0 讨论(0)
  • 2020-11-27 15:52

    are these thumbnails? if they are, cropping is not a huge problem. we do it all the time. i don't even shy away from cropping arbitrary ratios into crippled quadratic thumbnails, completely messing up the image (yes, i'm that hardcore), if it just looks good. this is a designers answer to a technical question, but still. don't fear the crop!

    0 讨论(0)
  • 2020-11-27 15:52

    You'll have to crop 5 px off the top and bottom to get to your target size, however this could ruin the picture.

    Really you should have a target width or height, then adjust the other dimension by the same proportion.

    0 讨论(0)
提交回复
热议问题