Как я могу добавить тень к изображению, используя PHP? - PullRequest
13 голосов
/ 02 сентября 2011

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

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

It's an image!

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

It's an image, with a drop shadow!


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

It's some Photoshop settings!

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

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

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

Ответы [ 6 ]

19 голосов
/ 03 сентября 2011

Просто, к черту, это (я знаю, что на него ответили и приняли): несколько месяцев назад, в ответ на вопрос о стеке обмена графическим дизайном о восстановлении маски из PNG, где был потерян исходный файл, я что-то собрал воедино который использует функции PHP GD для извлечения альфа-канала из прозрачного PNG. Как отметил Джо в комментарии, упомянутом выше, вы можете использовать альфа-канал в качестве тени, просто сместить его на пиксели x и y, а затем применить к нему фильтр размытия свертки изображения, а затем скопировать оригинал сверху. Следующий код, вероятно, медленный и подтверждение концепции, но это начало, и оно в 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);

?>
9 голосов
/ 27 июля 2012

На самом деле это можно сделать с помощью конвертации магики изображений, нет необходимости в библиотеке 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 percent-opacity{xsigma}{+-}x{+-}y{%}

result

6 голосов
/ 03 сентября 2011

Я воспользовался советом Марка Б. и призвал 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;
}
6 голосов
/ 02 сентября 2011

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

3 голосов
/ 02 сентября 2011

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

Здесь - это учебное пособие о том, как добавить эффект тени.Однако, если это не соответствует вашим потребностям, я уверен, что поиск в Google PHP Shadow Shadow поможет вам.

2 голосов
/ 28 мая 2012

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

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

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

...