我正在尝试在php手册中实现用户提供的示例代码,但其行为与预期不符

时间:2019-07-01 17:49:08

标签: php image-processing mirroring

我正在尝试在PHP手册的这一页上实现killing_wombles0000(8年前)提供的代码:https://www.php.net/manual/en/function.imagecopymerge.php 问题是代码中是否有错误/意外行为(例如,$ a未定义) 有点工作,但是镜像的图像会淡化为白色,而我希望它会淡化为黑色。当我做出我认为是需要的更改时,我无法按自己的意愿去做。 我的代码中有太多图像功能,我无法理解它们是如何协同工作的。

我整天都在阅读每个功能,试图通过代码进行逻辑性的工作,注释掉部分,更改透明颜色以及通常紧抓稻草。 我以为将255,255,255更改为0,0,0都会使镜像图像变黑。我真是天真;)

这是用户在PHP手册的该页面上提供的代码:

$in = imagecreatefromjpeg('C:\test.jpg');
$reflection_strength = 120;        //    starting transparency (0-127, 0 being opaque)
$reflection_height = 40;        //     height of reflection in pixels
$gap = 10;                        //    gap between image and reflection

$orig_height = imagesy($in);                                //    store height of original image
$orig_width = imagesx($in);                                    //    store height of original image
$output_height = $orig_height + $reflection_height + $gap;    //    calculate height of output image

// create new image to use for output. fill with transparency. ALPHA BLENDING MUST BE FALSE
$out = imagecreatetruecolor($orig_width, $output_height);
imagealphablending($out, false);
$bg = imagecolortransparent($out, imagecolorallocatealpha($out, 255, 255, 255, 127));
imagefill($out, 0, 0, $bg);
imagefilledrectangle($out, 0, 0, imagesx($in), imagesy($in), $bg1);

// copy original image onto new one, leaving space underneath for reflection and 'gap'
imagecopyresampled ( $out , $in , 0, 0, 0, 0, imagesx($in), imagesy($in), imagesx($in), imagesy($in));

 // create new single-line image to act as buffer while applying transparency
$reflection_section = imagecreatetruecolor(imagesx($in), 1);
imagealphablending($reflection_section, false);
$bg1 = imagecolortransparent($reflection_section, imagecolorallocatealpha($reflection_section, 255, 255, 255, 127));
imagefill($reflection_section, 0, 0, $bg1);

// 1. copy each line individually, starting at the 'bottom' of the image, working upwards.
// 2. set transparency to vary between reflection_strength and 127
// 3. copy line back to mirrored position in original
for ($y = 0; $y<$reflection_height;$y++)
{   
    $t = ((127-$reflection_strength) + ($reflection_strength*($y/$reflection_height)));
    imagecopy($reflection_section, $out, 0, 0, 0, imagesy($in)  - $y, imagesx($in), 1);
    imagefilter($reflection_section, IMG_FILTER_COLORIZE, 0, 0, 0, $t);
    imagecopyresized($out, $reflection_section, $a, imagesy($in) + $y + $gap, 0, 0, imagesx($in) - (2*$a), 1, imagesx($in), 1);
}

// output image to view
header('Content-type: image/png');
imagesavealpha($out,true);
imagepng($out);

在循环进入之前将$ a设置为0可消除错误。

1 个答案:

答案 0 :(得分:1)

您发现的代码中似乎存在一些错误。

    没有为主输出图像定义
  1. $bg1。我在$bg1中将$bg更改为imagefilledrectangle
  2. 未定义
  3. $a。我将对$a的引用更改为零,因为它引用了“ x”坐标,并且我们希望图像的整个宽度都从零到其整个宽度。

反射部分逐渐消失为透明的。由于页面的颜色是白色,因此图像看起来像是褪色为白色。如果要淡化为黑色而不是透明,我建议保留默认的混合模式,以使背景色发光并设置为黑色:

//imagealphablending($out, false);
//$bg = imagecolortransparent($out, imagecolorallocatealpha($out, 255, 255, 255, 127));
$bg = imagecolorallocatealpha($out, 0,0,0,0);

有关参考,请参见imagealphablending

这是一个例子:

$in = imagecreatefromjpeg('https://picsum.photos/id/1084/536/354?grayscale');
$reflection_strength = 127;        //    starting transparency (0-127, 0 being opaque)
$reflection_height = 40;        //     height of reflection in pixels
$gap = 0;                        //    gap between image and reflection

$orig_height = imagesy($in);                                //    store height of original image
$orig_width = imagesx($in);                                    //    store height of original image
$output_height = $orig_height + $reflection_height + $gap;    //    calculate height of output image

// create new image to use for output. fill with BLACK.
$out = imagecreatetruecolor($orig_width, $output_height);
//imagealphablending($out, false);
//$bg = imagecolortransparent($out, imagecolorallocatealpha($out, 255, 255, 255, 127));
$bg = imagecolorallocatealpha($out, 0,0,0,0);
imagefill($out, 0, 0, $bg);
imagefilledrectangle($out, 0, 0, imagesx($in), imagesy($in), $bg);

// copy original image onto new one, leaving space underneath for reflection and 'gap'
imagecopyresampled ( $out , $in , 0, 0, 0, 0, imagesx($in), imagesy($in), imagesx($in), imagesy($in));

 // create new single-line image to act as buffer while applying transparency
$reflection_section = imagecreatetruecolor(imagesx($in), 1);
imagealphablending($reflection_section, false);
$bg1 = imagecolortransparent($reflection_section, imagecolorallocatealpha($reflection_section, 255, 255, 255, 127));
imagefill($reflection_section, 0, 0, $bg1);

// 1. copy each line individually, starting at the 'bottom' of the image, working upwards.
// 2. set transparency to vary between reflection_strength and 127
// 3. copy line back to mirrored position in original
for ($y = 0; $y<$reflection_height;$y++)
{
    $t = ((127-$reflection_strength) + ($reflection_strength*($y/$reflection_height)));
    imagecopy($reflection_section, $out, 0, 0, 0, imagesy($in)  - $y, imagesx($in), 1);
    imagefilter($reflection_section, IMG_FILTER_COLORIZE, 0, 0, 0, $t);
    imagecopyresized($out, $reflection_section, 0, imagesy($in) + $y + $gap, 0, 0, imagesx($in) - 0, 1, imagesx($in), 1);
}

// output image to view
header('Content-type: image/png');
imagesavealpha($out,true);
imagepng($out);

Run on PHPFiddle