简体   繁体   中英

Resize image in PHP, keeping ratio, transparency and centering

如何在PHP中调整图像的大小,以保持宽高比(如果文件是gifpng图像,则保持透明度),然后根据最终大小将图像垂直或水平居中?

there are several tricks. here is my func:

function im_resize($file_src,$file_dest,$wd,$hd) {

  if (!file_exists($file_src)) return false;

  $size = getimagesize($file_src);
  if ($size === false) return false;

  if ($size['mime']=='image/pjpeg') $size['mime'] = 'image/jpeg';

  $format = strtolower(substr($size['mime'], strpos($size['mime'], '/')+1));
  $destformat = strtolower(substr($file_dest, -4));
  $icfunc = "imagecreatefrom" . $format;
  if (!function_exists($icfunc)) return false;

  $src = $icfunc($file_src);

  $ws = imagesx($src);
  $hs = imagesy($src);

  if ($ws >= $hs) {
    $hd = ceil(($wd * $hs) / $ws);
  }
  else {
    $wd =  ceil(($hd*$ws)/$hs);
  }
  if ($ws <= $wd) {
    $wd = $ws;
    $hd = $hs;
  }
  $wc=($wd * $hs) / $hd;

  if ($wc<=$ws) {
    $hc=($wc * $hd) / $wd;
  }
  else {
    $hc=($ws * $hd) / $wd;
    $wc=($wd * $hc) / $hd;
  }

  $dest = imagecreatetruecolor($wd,$hd);
  switch ($format) {
    case "png":
      imagealphablending( $dest, false );
      imagesavealpha( $dest, true );
      $transparent = imagecolorallocatealpha($dest, 255, 255, 255, 127);
      imagefilledrectangle($dest, 0,  0, $nw, $nh,  $transparent);

      break;
    case "gif":
      // integer representation of the color black (rgb: 0,0,0)
      $background = imagecolorallocate($src, 0, 0, 0);
      // removing the black from the placeholder
      imagecolortransparent($src, $background);

      break;
  }

  imagecopyresampled($dest,$src,0,0,($ws-$wc)/2,($hs-$hc)/2, $wd, $hd, $wc, $hc);

  if (!isset($q)) $q = 100;
  if ($destformat=='.png') $saved=imagepng($dest,$file_dest);
  if ($destformat=='.jpg') $saved=imagejpeg($dest,$file_dest,$q);
  if (!$saved) my_error_log('saving failed');

  imagedestroy($dest);
  imagedestroy($src);
  @chmod($file_dest, 0666);

  return true;
}

If

(…) then center the image vertically or horizontally (…)

means that you want to add a white or black border around, I wouldn't do that. Just save the resized image and do the centering in the browser using html/css.

// ---------------------------------------------------------------------------------
//  Resize Image
// ---------------------------------------------------------------------------------
function ResizeImage($FileName,$SaveFile, $MaxWidth, $MaxHeight = null) {

    $extension = GetFileExtension($FileName);

    switch(strtolower($extension)) {
        case "gif":
            $objImage = imagecreatefromgif($FileName);
            break;
        case "png":
            $objImage = imagecreatefrompng($FileName);
            break;
        default:
            $objImage = imagecreatefromjpeg($FileName);
            break;
    }

    list($width, $height, $type, $attr) = getimagesize($FileName);
    $TargetWidth = $width;
    $TargetHeight = $height;
    if (!is_null($MaxWidth)) {
        if ($MaxWidth < $TargetWidth) {
            $TargetWidth = $MaxWidth;
            $TargetHeight = round($TargetHeight * $TargetWidth / $width);
        }
    }
    if (!is_null($MaxHeight)) {
        if ($MaxHeight < $TargetHeight) {
            $TargetHeight = $MaxHeight;
            $TargetWidth = round($TargetWidth * $TargetHeight / $height);
        }
    }


    $DestImage = imagecreatetruecolor($TargetWidth, $TargetHeight);

    // handle transparancy    
    if ( ($type == IMAGETYPE_GIF) || ($type == IMAGETYPE_PNG) ) {
        $trnprt_indx = imagecolortransparent($objImage);
        // If we have a specific transparent color
        if ($trnprt_indx >= 0) {
            // Get the original image's transparent color's RGB values
            $trnprt_color  = imagecolorsforindex($objImage, $trnprt_indx);
            // Allocate the same color in the new image resource
            $trnprt_indx    = imagecolorallocate($DestImage, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);

            // Completely fill the background of the new image with allocated color.
            imagefill($DestImage, 0, 0, $trnprt_indx);

            // Set the background color for new image to transparent
            imagecolortransparent($DestImage, $trnprt_indx);
        } elseif ($type == IMAGETYPE_PNG) {

            // Turn off transparency blending (temporarily)
            imagealphablending($DestImage, false);

            // Create a new transparent color for image
            $color = imagecolorallocatealpha($DestImage, 0, 0, 0, 127);

            // Completely fill the background of the new image with allocated color.
            imagefill($DestImage, 0, 0, $color);

            // Restore transparency blending
            imagesavealpha($DestImage, true);
        }
    }



    imagecopyresampled($DestImage, $objImage, 0, 0, 0, 0, $TargetWidth, $TargetHeight, $width, $height); 
    switch(strtolower($extension)) {
        case "gif":
            imagegif($DestImage, $SaveFile);
            break;
        case "png":
            imagepng($DestImage, $SaveFile,0);
            break;
        default:
            imagejpeg($DestImage,$SaveFile,100);
            break;
    }

}
// ---------------------------------------------------------------------------------
//  GetFileExtension
// ---------------------------------------------------------------------------------
function GetFileExtension($inFileName) {
    return substr($inFileName, strrpos($inFileName, '.') + 1);
}

