PHP GD图像PNG水印在JPG文件上产生奇怪结果

4
尝试将透明的PNG水印添加到JPG图像,无论我是在本地主机还是生产服务器上,结果都不同。
以下是结果...
在我的本地主机上(PHP版本5.6.24) enter image description here 在生产服务器上(PHP版本5.5.9-1ubuntu4.21) enter image description here 我甚至不知道如何称呼这个问题,蓝色变成了粉色,标志没有正确呈现...
代码如下:

function getBrightness($gdHandle) {
$width = imagesx($gdHandle);
$height = imagesy($gdHandle);

$totalBrightness = 0;

for ($x = 0; $x < $width; $x++) {
    for ($y = 0; $y < $height; $y++) {
        $rgb = imagecolorat($gdHandle, $x, $y);

        $red = ($rgb >> 16) & 0xFF;
        $green = ($rgb >> 8) & 0xFF;
        $blue = $rgb & 0xFF;

        $totalBrightness += (max($red, $green, $blue) + min($red, $green, $blue)) / 2;
    }
}

  //  imagedestroy($gdHandle);

return ($totalBrightness / ($width * $height)) / 2.55;
}

function render_text_on_gd_image(&$source_gd_image, $text, $font, $size, $color, $opacity, $rotation, $bpx, $bpy, $wnewx) {

$source_width = imagesx($source_gd_image);
$source_height = imagesy($source_gd_image);
$bb = imagettfbbox($size, $rotation, $font, $text);
$x0 = min($bb[0], $bb[2], $bb[4], $bb[6]);
$x1 = max($bb[0], $bb[2], $bb[4], $bb[6]);
$y0 = min($bb[1], $bb[3], $bb[5], $bb[7]);
$y1 = max($bb[1], $bb[3], $bb[5], $bb[7]);
$bb_width = abs($x1 - $x0);
$bb_height = abs($y1 - $y0);

$alpha_color = imagecolorallocatealpha(
    $source_gd_image,
    hexdec(substr($color, 0, 2)),
    hexdec(substr($color, 2, 2)),
    hexdec(substr($color, 4, 2)),
    127 * (100 - $opacity) / 100
);
return imagettftext($source_gd_image, $size, $rotation, $bpx + $wnewx/2 - $bb_width/2 , $bpy, $alpha_color, $font, $text);
}


$val = array();

//$val["displayName"] = "Administrador";
$val["displayName"] = "Afonso Ferreira Gomes";

$val["relFile"] = "imagem.jpg";

list($val["width_original"], $val["height_original"]) = getimagesize($val["relFile"]);

if ($val["width_original"] > $val["height_original"] && $val["width_original"] >= 1200) {

    $val["height_resized"] = $val["height_original"] * (1200/$val["width_original"]);
    $val["width_resized"]  = 1200;

}  elseif ($val["height_original"] > $val["width_original"] && $val["height_original"] >= 1200) {

    $val["height_resized"] = 1200;
    $val["width_resized"]  = (1200/$val["height_original"]) * $val["width_original"];

} else {

    $val["height_resized"] = $val["height_original"];
    $val["width_resized"]  = $val["width_original"];

}

$i = imagecreatefromjpeg($val["relFile"]);

$i = imagescale($i, $val["width_resized"], $val["height_resized"]);

$val["width_new"] = imagesx($i);

$val["height_new"] = imagesy($i);


if ($val["width_new"] < $val["height_new"]) {

    $val["portait"] = true;
    $val["smallest"] = $val["width_new"];

} else {

    $val["portait"] = false;
    $val["smallest"] = $val["height_new"];

}


/* GERAR WATERMARK LOGOTIPO */
$val["racio"] = 0.20;
$val["marLeft"] = 40;
$val["marBottom"] = 40;
$val["bright"] = getBrightness($i);


if ($val["bright"] < 30) {

    $val["opacidade"] = 20;

} else {

    $val["opacidade"] = 40;

}

$w = imagecreatefrompng("jbw_260_40.png");

if ($val["portait"]) {

    $val["water_width"] = $val["width_new"] * $val["racio"];
    $val["water_height"] = $val["width_new"] * $val["racio"];

} else {

    $val["water_width"] = $val["height_new"] * $val["racio"];
    $val["water_height"] = $val["height_new"] * $val["racio"];

}

