How can I add a drop-shadow to an image using PHP?

怎甘沉沦 提交于 2019-12-03 05:39:36

You're not going to be able to do this in PHP without building in a full edge-detector algorithm and significant processing overhead. Look into using GIMP with some script-fu, and let it do the hard work for you.

Just for the hell of it (I know it was answered and accepted): a few months ago, in response to a question on graphic design stackexchange about recovering a mask from a PNG where the source file was lost I slapped together something which uses PHP GD functions to extract the alpha channel from a transparent PNG. As Joe in a comment mentioned above, you can use the alpha channel as the drop shadow, merely offset it by x and y pixels, and then apply an image convolution blur filter to it, then copymerge the original on top. Following code is probably SLOW and proof of concept, but it is a start and it is in PHP as you originally requested.

<?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);

?>

Actually this can be done with image magick's convert, no need for GD library:

<?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);
?>

you can play a little with the shadow parameter.

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

Josh

I used Marc B's advice, and called upon The GIMP to do this for me. If anyone else cares, here's the code I used:

/**
 * 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;
}

You can use PHPs GD Image Processing Libraries

Here is a tutorial on how to add the shadow effect. However if this doesn't fit your needs i'm sure googling "PHP GD Drop Shadow" will do the trick.

Ian Boyd

This answer doesn't provide a Python solution, but it does give the generic algorithm required.

i don't know Python, or anything about it, but presumably this algorithm can help you, or someone else stumbling across this question.

Note: Strictly speaking this should be a comment, but i really wanted to be able to show the images.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!