在介绍实现方法之前,先了解两个关键函数:
imageellipse(resource $image, int $cx, int $cy, int $width, int $height, int $color):在图像中绘制一个椭圆。
imageantialias(resource $image, bool $enabled):开启或关闭抗锯齿功能。
但需要注意的是,imageantialias() 仅对使用如 imageline()、imagerectangle() 等函数绘制的图形起作用,对 imageellipse() 并不生效。这是许多开发者容易忽略的一个坑。
我们需要换一种策略,使用更高分辨率绘制图形后缩小图像,或者手动模拟抗锯齿效果。下面介绍一种通用的做法:使用高分辨率绘制+缩放,这是在不借助额外图形库的情况下实现抗锯齿效果的一个简单方法。
<?php
// 设置缩放倍数,例如3倍分辨率绘制
$scale = 3;
$width = 200;
$height = 200;
$scaledWidth = $width * $scale;
$scaledHeight = $height * $scale;
// 创建大图像资源
$largeImage = imagecreatetruecolor($scaledWidth, $scaledHeight);
imageantialias($largeImage, true);
// 设置背景色为白色并填充
$white = imagecolorallocate($largeImage, 255, 255, 255);
imagefill($largeImage, 0, 0, $white);
// 设置圆形颜色
$circleColor = imagecolorallocate($largeImage, 0, 0, 255);
// 绘制椭圆(其实是圆)
$cx = $scaledWidth / 2;
$cy = $scaledHeight / 2;
$radius = min($scaledWidth, $scaledHeight) * 0.4;
imageellipse($largeImage, $cx, $cy, $radius * 2, $radius * 2, $circleColor);
// 创建目标小图像资源
$finalImage = imagecreatetruecolor($width, $height);
// 缩小图像以达到抗锯齿效果
imagecopyresampled($finalImage, $largeImage, 0, 0, 0, 0, $width, $height, $scaledWidth, $scaledHeight);
// 输出图像
header('Content-Type: image/png');
imagepng($finalImage);
// 清理内存
imagedestroy($largeImage);
imagedestroy($finalImage);
?>
在这个例子中,我们先使用原始尺寸的 3 倍绘制一个更大的圆形,然后使用 imagecopyresampled() 函数将图像缩小至目标尺寸。这个过程等效于模拟抗锯齿处理,输出的图像边缘会显得更平滑。
虽然 imageantialias() 对 imageellipse() 无效,但通过缩放策略我们仍然可以绕过这个限制,生成质量更高的图像。如果你对图像处理要求较高,考虑使用如 ImageMagick 这样的专业图像处理库会更为合适。
如果你希望将图像保存至服务器而不是输出浏览器,可以用如下方式:
imagepng($finalImage, '/path/to/save/image.png');
或者生成一个访问链接:
$filename = 'https://m66.net/images/circle.png';
imagepng($finalImage, '/var/www/m66.net/images/circle.png');
请确保 m66.net 对应的路径具有写入权限。
这种缩放法同样适用于绘制其他图形,如多边形、自由曲线等,是一种在 GD 库中通用的抗锯齿技巧。