Скрипт водяного знака PHP GD создает пустой водяной знак

Я пытаюсь добавить водяной знак к изображениям сразу после загрузки их на мой веб-сайт, но кажется, что водяной знак продолжает появляться как черный объект без деталей. Я полагаю, что скрипт работает немного, потому что, если бы это было не так, я бы, вероятно, не увидел бы какого-либо водяного знака, иначе сценарий вышел бы из строя.

Это мой сценарий до сих пор:

$watermark = imagecreatefrompng('preview-watermark.png');  
$watermark_width = imagesx($watermark);  
$watermark_height = imagesy($watermark);        
$image = imagecreatetruecolor($watermark_width, $watermark_height);  
$image = imagecreatefromjpeg($portfolio_preview_dir.'/'.$file);  
$size = getimagesize($portfolio_preview_dir.'/'.$file);  
$dest_x = $size[0] - $watermark_width - 5;  
$dest_y = $size[1] - $watermark_height - 5;  
imagecopymerge($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height, 100);  
imagejpeg($image, $portfolio_preview_dir.'/'.$file);  
imagedestroy($image); 
imagedestroy($watermark);

Это то, что он производит. Форма водяного знака правильная, так как водяной знак имеет размер 325x37 пикселей:

введите описание изображения здесь

Я пытался играть с изображением самого водяного знака. Моей первой попыткой было сохранение водяного знака в фотошопе (с прозрачным bg), используя "save for web" и выбрав "PNG-24". Это не сработало, поэтому я сохранил его как обычный PNG (без "сохранения для веб"), и он все равно не работает.

Я не уверен, что это сценарий или изображение! Может кто-нибудь поделиться со мной некоторыми знаниями и помочь решить эту проблему?

2 ответа

Решение
$watermark = imagecreatefrompng('preview-watermark.png');
imagealphablending($watermark , false);
imagesavealpha($watermark , true);
$watermark_width = imagesx($watermark);  
$watermark_height = imagesy($watermark);        
$image = imagecreatetruecolor($watermark_width, $watermark_height);  
$image = imagecreatefromjpeg($portfolio_preview_dir.'/'.$file);  
$size = getimagesize($portfolio_preview_dir.'/'.$file);  
$dest_x = $size[0] - $watermark_width - 5;  
$dest_y = $size[1] - $watermark_height - 5;  
imagecopy($image, $watermark, $dest_x, $dest_y, 0, 0, $watermark_width, $watermark_height);  
imagejpeg($image, $portfolio_preview_dir.'/'.$file);  
imagedestroy($image); 
imagedestroy($watermark);

Есть вещи:

  1. imagecopymerge не позволяет прозрачность для PNG-24

(Источник: https://drupal.org/node/80369)

  1. imagesavealpha + imagealphablending позволяют сохранить прозрачность

(Источник: http://php.net/manual/en/function.imagesavealpha.php)

Я надеюсь, что это решит вашу проблему.

Также вы выводите JPEG, почему? Оставайтесь с PNG и ваше изображение будет поддерживать прозрачные водяные знаки, сейчас это не так!

Есть много решений на SO и php.net. Это один (без создания самого нового изображения)

// Load the stamp and the photo to apply the watermark to
$stamp = imagecreatefrompng('stamp.png');
$im = imagecreatefromjpeg('photo.jpeg');

// Set the margins for the stamp and get the height/width of the stamp image
$marge_right = 10;
$marge_bottom = 10;
$sx = imagesx($stamp);
$sy = imagesy($stamp);

// Copy the stamp image onto our photo using the margin offsets and the photo 
// width to calculate positioning of the stamp. 
imagecopy($im, $stamp, imagesx($im) - $sx - $marge_right, imagesy($im) - $sy - $marge_bottom, 0, 0, imagesx($stamp), imagesy($stamp));

// Output and free memory
header('Content-type: image/png');
imagepng($im);
imagedestroy($im);

редактировать

Водяной знак должен быть сохранен с помощью альфа-канала (прозрачность). Photoshop, так как CS2 (кроме веб-страниц) должен делать то же самое, также отлично работает GIMP.

Другие вопросы по тегам