问题
I am looking for a way to add a drop shadow to an image using PHP. Before you answer or vote to close: I am not looking to do this using CSS or HTML. I want to generate an image file. This is not a duplicate of this question nor this one.
I am looking for a very specific effect. For example, given this input image:
I want to produce the following image:
TL;DR: This image above was generated using Photoshop's Drop Shadow effect. I want a look very similar to that. For reference, here's the settings our design team used. Ideally, I'd have similar control in my code for angle, distance, opacity, etc:
I have full access to our debian-linus-based servers, so any GD or ImageMagick solution will work. As will any FOSS linux software solution, although I'd prefer a way to do it with IM or GD as those are already installed and don't require new software to be installed.
The shadow must be able to be placed on a transparent, non-rectangular PNG!
I'm asking the question mainly because the scripts and solutions I have found on the web either only produce rectangular shadows, look like total poo, or just plain don't work at all.
回答1:
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.
回答2:
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);
?>
回答3:
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{%}
回答4:
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;
}
回答5:
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.
回答6:
This answer doesn't provide a Python solution, but it does give the generic algorithm required.
Taking images from an outstanding question about drop-shadows that i have, we start with an image:
convert the image to black and white:
apply a gaussian blur, and offset the image as desired:
finally overlay the original image:
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.
来源:https://stackoverflow.com/questions/7288173/how-can-i-add-a-drop-shadow-to-an-image-using-php