Как добавить тень к изображению с помощью PHP?

Я ищу способ добавить тень к изображению с помощью PHP. Прежде чем ответить или проголосовать, чтобы закрыть: я не ищу этого, используя CSS или HTML. Я хочу создать файл изображения. Это не дубликат этого вопроса и не этот .

Я ищу очень специфический эффект . Например, учитывая это входное изображение:

It's an image!

Я хочу создать следующее изображение:

It's an image, with a drop shadow!


TL; DR: Этот снимок был создан с использованием эффекта Drop Shadow. Я хочу выглядеть очень похоже на это. Для справки, вот настройки, которые использовала наша команда разработчиков. В идеале, у меня был бы аналогичный контроль в моем коде для угла, расстояния, непрозрачности и т. Д .:

It's some Photoshop settings!

У меня есть полный доступ к нашим серверам на основе debian-linus, поэтому любое решение GD или ImageMagick будет работать. Как и любое программное обеспечение FOSS linux, хотя я бы предпочел сделать это с помощью IM или GD, поскольку они уже установлены и не требуют установки нового программного обеспечения.

Тень должна быть размещена на прозрачном, не прямоугольном PNG!

Я задаю этот вопрос главным образом потому, что скрипты и решения, которые я нашел в Интернете, производят только прямоугольные тени, выглядят как общий poo или просто не работают вообще.

Вы не сможете это сделать в PHP, не строя в полном алгоритме крайнего детектора и значительных накладных расходах. Посмотрите на использование GIMP с некоторым скриптом-fu, и пусть это сделает вам тяжелую работу.

Просто, черт возьми (я знаю, что это было отвечено и принято): несколько месяцев назад, в ответ на вопрос о графическом дизайне stackexchange о восстановлении маски из PNG, где был потерян исходный файл, я ударил что-то, что использует PHP GD для извлечения альфа-канала из прозрачного PNG. Как Joe в комментарии, упомянутом выше, вы можете использовать альфа-канал в качестве тени, просто смещать его по x и y пикселям, а затем наносить на него фильтр размытия изображения, а затем копировать оригинал сверху. Следующий код, вероятно, SLOW и доказательство концепции, но это начало, и он находится в PHP, как вы изначально запрашивали.

<?php $im = imagecreatefrompng('./images/alphatest_nolayer.png'); $w = imagesx($im); $h = imagesy($im); $om = imagecreatetruecolor($w,$h); for ($x = 0; $x < $w; $x++) { for ($y = 0; $y < $h; $y++) { $rgb = imagecolorat($im, $x, $y); $colors = imagecolorsforindex($im, $rgb); $orgb = imagecolorallocate($om,$colors['alpha'],$colors['alpha'],$colors['alpha']); imagesetpixel($om,$x,$y,$orgb); } } header('Content-Type: image/png'); imagepng($om); imagedestroy($om); imagedestroy($im); ?> 

На самом деле это можно сделать с преобразованием изображения magick, без необходимости в библиотеке GD:

 <?php $cmd = 'convert /path/to/source.png \( +clone -background black -shadow 80x3+4+4 \) \+swap -background none -layers merge +repage /path/to/destination.png'; exec($cmd); ?> 

вы можете немного поиграть с параметром shadow.

 -shadow percent-opacity{xsigma}{+-}x{+-}y{%} 

результат

Я воспользовался советом Марка Б и призвал GIMP сделать это для меня. Если кто-то еще заботится, вот код, который я использовал:

 /** * Call upon The GIMP to apply a dropshadow to a given image. * * NOTE: This will overwrite the image file at $filename! Be sure to make a copy * of this file first if you need one. * * @param string $filename * @param int $offset_x * @param int $offset_y * @param float $radius * @param array $color * @param int $opacity * @return type * @todo Resize the canvas so there's room to apply dropshadows to images which have no whitespace around them. */ function apply_gimp_dropshadow($filename,$offset_x=8,$offset_y=8,$radius=15,$color=false,$opacity=40) { if(!is_array($color)) $color = array(0,0,0); $color = join(' ',$color); $gimpScript = <<<END_OF_SCHEME_CODE_OH_HOW_I_HATE_YOU_SCHEME (define (dropshadow filename) (let* ( (image (car (gimp-file-load RUN-NONINTERACTIVE filename filename))) (drawable (car (gimp-image-get-active-layer image))) ) (script-fu-drop-shadow image drawable 8 8 15 '($color) 40 FALSE) (set! drawable (car (gimp-image-merge-visible-layers image 0))) (gimp-file-save RUN-NONINTERACTIVE image drawable filename filename) (gimp-image-delete image) ) ) (dropshadow "$filename") (gimp-quit 0) END_OF_SCHEME_CODE_OH_HOW_I_HATE_YOU_SCHEME; $descriptorspec = array( 0 => array("pipe", "r"), // stdin is a pipe that the child will read from 1 => array("pipe", "w"), // stdout is a pipe that the child will write to ); $cwd = '/tmp'; $gimp = proc_open('/usr/bin/gimp -i -b -', $descriptorspec, $pipes, $cwd); if (!is_resource($gimp)) throw new Exception('Could not open a pipe to GIMP'); fwrite($pipes[0], $gimpScript); fclose($pipes[0]); $gimpOutput = stream_get_contents($pipes[1]); fclose($pipes[1]); $gimpResult = proc_close($gimp); return $gimpResult; } 

Вы можете использовать библиотеки обработки изображений GD для PHP

Вот урок о том, как добавить теневой эффект. Однако, если это не соответствует вашим потребностям, я уверен, что googling «PHP GD Drop Shadow» сделает трюк.

Этот ответ не дает решения Python , но он дает общий алгоритм .

  • Принимая изображения от выдающегося вопроса о тенях, которые у меня есть , мы начинаем с изображения:

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

  • конвертировать изображение в черно-белое:

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

  • примените гауссовское размытие и смещение изображения по желанию:

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

  • наконец, наложите исходное изображение:

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

я не знаю Python или что-то в этом роде , но, вероятно, этот алгоритм может помочь вам или кому-то еще споткнуться по этому вопросу.

Примечание . Строго говоря, это должен быть комментарий , но я действительно хотел показать изображения.