php gd image png водяные знаки в jpg файле дают странный результат

Попытка добавить прозрачный водяной знак PNG к изображениям jpg дает мне другие результаты, если я на локальном или производственном сервере.

Вот результаты …

На моем локальном хосте (версия PHP 5.6.24)
введите описание изображения здесь

На рабочем сервере (версия PHP 5.5.9-1ubuntu4.21)
введите описание изображения здесь

Я даже не знаю, как назвать эту проблему: синий цвет становится розовым, а логотип неправильно отображается …

Код такой:

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

И это GD-раздел phpinfo для локального и производственного сервера
введите описание изображения здесь

Что мне не хватает? это сводит меня с ума!

4

Решение

Эти проблемы почти всегда возражают против того, что альфа-канал либо источника, либо места назначения не сохраняется, или вывод не имеет истинного цвета.

Попробуйте использовать imagesavealpha() функция и поиск "alpha" в комментариях к документации PHP, потому что есть много людей, имеющих решения для похожих проблем.

Этот комментарий может быть полезен, и это то, что сказал Эско:

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

В основном это копирует изображение в буфер, используя imagecreatetruecolor(),

3

Другие решения

У меня та же проблема. Функция imageScale в Ubuntu, кажется, превращает зеленый и синий в розовый. Решением может быть использование imagecopyresampled и imagecreatetruecolor. Однако это решение намного медленнее.

-1

По вопросам рекламы [email protected]