我有一个功能,我用来接受用户上传的图像,按比例将其缩放到最大宽度/高度为4,000px,并生成400px和800px缩略图。它需要能够处理透明的PNG并应用白色背景。
我当前的代码完成了所有这些操作,然而,它增加了不典型的JPEG图像。它们是垂直条纹,当近距离观察时看起来像一个非常褪色的条形码(附加400%Zoomed截图)。当按照缩放到的尺寸上传时,这甚至会出现在原始图像上。它似乎在透明PNG中更为普遍,但也出现在JPEG的白色区域。 JPEG正在使用Quality 80保存。
function resize_image($file, $w, $h, $strict = false, $crop = false, $path = null, $thumbnail = false)
{
// Check for Valid Image + Calculate Ratio
list($width, $height) = getimagesize($file);
if (empty($width) || empty($height))
{
echo json_encode(['result' => 'error', 'error' => 'file_format_invalid']);
http_response_code(405);
exit;
}
$r = $width / $height;
if (!$strict)
{
$w = min($w, $width);
$h = min($h, $height);
}
$wTa = min($w, 400);
$hTa = min($h, 400);
$wTb = min($w, 800);
$hTb = min($h, 800);
// Apply Crop Constraint
if ($crop)
{
if ($width > $height)
{
$width = ceil($width - ($width * abs($r - $w / $h)));
$widthTa = ceil($width - ($width * abs($r - $wTa / $hTa)));
$widthTb = ceil($width - ($width * abs($r - $wTb / $hTb)));
}
else
{
$height = ceil($height - ($height * abs($r - $w / $h)));
$heightTa = ceil($height - ($height * abs($r - $wTa / $hTa)));
$heightTb = ceil($height - ($height * abs($r - $wTa / $hTb)));
}
$newWidth = $w;
$newHeight = $h;
}
else
{
if ($w / $h > $r || $r < 1)
{
$newWidth = $h * $r;
$newWidthTa = $hTa * $r;
$newWidthTb = $hTb * $r;
$newHeight = $h;
$newHeightTa = $hTa;
$newHeightTb = $hTb;
}
else
{
$newHeight = $w / $r;
$newHeightTa = $wTa / $r;
$newHeightTb = $wTb / $r;
$newWidth = $w;
$newWidthTa = $wTa;
$newWidthTb = $wTb;
}
}
// Create, Resample + Return Image
$src = imagecreatefromstring(file_get_contents($file));
$dst = imagecreatetruecolor($newWidth, $newHeight);
$fff = imagecolorallocate($dst, 255, 255, 255);
imagefill($dst, 0, 0, $fff);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if (!is_null($path))
{
imagejpeg($dst, $path, 80);
if ($thumbnail)
{
$dstThumbA = imagecreatetruecolor($newWidthTa, $newHeightTa);
$dstThumbB = imagecreatetruecolor($newWidthTb, $newHeightTb);
$fffThumbA = imagecolorallocate($dstThumbA, 255, 255, 255);
$fffThumbB = imagecolorallocate($dstThumbB, 255, 255, 255);
imagefill($dstThumbA, 0, 0, $fffThumbA);
imagefill($dstThumbB, 0, 0, $fffThumbB);
imagecopyresampled($dstThumbA, $src, 0, 0, 0, 0, $newWidthTa, $newHeightTa, $width, $height);
imagecopyresampled($dstThumbB, $src, 0, 0, 0, 0, $newWidthTb, $newHeightTb, $width, $height);
imagejpeg($dstThumbA, str_replace('.jpg', '-thumb.jpg', $path), 80);
imagejpeg($dstThumbB, str_replace('.jpg', '-thumb@2x.jpg', $path), 80);
}
}
return $dst;
}
答案 0 :(得分:0)
我得出结论,该问题是针对环境的(在Ubuntu下的PHP 7.1.3上发生,但在Windows上不在PHP 7.0.1下发生)。重新安装php7.1
和php7.1-gd
无效。
最终我决定咬紧牙关并使用ImageMagick重写,从而产生更简洁的代码块:
$magickSource = new Imagick();
$magickSource->readImageBlob(file_get_contents($file));
$magickSource = $magickSource->flattenImages();
$magickFull = clone $magickSource;
$magickFull->resizeImage(min($originalWidth, $newWidth), min($originalHeight, $newHeight), Imagick::FILTER_LANCZOS, 1, true);
$magickFull->setImageCompression(Imagick::COMPRESSION_JPEG);
$magickFull->setImageCompressionQuality(75);
$magickFull->stripImage();
$magickFull->writeImage($path);
$magickFull->destroy();
if ($thumbnail)
{
$magickThumb = clone $magickSource;
$magickThumb->resizeImage(min($originalWidth, 400), min($originalHeight, 400), Imagick::FILTER_LANCZOS, 1, true);
$magickThumb->setImageCompression(Imagick::COMPRESSION_JPEG);
$magickThumb->setImageCompressionQuality(75);
$magickThumb->stripImage();
$magickThumb->writeImage(str_replace('.jpg', '-thumb.jpg', $path));
$magickThumb->destroy();
}
对setImageCompression()
,setImageCompressionQuality
和stripImage()
的调用使合并文件大小减少了53%。 ({{3}})