使用 PHP GD lib 压缩和调整图像大小不适用于 png 和 jpg 的奇怪结果

Posted

技术标签:

【中文标题】使用 PHP GD lib 压缩和调整图像大小不适用于 png 和 jpg 的奇怪结果【英文标题】:Compress & resize images using PHP GD lib not working for png and weird results for jpg 【发布时间】:2019-09-13 12:42:21 【问题描述】:

我正在尝试使用 php GD 库压缩和调整图像大小。几乎所有关于 SO 和其他任何地方的答案都是相同的,但是对于我的解决方案,PNG 没有被正确转换,并且一些 jpg 给出了奇怪的结果。

这是我正在使用的代码:

public function resizeImages() 
    ini_set('max_execution_time', 0);

    //Initial settings, Just specify Source and Destination Image folder.
    $ImagesDirectory    = FCPATH . 'design/img/test/'; //Source Image Directory End with Slash
    $DestImagesDirectory    = FCPATH . 'design/img/test/thumb/'; //Destination Image Directory End with Slash
    $NewImageWidth      = 150; //New Width of Image
    $NewImageHeight     = 150; // New Height of Image
    $Quality        = 90; //Image Quality

    //Open Source Image directory, loop through each Image and resize it.
    if($dir = opendir($ImagesDirectory))
        while(($file = readdir($dir))!== false)
            $imagePath = $ImagesDirectory.$file;
            $destPath = $DestImagesDirectory.$file;
            $checkValidImage = @getimagesize($imagePath);

            if(file_exists($imagePath) && $checkValidImage) //Continue only if 2 given parameters are true
            
                //Image looks valid, resize.
                if (resize_image($imagePath,$destPath,$NewImageWidth,$NewImageHeight,$Quality))
                
                    echo $file.' resize Success!<br />';
                    /*
                    Now Image is resized, may be save information in database?
                    */

                 else 
                    echo $file.' resize Failed!<br />';
                
            
        
        closedir($dir);
    

resize_image 函数如下所示:

function resize_image($SrcImage,$DestImage, $MaxWidth,$MaxHeight,$Quality)
    
        list($iWidth,$iHeight,$type)    = getimagesize($SrcImage);
        $ImageScale             = min($MaxWidth/$iWidth, $MaxHeight/$iHeight);
        $NewWidth               = ceil($ImageScale*$iWidth);
        $NewHeight              = ceil($ImageScale*$iHeight);
        $NewCanves              = imagecreatetruecolor($NewWidth, $NewHeight);

        $imagetype = strtolower(image_type_to_mime_type($type));

        switch($imagetype)
        
            case 'image/jpeg':
                $NewImage = imagecreatefromjpeg($SrcImage);
                break;
            case 'image/png':
                $NewImage = imagecreatefrompng($SrcImage);
                break;
            default:
                return false;
        

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

        // Resize Image
        if(imagecopyresampled($NewCanves, $NewImage,0, 0, 0, 0, $NewWidth, $NewHeight, $iWidth, $iHeight))
        
            switch ($imagetype) 
                case 'image/jpeg':
                    if(imagejpeg($NewCanves,$DestImage,$Quality))
                    
                        imagedestroy($NewCanves);
                    
                    break;
                case 'image/png':
                    if(imagepng($NewCanves,$DestImage,$Quality))
                    
                        imagedestroy($NewCanves);
                    
                    break;
                default:
                    return false;
            
            return true;
        
    

每个 png 都不起作用,它只返回一个 0 字节的文件并且“不支持文件类型”,即使该类型在 Windows 中被识别为 .PNG...

一些 JPG 也返回了一个奇怪的结果,请参阅以下屏幕截图,它表明我对 png 和一些 jpg 的问题:

【问题讨论】:

【参考方案1】:

1)不要使用getimagesize来验证文件是否为有效图片,要提手册:

不要使用 getimagesize() 来检查给定文件是否为有效图像。请改用 Fileinfo 扩展等专用解决方案。

$checkValidImage = exif_imagetype($imagePath);
if(file_exists($imagePath) && ($checkValidImage == IMAGETYPE_JPEG || $checkValidImage == IMAGETYPE_PNG))

2) imagejpeg() 接受 0 到 100 之间的质量,imagepng() 需要 0 到 9 之间的值,你可以这样做:

if(imagepng($NewCanves,$DestImage,round(($Quality/100)*9)))

3) 使用readdir (),您应该跳过当前目录. 和父目录..

    while(($file = readdir($dir))!== false)
        if ($file == "." || $file == "..")
            continue;

编辑

第 2 点尤为重要,imagepng () 接受大于 9 的值,但随后经常在 zlib 或 libpng 生成损坏的 png 文件时出错。

我尝试调整一些 png 和 jpeg 的大小,但这些更改没有遇到任何问题。

【讨论】:

以上是关于使用 PHP GD lib 压缩和调整图像大小不适用于 png 和 jpg 的奇怪结果的主要内容,如果未能解决你的问题,请参考以下文章

使用gd在php中调整图像大小后的黑色背景

使用 PHP GD 调整图像大小并保存图像。这段代码有啥问题?

PHP GD - 调整图像框架/画布的大小,但不是实际图像

在 PHP 中调整 PHP GD 生成的图像的大小并显示它

如何使用 PHP 和 GD 获取图像资源大小(以字节为单位)?

如何使用 PHP 的 GD 库对图像执行接缝雕刻?