PHP利用GD库实现图片合成功能方法

发布于:2024-07-08 ⋅ 阅读:(38) ⋅ 点赞:(0)

在程序项目开发的过程中我们免不了要实现一种功能。例如海报的生成,照片和文字合成一张新的图片。php中怎么实现
实现功能
文字和照片合成一张新的照片,并且自适应换行并加上签名和日期,加上字体样式,下面我们就开实现该功能

实现步骤简述
1.加载原始图片:使用imagecreatefromjpeg, imagecreatefrompng, 或 imagecreatefromgif等函数根据图片类型加载图片。

2.设置字体颜色、大小和样式:通过imagecolorallocate分配颜色,使用GD的内置字体或自定义字体。

3.处理文字换行:计算每行文字的宽度,以适应图片宽度进行换行处理。
在图片上绘制文字:使用imagettftext函数逐行绘制文字到图片上。

4.输出或保存合成图片:使用header设置正确的MIME类型后直接输出,或用imagejpeg, imagepng, imagegif等函数保存到文件。

// 引入GD库
if (!function_exists('imagettftext')) {
    die('GD库未安装或不支持TrueType文本');
}

// 图片路径
$imagePath = './example.jpg';
// 输出图片路径(如果需要保存)
$outputPath = './output.jpg';

// 加载图片
$im = imagecreatefromjpeg($imagePath);
list($width, $height) = getimagesize($imagePath);

// 设置文字参数
$text = "这是一段示例文字\n它包含换行\n第三行文字";
$fontColor = imagecolorallocate($im, 255, 255, 255); // 白色
$fontSize = 20;
$fontFile = './simhei.ttf'; // 确保字体文件存在

// 文字位置起始点(左上角)
$x = 10;
$y = 50;

// 处理换行
$lines = explode("\n", $text);
foreach ($lines as $line) {
    // 计算当前行的文字高度,用于垂直定位下一行
    $textBox = imagettfbbox($fontSize, 0, $fontFile, $line);
    $textWidth = max(array($textBox[2], $textBox[4])); // 获取最大宽度
    $textHeight = abs($textBox[7] - $textBox[1]); // 获取高度
    
    // 如果文字超出图片宽度,则调整字体大小或换行逻辑
    if ($textWidth > $width - 20) {
        echo "警告: 文字宽度超过图片宽度,请调整字体大小或文字内容。";
        break;
    }
    
    // 绘制文字
    imagettftext($im, $fontSize, 0, $x, $y, $fontColor, $fontFile, $line);
    $y += $textHeight + 10; // 移动到下一行
}

// 输出图片到浏览器
header('Content-Type: image/jpeg');
imagejpeg($im);

// 如果需要保存到文件
// imagejpeg($im, $outputPath);

// 释放内存
imagedestroy($im);

确保服务器已安装GD库并支持TrueType字体。
替换$fontFile变量为实际的字体文件路径,确保该字体支持中文(如simsun.ttc或simhei.ttf)。
根据实际情况调整文字位置、颜色、大小等参数。
如果文字内容动态变化且长度未知,可能需要更复杂的逻辑来处理文字换行,确保文字不会超出图片边界。

通过上述代码如果我们需要增加一个合成的内容区块那么就可以这样做例如我们要加入签名

// ... 上述代码保持不变 ...

// 文字位置起始点(左上角)
$x = 10;
$y = 50;

// 绘制主要文字内容
// ... 绘制文字的循环代码保持不变 ...

// 添加签名和时间到右下角
$signature = "签名: 作者";
$time = date("Y-m-d H:i:s"); // 获取当前时间格式化字符串
$combinedText = $signature . "\n" . $time;

// 计算签名和时间的文本框,以确定其大小
$textBox = imagettfbbox($fontSize, 0, $fontFile, $combinedText);
$textWidth = max(array($textBox[2], $textBox[4]));
$textHeight = abs($textBox[7] - $textBox[1]);

// 设置右下角的起始坐标
$x = $width - $textWidth - 10;
$y = $height - $textHeight - 10;

// 绘制签名和时间
imagettftext($im, $fontSize, 0, $x, $y, $fontColor, $fontFile, $combinedText);

// 输出图片到浏览器
header('Content-Type: image/jpeg');
imagejpeg($im);

// 保存图片到文件
imagejpeg($im, $outputPath);

echo "图片已成功保存至: " . $outputPath;

// 释放内存
imagedestroy($im);

比如我们要加入签名图片那么我们可以这么做

// ... 上述代码保持不变 ...

// 加载签名图片
$signatureImagePath = './signature.png';
$signatureIm = imagecreatefrompng($signatureImagePath);
$signatureWidth = imagesx($signatureIm);
$signatureHeight = imagesy($signatureIm);

// 计算签名图片的位置,确保在右下角
$x = $width - $signatureWidth - 10;
$y = $height - $signatureHeight - 10;

// 合并签名图片到主图片
imagecopy($im, $signatureIm, $x, $y, 0, 0, $signatureWidth, $signatureHeight);

// 销毁签名图片资源
imagedestroy($signatureIm);

// 绘制签名和时间到右下角
// ... 与之前示例中的签名和时间绘制代码保持不变 ...

// 输出图片到浏览器
header('Content-Type: image/jpeg');
imagejpeg($im);

// 保存图片到文件
imagejpeg($im, $outputPath);

echo "图片已成功保存至: " . $outputPath;

// 释放内存
imagedestroy($im);

整体就算完成了,剩下的自己研究,仅仅是一个方法,有很多可取代的方法,自行研究。学无止境。


网站公告

今日签到

点亮在社区的每一天
去签到