使用PHP GD库压缩和调整大小图片无法处理PNG格式,而JPG格式则出现奇怪的结果

4
我正在尝试使用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

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)))

使用readdir()时,应跳过当前目录.和父目录..
    while(($file = readdir($dir))!== false){
        if ($file == "." || $file == "..")
            continue;

编辑

第二点尤其重要,imagepng()接受大于9的值,但通常会因zlib或libpng错误而无法生成损坏的PNG文件。

我尝试过调整一些PNG和JPEG,并且在这些更改中没有遇到任何问题。


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