Firstly read in the image size of the image you want to resize using getimagesize();

Work out what the max width and height you want your resized image to be.

Find out which is the largest, the width or the height of your image to be resized.

Find out how much you have to devide that side to make it within the width or height of the resized. Take that value then devide the other side of the image to be resized.

Now you have your resulting width and height of the resized image. just use imagecopyresampled().

There's a PEAR package called Image_Transform (http://pear.php.net/package/Image_Transform) that I've used in the past. It has a lot of great functions for manipulating images and it's very easy to use (don't have to be an advanced PHP programmer)

For later search
This is the correct answer
I found this answer base on : http://php.net/manual/en/function.imagecopyresampled.php#112742

function resizeKeepRatio($path,$new_path,$width, $height){
    $image_info = getimagesize($path);
    $image_type = $image_info[2];
    if ($image_type == IMAGETYPE_JPEG) {
        $image = imagecreatefromjpeg($path);
    } elseif ($image_type == IMAGETYPE_GIF) {
        $image = imagecreatefromgif($path);
    } elseif ($timage_type == IMAGETYPE_PNG) {
        $image = imagecreatefrompng($path);
    }else{
        return false; // The image type does not support
    }

    $new_image = imagecreatetruecolor($width, $height);

    $src_w = imagesx($image);
    $src_h = imagesy($image);

    if($src_w > $src_h){
        $dst_w = $width;
        $dst_h = ($dst_w * $src_h) / $src_w ;

        if($dst_h > $height){
            $dst_h = $height;
            $dst_w = ($dst_h * $src_w) / $src_h;
        }
    }else{
        $dst_h = $height;
        $dst_w = ($dst_h * $src_w) / $src_h;

        if($dst_w > $width){
            $dst_w = $width;
            $dst_h = ($dst_w * $src_h) / $src_w;
        }
    }

    $dst_x = abs($width - $dst_w) / 2;
    $dst_y = abs($height - $dst_h) / 2;

    $color = imagecolorallocatealpha($new_image, 0, 0, 0, 127); //fill transparent background
    if ($image_type != IMAGETYPE_PNG) {
        $color = imagecolorallocatealpha($new_image, 255, 255, 255, 0); //fill white background
    }
    imagefill($new_image, 0, 0, $color);
    imagesavealpha($new_image, true);
    imagecopyresampled($new_image, $image, $dst_x, $dst_y,0,0, $dst_w, $dst_h, $src_w, $src_h);

    if ($image_type == IMAGETYPE_JPEG) {
        imagejpeg(new_image, $new_path);
    } elseif ($image_type == IMAGETYPE_GIF) {
        imagegif(new_image, $new_path);
    } elseif ($image_type == IMAGETYPE_PNG) {
        imagepng(new_image, $new_path);
    }

    return true;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM