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

在程序项目开发的过程中我们免不了要实现一种功能。例如海报的生成,照片和文字合成一张新的图片。php中怎么实现

实现功能

文字和照片合成一张新的照片,并且自适应换行并加上签名和日期,加上字体样式,下面我们就开实现该功能

实现步骤简述

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

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

3.处理文字换行:计算每行文字的宽度,以适应图片宽度进行换行处理。

在图片上绘制文字:使用imagettftext函数逐行绘制文字到图片上。

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

php 复制代码
// 引入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)。

根据实际情况调整文字位置、颜色、大小等参数。

如果文字内容动态变化且长度未知,可能需要更复杂的逻辑来处理文字换行,确保文字不会超出图片边界。

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

php 复制代码
// ... 上述代码保持不变 ...

// 文字位置起始点(左上角)
$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);

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

php 复制代码
// ... 上述代码保持不变 ...

// 加载签名图片
$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);

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

相关推荐
tangliang_cn17 分钟前
java入门 自定义springboot starter
java·开发语言·spring boot
程序猿阿伟18 分钟前
《智能指针频繁创建销毁:程序性能的“隐形杀手”》
java·开发语言·前端
找藉口是失败者的习惯25 分钟前
从传统到未来:Android XML布局 与 Jetpack Compose的全面对比
android·xml
新知图书29 分钟前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
威威猫的栗子31 分钟前
Python Turtle召唤童年:喜羊羊与灰太狼之懒羊羊绘画
开发语言·python
力透键背31 分钟前
display: none和visibility: hidden的区别
开发语言·前端·javascript
bluefox197932 分钟前
使用 Oracle.DataAccess.Client 驱动 和 OleDB 调用Oracle 函数的区别
开发语言·c#
ö Constancy1 小时前
c++ 笔记
开发语言·c++
墨染风华不染尘1 小时前
python之开发笔记
开发语言·笔记·python
徐霞客3201 小时前
Qt入门1——认识Qt的几个常用头文件和常用函数
开发语言·c++·笔记·qt