私は、ユーザーがアップロードした画像を受け入れ、最大幅/高さが4,000pxになるように比例してサイズを変更し、400pxおよび800pxのサムネイルを生成する機能を持っています。透明なPNGを処理し、白い背景を適用する能力が必要です。PHP GDサイズ変更でアーティファクトが発生する
私の現在のコードはこれをすべて行いますが、JPEGに特有の望ましくないアーチファクトを追加します。それらは垂直線であり、クローズアップされたときに非常に洗い流されたバーコードのように見えます(400%Zoomed Screenshot添付)。これは、拡大縮小されているサイズでアップロードされたときに元の画像にも発生します。透明なPNGではさらに普及しているようですが、JPEGの白い領域でも同様に起こります。 JPEGファイルは、(Windows上でUbuntuの下ではなく、PHP 7.0.1の下でPHP 7.1.3で発生した)私は問題が環境に固有であると結論品質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', '[email protected]', $path), 80);
}
}
return $dst;
}
私は 'imagecopyresampled'の代わりに' imagecopyresized'を使ってみてみたいと思います - おそらくこれもまた助けになりますhttp://stackoverflow.com/questions/23200823/gd-quality-issue-with-transparent -pngs || http://stackoverflow.com/questions/23993901/imagecopyresampled-introduces-artifacts-in-transparent-png –
うーん、良い考え方、「imagecopyresized」はうまくいくと思います。私はこの症状がUbuntuのPHP 7.1.3では発生しているが、開発中のWindowsではPHP 7.0.1では発生していないことに気付きました。たぶん、設定関連? –