使用PHP调整图像大小,支持PNG、JPG。

23

我正在使用这个类:

class ImgResizer {

function ImgResizer($originalFile = '$newName') {
    $this -> originalFile = $originalFile;
}
function resize($newWidth, $targetFile) {
    if (empty($newWidth) || empty($targetFile)) {
        return false;
    }
    $src = imagecreatefromjpeg($this -> originalFile);
    list($width, $height) = getimagesize($this -> originalFile);
    $newHeight = ($height / $width) * $newWidth;
    $tmp = imagecreatetruecolor($newWidth, $newHeight);
    imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    if (file_exists($targetFile)) {
        unlink($targetFile);
    }
    imagejpeg($tmp, $targetFile, 95);
}

}

这个方法非常出色,但对于png图片会失败,它会生成一个调整大小的黑色图像。

有没有办法修改这个类以支持png图像?


这个问题可能会帮助你找到答案:https://dev59.com/K2LVa4cB1Zd3GeqPvmDo - ReLeaf
imagecreatefrompng($filename) - Võ Minh
7个回答

52
function resize($newWidth, $targetFile, $originalFile) {

    $info = getimagesize($originalFile);
    $mime = $info['mime'];

    switch ($mime) {
            case 'image/jpeg':
                    $image_create_func = 'imagecreatefromjpeg';
                    $image_save_func = 'imagejpeg';
                    $new_image_ext = 'jpg';
                    break;

            case 'image/png':
                    $image_create_func = 'imagecreatefrompng';
                    $image_save_func = 'imagepng';
                    $new_image_ext = 'png';
                    break;

            case 'image/gif':
                    $image_create_func = 'imagecreatefromgif';
                    $image_save_func = 'imagegif';
                    $new_image_ext = 'gif';
                    break;

            default: 
                    throw new Exception('Unknown image type.');
    }

    $img = $image_create_func($originalFile);
    list($width, $height) = getimagesize($originalFile);

    $newHeight = ($height / $width) * $newWidth;
    $tmp = imagecreatetruecolor($newWidth, $newHeight);
    imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    if (file_exists($targetFile)) {
            unlink($targetFile);
    }
    $image_save_func($tmp, "$targetFile.$new_image_ext");
}

你介意把它重写成调整大小的函数吗?我特别共享了这个类,以便我们可以扩展它。 - Toni Michel Caubet
嗨!我刚测试了一下,它给了我一个错误,说它抛出了未知的异常...你有什么想法吗?(问题在于在switch语句中进入默认值,所以无法正确识别mime类型?) - Toni Michel Caubet
那个函数中原始的高度/宽度没有被定义,是吗? - ForrestLyman
在我的情况下,我需要从最后一行中删除 $new_image_ext。$image_save_func($tmp, "$targetFile"); - Confused
1
运行良好,但在指定保存图像位置时包含 $new_image_ext 是没有意义的。此 resize 函数的预期输入为 resize(100, "newfile.png", "oldfile.png")。另外,throw Exception 应该是 throw new Exception。已编辑问题以反映这一点。 - fgblomqvist
显示剩余4条评论

13
我写了一个类,可以做到这一点,并且非常易于使用。它被称为PHP Image Magician
$magicianObj = new imageLib('racecar.jpg');
$magicianObj -> resizeImage(100, 200);
$magicianObj -> saveImage('racecar_convertd.png', 100);

它支持以下格式的读取和写入(包括转换):
  • jpg
  • png
  • gif
  • bmp
并且仅能读取以下格式:
  • psd's
示例
// Include PHP Image Magician library
require_once('php_image_magician.php');

// Open JPG image
$magicianObj = new imageLib('racecar.jpg');

// Resize to best fit then crop
$magicianObj -> resizeImage(100, 200, 'crop');

// Save resized image as a PNG
$magicianObj -> saveImage('racecar_small.png');

你的库能否自动根据宽度调整高度的大小? - Shafizadeh

7

您可以尝试这个方法。目前它假设图像将始终是jpeg格式。使用此方法可以加载jpeg、png或gif格式的图像。我没有测试过,但应该可以正常工作。

