You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP实现文本转图片:按双空行分割文本并适配500×500区块

Hey,我来帮你搞定这两个问题,刚好之前处理过类似的场景,给你一步步拆解解决方案:

解决文本分割与转图片的两个核心需求

一、正确按双空行分割文本

你当前用#\n\n#无法匹配双空行,主要是没考虑不同系统的换行符差异(Windows是\r\n,Linux/macOS是\n),而且直接硬写换行符不够鲁棒。推荐用PHP正则里的\R来匹配任意换行序列,再配合数量限定符,就能完美解决:

// 匹配任意类型的双换行(包括\r\n\r\n、\n\n、\r\r),同时过滤空元素
$textBlocks = preg_split('/\R{2,}/', file_get_contents($file['tmp_name']), -1, PREG_SPLIT_NO_EMPTY);

解释下关键参数:

  • \R:自动匹配所有换行格式(\n、\r\n、\r),不用自己写一堆分支
  • {2,}:匹配至少2个连续换行,能处理不小心多敲的空行
  • PREG_SPLIT_NO_EMPTY:自动过滤分割后为空的块,避免后续处理无效内容

如果你的场景是严格的双空行(中间没有空格),也可以用'/(\r\n){2,}|\n{2,}|\r{2,}/',但\R{2,}更简洁通用。

二、将文本块转为500×500图片(自动换行不溢出)

这里用PHP自带的GD库就能实现,不用额外装扩展,下面是完整的可复用代码:

1. 先写个自动换行的辅助函数

这个函数会根据画布宽度和字体大小,把长文本拆成多行,避免溢出:

function wrapText($fontPath, $text, $maxWidth, $fontSize) {
    $words = preg_split('/\s+/', $text);
    $lines = [];
    $currentLine = '';

    foreach ($words as $word) {
        $testLine = $currentLine . ($currentLine ? ' ' : '') . $word;
        // 计算当前测试行的宽度
        $bbox = imagettfbbox($fontSize, 0, $fontPath, $testLine);
        $lineWidth = $bbox[2] - $bbox[0];

        if ($lineWidth > $maxWidth && $currentLine !== '') {
            $lines[] = $currentLine;
            $currentLine = $word;
        } else {
            $currentLine = $testLine;
        }
    }

    if ($currentLine !== '') {
        $lines[] = $currentLine;
    }

    return $lines;
}

2. 核心的图片生成函数

把文本块渲染成500×500的图片,还做了垂直居中,看起来更美观:

function textToImage($text, $savePath, $fontPath, $imageSize = 500) {
    // 创建500×500的画布
    $image = imagecreatetruecolor($imageSize, $imageSize);
    // 设置背景色(白色)
    $bgColor = imagecolorallocate($image, 255, 255, 255);
    imagefill($image, 0, 0, $bgColor);
    // 设置文本颜色(黑色)
    $textColor = imagecolorallocate($image, 0, 0, 0);

    $fontSize = 16; // 字体大小,可根据需求调整
    $padding = 20; // 左右内边距,避免文本贴边
    $maxTextWidth = $imageSize - $padding * 2;

    // 调用自动换行函数拆分文本
    $lines = wrapText($fontPath, trim($text), $maxTextWidth, $fontSize);

    // 计算文本总高度,实现垂直居中
    $lineHeight = $fontSize * 1.5; // 行间距设为字体的1.5倍,更易读
    $totalTextHeight = count($lines) * $lineHeight;
    $startY = ($imageSize - $totalTextHeight) / 2;

    // 逐行绘制文本
    foreach ($lines as $index => $line) {
        $y = $startY + $index * $lineHeight;
        // 水平居中计算X坐标
        $bbox = imagettfbbox($fontSize, 0, $fontPath, $line);
        $lineWidth = $bbox[2] - $bbox[0];
        $x = ($imageSize - $lineWidth) / 2;

        imagettftext($image, $fontSize, 0, $x, $y, $textColor, $fontPath, $line);
    }

    // 保存为PNG图片(也可以用imagejpeg生成JPG)
    $success = imagepng($image, $savePath);
    // 释放内存资源
    imagedestroy($image);

    return $success;
}

3. 结合你的文件上传代码整合使用

把上面的函数和你现有的文件处理逻辑结合起来,完整流程如下:

$img = $_FILES['img'];

function reArrayFiles($file) {
    $file_ary = array();
    $file_count = count($file['name']);
    $file_key = array_keys($file);
    for($i=0;$i<$file_count;$i++) {
        foreach($file_key as $val) {
            $file_ary[$i][$val] = $file[$val][$i];
        }
    }
    return $file_ary;
}

$img_desc = reArrayFiles($img);

// 配置项,根据你的服务器路径调整
$fontPath = './fonts/msyh.ttf'; // 替换为你的字体文件路径(处理中文必须用中文字体)
$saveDir = './generated_text_images/'; // 图片保存目录,确保有写入权限

// 创建保存目录(如果不存在)
if (!is_dir($saveDir)) {
    mkdir($saveDir, 0755, true);
}

// 遍历处理每个上传的文件
foreach ($img_desc as $file) {
    // 只处理text/plain类型且上传成功的文件
    if ($file['type'] === 'text/plain' && $file['error'] === UPLOAD_ERR_OK) {
        $originalText = file_get_contents($file['tmp_name']);

        // 1. 按双空行分割文本
        $textBlocks = preg_split('/\R{2,}/', $originalText, -1, PREG_SPLIT_NO_EMPTY);

        // 2. 每个文本块生成一张图片
        foreach ($textBlocks as $blockIndex => $block) {
            $cleanBlock = trim($block);
            if (empty($cleanBlock)) continue; // 跳过空内容

            // 生成唯一文件名,避免重复
            $fileName = uniqid('text_block_') . "_" . ($blockIndex + 1) . ".png";
            $savePath = $saveDir . $fileName;

            // 生成图片
            if (textToImage($cleanBlock, $savePath, $fontPath)) {
                echo "图片生成成功:{$savePath}<br>";
            } else {
                echo "图片生成失败,请检查权限和字体路径<br>";
            }
        }
    }
}

几个重要的注意事项

  1. GD库启用:确保你的PHP环境已经启用GD库,可以通过phpinfo()查看GD模块状态
  2. 字体文件:如果需要处理中文,必须使用支持中文的字体(比如微软雅黑、思源黑体),并确保字体路径正确
  3. 目录权限:$saveDir所在的目录需要给PHP进程写入权限(通常设置为0755)
  4. 超长文本处理:如果某个文本块内容太多,换行后总高度超过500,可以在textToImage函数里添加逻辑,比如自动缩小字体大小,或者限制最大行数

内容的提问来源于stack exchange,提问作者Алексей Котов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:38:52