Ответ 1
Вы не сможете сделать это на PHP без построения полного алгоритма крайнего детектора и значительных издержек обработки. Посмотрите на использование GIMP с некоторым script -fu, и пусть это сделает тяжелую работу для вас.
Я ищу способ добавить тень к изображению с помощью PHP. Прежде чем ответить или проголосовать, чтобы закрыть: я не ищу этого, используя CSS или HTML. Я хочу создать файл изображения. Это не дубликат этого вопроса, а этот.
Я ищу очень специфический эффект. Например, учитывая это входное изображение:
Я хочу создать следующее изображение:
TL; DR: Данное изображение было создано с использованием эффекта Drop Drop Shadow. Я хочу выглядеть очень похоже на это. Для справки, здесь настройки, которые использовала наша команда разработчиков. В идеале, у меня был бы аналогичный контроль в моем коде для угла, расстояния, непрозрачности и т.д.:
У меня есть полный доступ к нашим серверам на основе debian-linus, поэтому любое решение GD или ImageMagick будет работать. Как и любое программное обеспечение FOSS linux, хотя я бы предпочел сделать это с помощью IM или GD, поскольку они уже установлены и не требуют установки нового программного обеспечения.
Тень должна быть размещена на прозрачном, не прямоугольном PNG!
Я задаю вопрос главным образом потому, что скрипты и решения, которые я нашел в Интернете, либо производят только прямоугольные тени, но и выглядят как общее poo или просто не работают вообще.
Вы не сможете сделать это на PHP без построения полного алгоритма крайнего детектора и значительных издержек обработки. Посмотрите на использование GIMP с некоторым script -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 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;
}
Вы можете использовать Библиотеки обработки изображений PHP GD
Здесь - это учебник о том, как добавить теневой эффект. Однако, если это не соответствует вашим потребностям, я уверен, что googling "PHP GD Drop Shadow" сделает трюк.
Этот ответ не дает решения Python, но он дает общий алгоритм.
Принимая изображения от выдающегося вопроса о тенях, которые у меня есть, мы начинаем с изображения:
конвертировать изображение в черно-белое:
примените гауссовское размытие и смещение изображения по желанию:
окончательно накладывает исходное изображение:
Я не знаю Python или что-то в этом роде, но, вероятно, этот алгоритм может помочь вам или кому-то еще споткнуться по этому вопросу.
Примечание. Строго говоря, это должен быть комментарий, но я действительно хотел показать изображения.