为什么调整大小后的PNG图片比原始图片要大很多?

9
我很困惑为什么使用GD库调整大小后的PNG图像比原始图像要大得多。
这是我用来调整图像大小的代码:
// create image from posted file
$src = imagecreatefrompng($file['tmp_name']);
// get original size of uploaded image
list($width,$height) = getimagesize($file['tmp_name']);
if($width>$maxImgWidth) {
    // resize the image to maxImgWidth, maintain the original aspect ratio
    $newwidth = $maxImgWidth;
    $newheight=($height/$width)*$newwidth;
    $newImage=imagecreatetruecolor($newwidth,$newheight);

    // fill transparent with white
    /*$white=imagecolorallocate($newImage, 255, 255, 255); 
    imagefill($newImage, 0, 0, $white);*/

    // the following is to keep PNG's alpha channels
    // turn off transparency blending temporarily
    imagealphablending($newImage, false);
    // Fill the image with transparent color
    $color = imagecolorallocatealpha($newImage,255,255,255,127);
    imagefill($newImage, 0, 0, $color); 
    // restore transparency blending
    imagesavealpha($newImage, true);

    // do the image resizing by copying from the original into $newImage image
    imagecopyresampled($newImage,$src,0,0,0,0,$newwidth,$newheight,$width,$height);

    // write image to buffer and save in variable
    ob_start(); // Stdout --> buffer
    imagepng($newImage,NULL,5); // last parameter is compression 0-none 9-best (slow), see also http://www.php.net/manual/en/function.imagepng.php
    $newImageToSave = ob_get_contents(); // store stdout in $newImageToSave
    ob_end_clean(); // clear buffer
    // remove images from php buffer
    imagedestroy($src);
    imagedestroy($newImage);
    $resizedFlag = true;
}

然后我将$newImageToSave保存为MySQL数据库中的blob。 我试图防止alpha通道并仅设置白色背景,文件大小没有显着变化。 我尝试设置“压缩”参数(0到9),但仍比原始文件大。

举个例子,我将这张image(1058px * 1296px)调整大小为900px * 1102px。以下是结果:

原始文件:328 KB
PNG(0):3.79 MB
PNG(5):564 KB
PNG(9):503 KB

如果有任何提示可以让调整大小后的图像文件更小,将不胜感激。

--

PS:我认为这可能与比特深度有关,但正如您所见,上面的示例图像具有32位,而调整大小后的图像为24位。


1
你正在使用压缩因子 5。尝试使用 9 看看会发生什么。 - Marc B
1
缩小图像很可能会减小任何“相同颜色”区域的大小,或引入不可见的条纹,从而降低了压缩量。如果您只是打开原始文件并使用imagepng重新保存它而不做任何操作,会发生什么? - Marc B
@MarcB 当我使用上述代码仅加载PNG并将其重新保存,但“调整大小”为相同大小时,我得到463KB。原始文件为328KB。PNG压缩设置为5。 - Avatar
@mortezakavakebi:点击图片,你会发现它是一个PNG格式的。 - Avatar
你更喜欢白色背景的JPG吗?还是你当前网站的背景? - Baba
显示剩余11条评论
1个回答

13

你调用的大多数函数来缩小图像,如imagefillimagealphablending等,可能会导致更高的文件大小。

为了保持透明,请使用imagecreate而不是imagecreatetruecolor,并进行简单的调整。

$file['tmp_name'] = "wiki.png";
$maxImgWidth = 900;
// create image from posted file
$src = imagecreatefrompng($file['tmp_name']);
// get original size of uploaded image
list($width, $height) = getimagesize($file['tmp_name']);
if ($width > $maxImgWidth) {
    $newwidth = $maxImgWidth;
    $newheight = ($height / $width) * $newwidth;
    $newImage = imagecreate($newwidth, $newheight);
    imagecopyresampled($newImage, $src, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
    imagepng($newImage, "wiki2.png", 5); 
    imagedestroy($src);
    imagedestroy($newImage);
    $resizedFlag = true;
}

最终大小:164KB


1
太好了,谢谢!原始大小:328KB → 使用您的代码调整大小后:163KB。唯一让我困惑的是,为什么现在透明通道能保留,而之前的某些代码会变成黑色。 - Avatar
看我的解释......你现在正在使用imagecreate......它是一个空白的画布... - Baba
1
由于PNG质量问题(GD使用索引8位调色板),导致文本失真和颜色丢失,我现在正在使用这里的提示,并使用以下代码:$newImageTmp = imagecreatetruecolor($newwidth,$newheight); imagecopyresampled($newImageTmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height); $newImage = imagecreate($newwidth,$newheight); imagecopy($newImage,$newImageTmp,0,0,0,0,$newwidth,$newheight);调色板是基于重新采样的结果确定的,图像质量更好(尽管颜色会丢失)! - Avatar
使用createimage创建的图像:http://i50.tinypic.com/6egcjc.jpg # 使用truecolor进行微调后的图像(先使用truecolor,然后复制):http://i45.tinypic.com/qn18gg.png - Avatar
是的,你说得对。我还有另一个问题:http://stackoverflow.com/questions/13642018/optimize-png-when-resizing-with-gd-php-how-to-determine-color-palette - Avatar
显示剩余2条评论

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