Я добавляю прозрачный водяной знак PNG к изображению. Водяной знак имеет высокое разрешение, поэтому, прежде чем накладывать его на исходное изображение, я изменяю его размер. Это, кажется, вносит некоторые артефакты в водяной знак, который я не нашел способа избежать.
Исходное изображение:
Измененное изображение (посмотрите на горизонтальную линию «грязь» между буквами »):
Масштабирование измененного изображения (непрозрачное), чтобы прояснить, что я подразумеваю под «грязью» между буквами. Область между «s» и «t», которую я очистил с помощью инструмента select и delete (открыть на новой вкладке, чтобы увидеть полный размер, где это более понятно):
Вот код, который я использую:
function resizeImage($image_filename, $out_filename, $width, $height){ // Get image info $image_info = @getimagesize($image_filename); if ($image_info == false) return false; $org_width = $image_info[0]; $org_height = $image_info[1]; $image_type = $image_info[2]; // Open image if ($image_type == IMAGETYPE_JPEG) $org_image = @imagecreatefromjpeg($image_filename); else if ($image_type == IMAGETYPE_GIF) $org_image = @imagecreatefromgif($image_filename); else if ($image_type == IMAGETYPE_PNG) $org_image = @imagecreatefrompng($image_filename); else return false; // Open stream for resized image $resized_image = @imagecreatetruecolor($width, $height); if ($resized_image == false) return false; // Handle transparency in PNGs if ($image_type == IMAGETYPE_PNG){ $transparent = imagecolorallocatealpha($resized_image, 255, 255, 255, 127); imagefilledrectangle($resized_image, 0, 0, $width, $height, $transparent); imagealphablending($resized_image, false); imagesavealpha($resized_image, true); } // Resize $resize_result = @imagecopyresampled($resized_image, $org_image, 0, 0, 0, 0, $width, $height, $org_width, $org_height); // Free original image @imagedestroy($org_image); // Save if ($image_type == IMAGETYPE_JPEG) $save_result = imagejpeg($resized_image, $out_filename, 90); // 90 = compression else if ($image_type == IMAGETYPE_GIF) $save_result = imagegif($resized_image, $out_filename); else if ($image_type == IMAGETYPE_PNG) $save_result = imagepng($resized_image, $out_filename, 0); // Free resized image if ($resize_result) @imagedestroy($resized_image); return ($resize_result && $save_result); }
Любая идея о том, что вызывает артефакты?
Это, похоже, не происходит на черном фоне, поэтому другой взлом должен состоять в том, чтобы инвертировать изображение перед изменением размера и сделать это снова после
imagefilter($org_image, IMG_FILTER_NEGATE); imagecopyresampled($resized_image, $org_image, 0, 0, 0, 0, $width, $height, $org_width, $org_height); imagefilter($resized_image, IMG_FILTER_NEGATE);
Хорошо, в первую очередь, вот ваше «грязное» тестовое изображение с каналами RGB (выше) и альфа-каналом (ниже):
Я заменил чистый белый ( #FFFFFF
) / 100% прозрачный синий, чтобы выделить пятнышки.
Как вы можете видеть, GD добавляет speckles как к каналам RGB, так и к альфа-каналу.
Не изучив GD-код, я предполагаю, что это вызвано ошибкой округления, в результате чего некоторые пиксели отключены на 1 или 2.
Я заметил, что у вас встроенный цветовой профиль в исходном PNG. Попробуйте удалить это; артефакты могут быть вызваны выполнением коррекции цвета GD. (В Photoshop вы должны использовать «Сохранить для Интернета»).
В противном случае я не могу предложить способ решить эту проблему, не исправляя код GD, однако я могу предложить грязное обходное решение, которое может работать:
Вместо того, чтобы изменять размер водяного знака до целевого размера изображения, затем накладывая его на целевое изображение, вы можете изменить размер целевого изображения на размер водяного знака, наложить водяной знак, сбросить альфа-канал и затем изменить размер до старого размера целевого изображения. Таким образом, вы избегаете изменения размера изображения, когда у него есть альфа-канал, который может избежать видимых артефактов.
Как я писал в своем комментарии в ответ на ответ Сёрен Лёборгс, похоже, что это просто проблема с GD / imagecopyresampled()
которую нельзя легко избежать. Проблема GD Quality с прозрачными PNG имеет ту же проблему.
Можно использовать предложенный Søren Løvborgs способ обхода, просто имейте в виду, что он может ввести заметное снижение качества из-за изменения размера исходного изображения в два раза.
Я предлагаю использовать редактор фотографий для изменения размера водяного знака перед наложением. Это не так гибко, но оно сохранит качество изображения и не добавит шума.