function resize($newWidth, $targetFile) {
    if (empty($newWidth) || empty($targetFile)) {
        return false;
    }

    $fileHandle = @fopen($this->originalFile, 'r');

    //error loading file
    if(!$fileHandle) {
        return false;
    }

    $src = imagecreatefromstring(stream_get_contents($fileHandle));

    fclose($fileHandle);

    //error with loading file as image resource
    if(!$src) {
        return false;
    }

    //get image size from $src handle
    list($width, $height) = array(imagesx($src), imagesy($src));

    $newHeight = ($height / $width) * $newWidth;

    $tmp = imagecreatetruecolor($newWidth, $newHeight);

    imagecopyresampled($tmp, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    //allow transparency for pngs
    imagealphablending($tmp, false);
    imagesavealpha($tmp, true);

    if (file_exists($targetFile)) {
        unlink($targetFile);
    }

    //handle different image types.
    //imagepng() uses quality 0-9
    switch(strtolower(pathinfo($this->originalFile, PATHINFO_EXTENSION))) {
        case 'jpg':
        case 'jpeg':
            imagejpeg($tmp, $targetFile, 95);
            break;
        case 'png':
            imagepng($tmp, $targetFile, 8.5);
            break;
        case 'gif':
            imagegif($tmp, $targetFile);
            break;
    }

    //destroy image resources
    imagedestroy($tmp);
    imagedestroy($src);
}

我不明白“假设图像是jpg”是什么意思。 - Toni Michel Caubet
在原始的resize方法中,$originalFile只被处理为jpeg格式进行调整大小(imagecreatefromjpeg/imagejpeg)。 - Austin Brunkhorst
我尝试将我的resize()函数替换为你的,但是它没有生成任何图像 ;S - Toni Michel Caubet
1
@Sharpless512 在 switch/case 语句中适当的位置加入了 break 语句。 - O. Jones
1
谢谢,我没听懂那个笑话。 (不是故意的) - Austin Brunkhorst
这是第一个示例,它不包括imagecreatefromjpeg(),并且在我摆脱它后立即为我工作的第一个示例。其他示例可以工作,但图像完全是黑色的。 - batoutofhell

3

试试这个方法,使用它可以将图片保存到指定路径。

function resize($file, $imgpath, $width, $height){
    /* Get original image x y*/
    list($w, $h) = getimagesize($file['tmp_name']);
    /* calculate new image size with ratio */
    $ratio = max($width/$w, $height/$h);
    $h = ceil($height / $ratio);
    $x = ($w - $width / $ratio) / 2;
    $w = ceil($width / $ratio);

    /* new file name */
    $path = $imgpath;
    /* read binary data from image file */
    $imgString = file_get_contents($file['tmp_name']);
    /* create image from string */
    $image = imagecreatefromstring($imgString);
    $tmp = imagecreatetruecolor($width, $height);
    imagecopyresampled($tmp, $image, 0, 0, $x, 0, $width, $height, $w, $h);
    /* Save image */
    switch ($file['type']) {
       case 'image/jpeg':
          imagejpeg($tmp, $path, 100);
          break;
       case 'image/png':
          imagepng($tmp, $path, 0);
          break;
       case 'image/gif':
          imagegif($tmp, $path);
          break;
          default:
          //exit;
          break;
        }
     return $path;

     /* cleanup memory */
     imagedestroy($image);
     imagedestroy($tmp);
}

现在,您需要在保存图像时调用此函数,如下所示...
<?php

    //$imgpath = "Where you want to save your image";
    resize($_FILES["image"], $imgpath, 340, 340);

?>

如果我想将总图片质量降低50%而不是固定数量以保持纵横比怎么办? - Dimitri Bostrovich
经过一些修改,它运行良好。 - UserOfStackOverFlow

1

我采用了P. Galbraith的版本,修复了错误,并将其更改为按面积(宽度x高度)调整大小。对于我自己,我想要调整过大的图像。

function resizeByArea($originalFile,$targetFile){

    $newArea = 375000; //a little more than 720 x 480

    list($width,$height,$type) = getimagesize($originalFile);
    $area = $width * $height;

if($area > $newArea){

    if($width > $height){ $big = $width; $small = $height; }
    if($width < $height){ $big = $height; $small = $width; }

    $ratio = $big / $small;

    $newSmall = sqrt(($newArea*$small)/$big);
    $newBig = $ratio*$newSmall;

    if($width > $height){ $newWidth = round($newBig, 0); $newHeight = round($newSmall, 0); }
    if($width < $height){ $newWidth = round($newSmall, 0); $newHeight = round($newBig, 0); }

    }

switch ($type) {
    case '2':
            $image_create_func = 'imagecreatefromjpeg';
            $image_save_func = 'imagejpeg';
            $new_image_ext = '.jpg';
            break;

    case '3':
            $image_create_func = 'imagecreatefrompng';
         // $image_save_func = 'imagepng';
         // The quality is too high with "imagepng"
         // but you need it if you want to allow transparency
            $image_save_func = 'imagejpeg';
            $new_image_ext = '.png';
            break;

    case '1':
            $image_create_func = 'imagecreatefromgif';
            $image_save_func = 'imagegif';
            $new_image_ext = '.gif';
            break;

    default: 
            throw Exception('Unknown image type.');
}

    $img = $image_create_func($originalFile);
    $tmp = imagecreatetruecolor($newWidth,$newHeight);
    imagecopyresampled( $tmp, $img, 0, 0, 0, 0,$newWidth,$newHeight, $width, $height );

    ob_start();
    $image_save_func($tmp);
    $i = ob_get_clean();

    // if file exists, create a new one with "1" at the end
    if (file_exists($targetFile.$new_image_ext)){
      $targetFile = $targetFile."1".$new_image_ext;
    }
    else{
      $targetFile = $targetFile.$new_image_ext;
    }

    $fp = fopen ($targetFile,'w');
    fwrite ($fp, $i);
    fclose ($fp);

    unlink($originalFile);
}

如果您想允许透明度,请勾选此选项:http://www.akemapa.com/2008/07/10/php-gd-resize-transparent-image-png-gif/ 我测试了该功能,它运行良好!

有趣!我会进行一些测试并告诉你结果。谢谢! - Toni Michel Caubet

0

被接受的答案有很多错误,这里已经修复了。

<?php 




function resize($newWidth, $targetFile, $originalFile) {

    $info = getimagesize($originalFile);
    $mime = $info['mime'];

    switch ($mime) {
            case 'image/jpeg':
                    $image_create_func = 'imagecreatefromjpeg';
                    $image_save_func = 'imagejpeg';
                    $new_image_ext = 'jpg';
                    break;

            case 'image/png':
                    $image_create_func = 'imagecreatefrompng';
                    $image_save_func = 'imagepng';
                    $new_image_ext = 'png';
                    break;

            case 'image/gif':
                    $image_create_func = 'imagecreatefromgif';
                    $image_save_func = 'imagegif';
                    $new_image_ext = 'gif';
                    break;

            default: 
                    throw Exception('Unknown image type.');
    }

    $img = $image_create_func($originalFile);
    list($width, $height) = getimagesize($originalFile);
    $newHeight = ($height / $width) * $newWidth;
    $tmp = imagecreatetruecolor($newWidth, $newHeight);
    imagecopyresampled($tmp, $img, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);

    if (file_exists($targetFile)) {
            unlink($targetFile);
    }
    $image_save_func($tmp, "$targetFile.$new_image_ext");
}



$img=$_REQUEST['img'];
$id=$_REQUEST['id'];

  //  echo $img
resize(120, $_SERVER['DOCUMENT_ROOT'] ."/images/$id",$_SERVER['DOCUMENT_ROOT'] ."/images/$img") ;


?>

0

我知道这是一个很老的帖子,但我发现PHP内置了imagescale函数,可以完成所需的工作。请参阅此处的文档。

示例用法:

$temp = imagecreatefrompng('1.png'); 
$scaled_image= imagescale ( $temp, 200 , 270);

这里的200是调整大小后图像的宽度,270是高度。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接