Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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:

It's an image!

I want to produce the following image:

It's an image, with a drop shadow!


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:

It's some Photoshop settings!

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.

like image 298
Josh Avatar asked Sep 02 '11 19:09

Josh


2 Answers

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

?>
like image 131
horatio Avatar answered Sep 21 '22 11:09

horatio


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{%}

result

like image 20
Alex Avatar answered Sep 21 '22 11:09

Alex