Я новичок в php, и я не смог найти исправление, как сделать закругленные углы для динамического изображения или добавить текст, отображающий IP-адрес в центре изображения.
<?php
// Create the image
$image = imagecreatetruecolor(333, 33);
// Allocate colors for the image
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
// Fill the image with white
imagefill($image, 0, 0, $white);
// Calculate the center position of the image
$image_width = imagesx($image);
$image_height = imagesy($image);
// Get the client's IP address
// Use the IP Geolocation API to get the country of the IP address
// Decode the JSON response
// Get the country code and name from the response
// Get the flag image file
$flag_file = "images/flags/$country_code.png";
// Load the flag image
$flag_image = imagecreatefrompng($flag_file);
// Set the font size
if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
$font_size = 15;
} elseif (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$font_size = 7;
}
$font_file = '/css/SatrevaNeue-lgJ6V.ttf';
// Add a border radius to the image
$radius = 10;
// Draw the four ellipses to the corners of the image
imagefilledellipse($image, $radius, $radius, $radius * 2, $radius * 2, $white);
imagefilledellipse($image, 333 - $radius, $radius, $radius * 2, $radius * 2, $white);
imagefilledellipse($image, $radius, 33 - $radius, $radius * 2, $radius * 2, $white);
imagefilledellipse($image, 333 - $radius, 33 - $radius, $radius * 2, $radius * 2, $white);
// Calculate the center position of the image
$text = "Your IP is $ip";
$text_box_width = imagefontwidth($font_size) * strlen($text);
$text_box_height = imagefontheight($font_size);
$x = ($image_width / 2) - ($text_box_width / 2);
$y = ($image_height / 2) - ($text_box_height / 2);
// Add the IP address to the image
imagettftext($image, $font_size, 0, $x, $y, $black, $font_file, $text);
// Calculate the position of the flag image
$flag_width = 20;
$flag_height = 20;
$flag_x = $x + $text_box_width + 10; // Add some spacing between the text and the flag image
$flag_y = ($image_height / 2) - ($flag_height / 2);
// Get the width and height of the flag image
$src_w = imagesx($flag_image);
$src_h = imagesy($flag_image);
// Resize and copy the flag image onto the canvas
imagecopyresampled($image, $flag_image, $flag_x, $flag_y, 0, 0, $flag_width, $flag_height, $src_w, $src_h);
// Set the content type header so the image is displayed properly
header('Content-Type: image/png');
// Output the image
imagepng($image);
// Free up memory
imagedestroy($image);
Я попытался нарисовать многоугольники, чтобы вырезать углы imagefilledpolygon(), но тот же результат вот изображение, которое он генерирует:






Несколько проблем, на которые следует обратить внимание в предоставленном вами сценарии:
filter_var не пройдёт проверку в обоих случаях, вы попытаетесь добавить текст к изображению без установленного размера шрифта. Вы должны переместить свой IP-адрес и логику страны наверх и убедиться, что они установлены правильно, прежде чем приступить к созданию изображения.imagefilledellipse добавляет круги только к углам, вам понадобится пара imagefilledrectangle, чтобы заполнить промежутки между этими углами.Чтобы ваш текст был правильно центрирован по вертикали, используйте метод imagettfbbox для определения размера ограничивающей рамки, а не полагайтесь на размер шрифта внутри нее. Это важно, поскольку ограничительная рамка обычно выше шрифта и обеспечивает более точное вертикальное выравнивание. Измените следующий код:
$text = "Your IP is $ip";
$text_box_width = imagefontwidth($font_size) * strlen($text);
$text_box_height = imagefontheight($font_size);
$x = ($image_width / 2) - ($text_box_width / 2);
$y = ($image_height / 2) - ($text_box_height / 2);
вместо этого:
// $text = "Your IP is ".($_SERVER['REMOTE_ADDR'] ?? 'localhost');
$text = "Your IP is $ip";
$bbox = imagettfbbox($font_size, 0, $font_file, $text);
$x = ($image_width / 2) - (($bbox[2] - $bbox[0]) / 2);
$y = ($image_height / 2) - (($bbox[7] - $bbox[1]) / 2);
Обратите внимание, что изображение, вероятно, должно быть шире, или текст должен быть разделен на две строки, так как любой сгенерированный здесь IPv6-адрес будет слишком маленьким, чтобы его можно было легко прочитать.
Вышеприведенное производит для меня следующее:
Со скругленными углами немного сложнее, сначала нужно отключить альфа-смешивание, а затем залить изображение прозрачным цветом:
Примечание. Не забудьте снова включить альфа-смешивание, иначе ваш текст будет не очень читабельным, когда вы захотите его добавить.
// Allocate colors
$black = imagecolorallocate($image, 0, 0, 0);
$white = imagecolorallocate($image, 255, 255, 255);
$transparency = imagecolorallocatealpha($image, 0, 0, 0, 127); // 127 indicates "completely transparent"
// Transparent Background
imagealphablending($image, false);
imagefill($image, 0, 0, $transparency);
imagesavealpha($image, true);
imagealphablending($image, true); // turn blending back on otherwise text will be ugly
// Create 4 circles in each corner, emulating our rounded corners
imagefilledellipse($image, 10, 10, 20, 20, $white);
imagefilledellipse($image, 323, 10, 20, 20, $white);
imagefilledellipse($image, 10, 23, 20, 20, $white);
imagefilledellipse($image, 323, 23, 20, 20, $white);
// Connect the circles with a couple of rectangles
imagefilledrectangle($image, 10, 0, 323, 33, $white);
imagefilledrectangle($image, 0, 10, 333, 23, $white);
// add your text etc...
Если вы не используете прямоугольники для заполнения промежутков между кругами, расположенными в углу, результат будет выглядеть так:
Однако с прямоугольниками все хорошо сочетается, и результат выглядит так:
Дополнительный совет: при работе с пикселями я обычно стараюсь не использовать четные числа в качестве диаметра закругленных углов, поскольку в четных числах нет идеального центра...
Например, в числе 10 ... центральные числа - это 4, 5 и 6. Однако в числе 11 центральное число - это просто 6)
Я создал этот GIF, чтобы проиллюстрировать, что именно здесь происходит:
ваши решения сработали для меня - очень признателен