如何使用PHP为图像添加阴影?

时间:2021-11-20 04:08:47

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.

我正在寻找一种使用PHP为图像添加阴影的方法。在你回答或投票结束之前:我不打算用CSS或HTML来做这件事。我想生成一个图像文件。这不是这个问题的重复,也不是这个问题的重复。

I am looking for a very specific effect. For example, given this input image:

我正在寻找一个非常具体的效果。例如,给定此输入图像:

如何使用PHP为图像添加阴影?

I want to produce the following image:

我想生成以下图像:

如何使用PHP为图像添加阴影?


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:

TL; DR:上面的图像是使用Photoshop的投影效果生成的。我希望看起来非常相似。作为参考,这是我们的设计团队使用的设置。理想情况下,我在代码中对角度,距离,不透明度等有类似的控制:

如何使用PHP为图像添加阴影?

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.

我可以完全访问基于debian-linus的服务器,因此任何GD或ImageMagick解决方案都可以使用。和任何FOSS linux软件解决方案一样,虽然我更喜欢使用IM或GD的方式,因为它们已经安装并且不需要安装新软件。

The shadow must be able to be placed on a transparent, non-rectangular PNG!

阴影必须能够放在透明的非矩形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.

我问这个问题主要是因为我在网上找到的脚本和解决方案只产生矩形阴影,看起来像是整体便便,或者只是简单地根本不起作用。

6 个解决方案

#1


6  

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.

如果不构建完整的边缘检测器算法和显着的处理开销,您将无法在PHP中执行此操作。考虑使用GIMP和一些脚本fu,让它为你做艰苦的工作。

#2


19  

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.

只是为了它的地狱(我知道它得到了回答和接受):几个月前,为了回应有关图形设计stackexchange的问题,关于从源文件丢失的PNG中恢复掩码,我打了一些使用PHP的东西GD用于从透明PNG中提取alpha通道。正如乔在上面提到的评论中,您可以使用Alpha通道作为投影,仅将其偏移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);

?>

#3


9  

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

实际上这可以通过图像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);
?>

you can play a little with the shadow parameter.

你可以用shadow参数玩一点。

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

如何使用PHP为图像添加阴影?

#4


6  

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:

我使用了Marc B的建议,并呼吁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;
}

#5


3  

You can use PHPs GD Image Processing Libraries

您可以使用PHP GD图像处理库

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.

这是一个关于如何添加阴影效果的教程。但是,如果这不符合您的需求,我肯定谷歌搜索“PHP GD投影”将成功。

#6


2  

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

这个答案不提供Python解决方案,但它确实提供了所需的通用算法。

  • Taking images from an outstanding question about drop-shadows that i have, we start with an image:

    从一个关于我有的阴影的突出问题拍摄图像,我们从图像开始:

    如何使用PHP为图像添加阴影?

  • convert the image to black and white:

    将图像转换为黑白图像:

    如何使用PHP为图像添加阴影?

  • apply a gaussian blur, and offset the image as desired:

    应用高斯模糊,并根据需要偏移图像:

    如何使用PHP为图像添加阴影?

  • finally overlay the original image:

    最后覆盖原始图像:

    如何使用PHP为图像添加阴影?

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

我不知道Python,或任何有关它的东西,但可能这个算法可以帮助你,或者其他人绊倒这个问题。

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

注意:严格来说这应该是一个评论,但我真的希望能够显示图像。

#1


6  

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.

如果不构建完整的边缘检测器算法和显着的处理开销,您将无法在PHP中执行此操作。考虑使用GIMP和一些脚本fu,让它为你做艰苦的工作。

#2


19  

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.

只是为了它的地狱(我知道它得到了回答和接受):几个月前,为了回应有关图形设计stackexchange的问题,关于从源文件丢失的PNG中恢复掩码,我打了一些使用PHP的东西GD用于从透明PNG中提取alpha通道。正如乔在上面提到的评论中,您可以使用Alpha通道作为投影,仅将其偏移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);

?>

#3


9  

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

实际上这可以通过图像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);
?>

you can play a little with the shadow parameter.

你可以用shadow参数玩一点。

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

如何使用PHP为图像添加阴影?

#4


6  

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:

我使用了Marc B的建议,并呼吁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;
}

#5


3  

You can use PHPs GD Image Processing Libraries

您可以使用PHP GD图像处理库

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.

这是一个关于如何添加阴影效果的教程。但是,如果这不符合您的需求,我肯定谷歌搜索“PHP GD投影”将成功。

#6


2  

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

这个答案不提供Python解决方案,但它确实提供了所需的通用算法。

  • Taking images from an outstanding question about drop-shadows that i have, we start with an image:

    从一个关于我有的阴影的突出问题拍摄图像,我们从图像开始:

    如何使用PHP为图像添加阴影?

  • convert the image to black and white:

    将图像转换为黑白图像:

    如何使用PHP为图像添加阴影?

  • apply a gaussian blur, and offset the image as desired:

    应用高斯模糊,并根据需要偏移图像:

    如何使用PHP为图像添加阴影?

  • finally overlay the original image:

    最后覆盖原始图像:

    如何使用PHP为图像添加阴影?

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

我不知道Python,或任何有关它的东西,但可能这个算法可以帮助你,或者其他人绊倒这个问题。

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

注意:严格来说这应该是一个评论,但我真的希望能够显示图像。