$wnew = imagescale($w, $val["water_width"], $val["water_height"]);

$val["water_width"] = imagesx($wnew);
$val["water_height"] = imagesy($wnew);

/* GERAR WATERMARK TEXTO AUTOR */
if ($val["displayName"] == "Administrador") {
    $val["autor"] = "";
    $val["marBottom"] = 20;
    $val["marLeft"] = 20;
} else {
    $val["autor"] = $val["displayName"];
}


// PRIMEIRO E ULTIMO NOME SÓ!!
$autorNomes = explode(" ", $val["autor"]);

if (count($autorNomes) >= 2) {
    $val["autor"] = $autorNomes[0] . " " . $autorNomes[count($autorNomes) - 1];
} else {
    $val["autor"] = $autorNomes[0];
}

$font = "../font/Montserrat.ttf";
$color = "FFFFFF";

$flagSize = false;

$val["fontSize"] = 12;

for ($size = 7; $size <= 50; $size += 0.5) {

    $bb = imagettfbbox($size, 0, $font, $val["autor"]);
    $x0 = min($bb[0], $bb[2], $bb[4], $bb[6]);
    $x1 = max($bb[0], $bb[2], $bb[4], $bb[6]);
    $y0 = min($bb[1], $bb[3], $bb[5], $bb[7]);
    $y1 = max($bb[1], $bb[3], $bb[5], $bb[7]);

    $val["bbox_width"] = abs($x1 - $x0);
    $val["bbox_height"] = abs($y1 - $y0);

    if (($val["bbox_width"] >= $val["water_width"] && !$flagSize) || $size == 50) {
        $val["fontSize"] = $size;
        $flagSize = true;
        break;
    }
}

$val["posY_water"] = $val["height_new"] - $val["water_height"] - $val["marBottom"];
$val["posY_text"] = $val["height_new"] - $val["marBottom"] + $val["bbox_height"] - 5;

imagecopy($i, $wnew, $val["marLeft"],  $val["posY_water"] , 0, 0, $val["water_width"], $val["water_height"]);

render_text_on_gd_image($i, $val["autor"], $font, $val["fontSize"], $color, $val["opacidade"] ,0 , $val["marLeft"]  , $val["posY_text"], $val["water_width"]);


// echo "<pre>"; print_r($val); echo "</pre>"; die;

/* OUTPUT IMAGEM E LIMPA BUFFER */
header('Content-type: image/png');

imagepng($i);
imagedestroy($i);
imagedestroy($w);

And this are the gd section of phpinfo for localhost and production server enter image description here

What am I missing? this is driving me insane!


可能是libpng库版本的差异导致了问题?因为本地主机版本是9,而服务器版本是8。也许尝试更新一下? - Deathstorm
我不是专家,但我认为最有可能的情况是,我无法更改服务器上的php或libpng... - Afonso Gomes
2个回答

3
那些问题几乎总是涉及到源或目标的Alpha通道没有被保留,或者输出并不是真正的彩色。尝试使用imagesavealpha()函数,并在PHP文档的评论中搜索"alpha",因为有很多人提供了类似问题的解决方案。这条评论可能会有帮助,而且与Esko所说的有些相同。

http://php.net/manual/en/function.imagecreatefrompng.php#90364

基本上,它使用imagecreatetruecolor()将图像复制到缓冲区。

使用GD时,我不在我的海滩上,请耐心等待。 :) 所以你的意思是:不是打开jpeg并对其进行操作,而是使用imagetruecolor()创建一个新图像,然后将原始图像和水印传递给该图像,同时使用imagesavealpha()? - Afonso Gomes
@AfonsoGomes 是的,就像那样!在打开和保存过程中,图片的一些信息会丢失,并且库版本之间存在一些小差异。 - Daniel W.

-1

我也遇到了同样的问题。在Ubuntu的imageScale函数似乎会将绿色和蓝色转为粉色。解决方法可能是使用imagecopyresampled和imagecreatetruecolor。然而,这种解决方案速度要慢得多。


图片缩放问题对我来说似乎是一个不同的挑战!我也遇到了这个问题。如果你只提供宽度,它就无法正常工作...这就是为什么在我的代码中我传递了宽度和高度。不知道你的代码是怎样的,但这对我很有用。 - Afonso Gomes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接