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

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

相关推荐
feiyangqingyun19 分钟前
Qt项目作品在苹果macos上编译运行效果/视频监控系统/物联网平台等
开发语言·qt·macos
你不是我我1 小时前
【Java 开发日记】我们来说一说 Redisson 的原理
java·开发语言
kk”1 小时前
C++ stack 和 queue
开发语言·c++
Matlab仿真实验室1 小时前
基于Matlab实现双目图计算深度图
开发语言·数码相机·matlab·双目图计算深度图
QT 小鲜肉1 小时前
【数据结构与算法基础】05. 栈详解(C++ 实战)
开发语言·数据结构·c++·笔记·学习·算法·学习方法
老K的Java兵器库2 小时前
Collections 工具类 15 个常用方法源码:sort、binarySearch、reverse、shuffle、unmodifiableXxx
java·开发语言·哈希算法
武子康2 小时前
Java-153 深入浅出 MongoDB 全面的适用场景分析与选型指南 场景应用指南
java·开发语言·数据库·mongodb·性能优化·系统架构·nosql
怪兽20142 小时前
请谈谈什么是同步屏障?
android·面试
rit84324992 小时前
ES6 箭头函数:告别 `this` 的困扰
开发语言·javascript·es6
嵌入式-老费2 小时前
Easyx图形库应用(用lua开发图形界面)
开发语言·lua