PHP生成占位图

参数说明:

1. w=300 – 图片宽度

  • 作用:设置生成图片的宽度
  • 单位:像素(px)
  • 范围:10-3000像素
  • 示例值300 表示生成300像素宽的图片
  • 默认值:如果省略此参数,默认300像素

2. h=200 – 图片高度

  • 作用:设置生成图片的高度
  • 单位:像素(px)
  • 范围:10-3000像素
  • 示例值200 表示生成200像素高的图片
  • 默认值:如果省略此参数,默认200像素

3. bg=CCC – 背景颜色

  • 作用:设置图片的背景颜色
  • 格式:十六进制颜色码(不带#号)
  • 支持格式
    • 3位简写:CCC 相当于 CCCCCC
    • 6位完整:CCCCCCFF0000
  • 示例值CCC 表示浅灰色背景(#CCCCCC)
  • 默认值:如果省略此参数,默认CCCCCC(浅灰色)
  • 其他示例
    • bg=FFF:白色背景
    • bg=000:黑色背景
    • bg=F00:红色背景
    • bg=336699:蓝色背景

4. cl=00FF00 – 文字颜色

  • 作用:设置图片上文字的颜色
  • 格式:十六进制颜色码(不带#号)
  • 支持格式
    • 3位简写:F00 相当于 FF0000
    • 6位完整:00FF00FFFFFF
  • 示例值00FF00 表示亮绿色文字
  • 默认值:如果省略此参数,默认66CCFF(天依蓝)
  • 其他示例
    • cl=FFF:白色文字
    • cl=000:黑色文字
    • cl=F0F:紫色文字

5. t=IMG – 显示的文字

  • 作用:设置在图片上显示的文字内容
  • 格式:URL编码的文本
  • 示例值IMG 表示显示”IMG”三个字母
  • 默认值:如果省略此参数,默认显示图片尺寸,如”300×200″
  • 支持中文:需要URL编码,如 t=%E4%B8%AD%E6%96%87 显示”中文”
  • 空格处理:使用+%20,如 t=Hello+World

6. s=20 – 文字大小

  • 作用:设置文字的字号大小
  • 单位:像素(px)
  • 范围:1-100像素(实际受图片尺寸限制)
  • 示例值20 表示20像素高的文字
  • 默认值:如果省略此参数,默认20像素
  • 智能调整
    • 如果指定大小超出图片范围,会自动缩小
    • 最小保证可读性为8像素
    • 最大不超过图片尺寸的一半

完整URL示例:

img.php?w=300&h=200&bg=CCC&cl=00FF00&t=IMG&s=20

代码:

<?php
// img.php - 动态生成占位图片
header('Content-Type: image/png');

// 获取参数并设置默认值
$width = isset($_GET['w']) ? intval($_GET['w']) : 300;
$height = isset($_GET['h']) ? intval($_GET['h']) : 200;
$bgColor = isset($_GET['bg']) ? $_GET['bg'] : '999999';
$textColor = isset($_GET['cl']) ? $_GET['cl'] : '66ccff';
$text = isset($_GET['t']) ? urldecode($_GET['t']) : "Image".$width . 'x' . $height;
$fontSizeUser = isset($_GET['s']) ? intval($_GET['s']) : 20; // 新增:用户指定的文字大小

// 验证尺寸范围(防止过大导致内存溢出)
$width = max(10, min($width, 3000));
$height = max(10, min($height, 3000));

// 验证字体大小范围
$fontSizeUser = max(1, min($fontSizeUser, 100)); // 限制在1-100像素之间

// 处理颜色值
function hexColorToRGB($hex) {
    // 移除可能存在的#号
    $hex = ltrim($hex, '#');
    
    // 处理缩写形式如 CCC
    if (strlen($hex) == 3) {
        $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
    }
    
    // 验证是否为有效的十六进制颜色
    if (!ctype_xdigit($hex) || strlen($hex) != 6) {
        return array(204, 204, 204); // 默认灰色
    }
    
    $r = hexdec(substr($hex, 0, 2));
    $g = hexdec(substr($hex, 2, 2));
    $b = hexdec(substr($hex, 4, 2));
    
    return array($r, $g, $b);
}

// 转换颜色
$bgRGB = hexColorToRGB($bgColor);
$textRGB = hexColorToRGB($textColor);

// 创建图片
$image = imagecreatetruecolor($width, $height);

// 分配颜色
$backgroundColor = imagecolorallocate($image, $bgRGB[0], $bgRGB[1], $bgRGB[2]);
$textImageColor = imagecolorallocate($image, $textRGB[0], $textRGB[1], $textRGB[2]);

// 填充背景
imagefill($image, 0, 0, $backgroundColor);

// 准备文本
if (empty(trim($text))) {
    $text = $width . 'x' . $height;
}

// 检查是否支持TTF字体
$useTTF = function_exists('imagettfbbox') && function_exists('imagettftext');

// 尝试查找字体文件(只在允许的目录内查找)
if ($useTTF) {
    $fontPath = null;
    
    // 在当前目录及其子目录中查找常见字体文件
    $fontFiles = array(
        'arial.ttf',
        'Arial.ttf',
        'DejaVuSans.ttf',
        'Roboto-Regular.ttf',
        'fonts/arial.ttf',
        'fonts/Arial.ttf',
        'fonts/DejaVuSans.ttf',
        'fonts/Roboto-Regular.ttf',
        'font/arial.ttf',
        'font/Arial.ttf',
    );
    
    // 检查当前目录和fonts子目录
    $baseDir = dirname(__FILE__);
    $checkedPaths = array($baseDir, $baseDir . '/fonts', $baseDir . '/font');
    
    foreach ($checkedPaths as $checkDir) {
        if (is_dir($checkDir)) {
            foreach ($fontFiles as $fontFile) {
                $fullPath = $checkDir . '/' . basename($fontFile);
                if (file_exists($fullPath) && is_readable($fullPath)) {
                    $fontPath = $fullPath;
                    break 2; // 找到字体文件,跳出两层循环
                }
            }
        }
    }
    
    // 如果找到了字体文件且图片尺寸适合,使用TTF字体
    if ($fontPath && $width >= 50 && $height >= 30) {
        // 设置最小和最大字体大小
        $minFontSize = 8;
        $maxFontSize = min($width, $height) / 2; // 最大字体为图片尺寸的一半
        
        // 如果用户指定了字体大小,则使用用户指定的大小(但限制在合理范围内)
        $fontSize = max($minFontSize, min($fontSizeUser, $maxFontSize));
        
        // 检查文本是否适合图片,如果不适合则缩小字体
        do {
            $bbox = imagettfbbox($fontSize, 0, $fontPath, $text);
            if ($bbox === false) {
                // 如果获取边界框失败,回退到内置字体
                $useTTF = false;
                break;
            }
            
            $textWidth = abs($bbox[2] - $bbox[0]);
            $textHeight = abs($bbox[1] - $bbox[7]);
            
            // 如果文本适合图片或者字体已经是最小值,则跳出循环
            if (($textWidth < $width * 0.9 && $textHeight < $height * 0.8) || $fontSize <= $minFontSize) {
                break;
            }
            $fontSize -= 1; // 缩小字体
        } while ($fontSize > $minFontSize);
        
        if ($useTTF) {
            // 计算居中位置
            $bbox = imagettfbbox($fontSize, 0, $fontPath, $text);
            $textWidth = abs($bbox[2] - $bbox[0]);
            $textHeight = abs($bbox[1] - $bbox[7]);
            
            // 计算文本起始位置(完美居中)
            $x = ($width - $textWidth) / 2;
            $y = ($height - $textHeight) / 2 + $textHeight - $bbox[1];
            
            // 添加文本
            imagettftext($image, $fontSize, 0, intval($x), intval($y), $textImageColor, $fontPath, $text);
            
            // 可选:添加边框
            $borderColor = imagecolorallocate($image, 100, 100, 100);
            imagerectangle($image, 0, 0, $width - 1, $height - 1, $borderColor);
            
            // 输出PNG图片
            imagepng($image);
            imagedestroy($image);
            exit;
        }
    }
}

// 如果未使用TTF字体,使用GD内置字体
// 使用GD内置字体(1-5,1最小,5最大)

// 将用户指定的像素大小转换为GD内置字体等级
// 内置字体等级与像素大小的对应关系:
// 等级1: 约8px, 等级2: 约13px, 等级3: 约13px, 等级4: 约15px, 等级5: 约16px
$fontLevels = array(
    1 => 8,
    2 => 13,
    3 => 13,
    4 => 15,
    5 => 16
);

// 根据用户指定的字体大小选择最接近的等级
$selectedLevel = 5; // 默认最大等级
$minDiff = PHP_INT_MAX;

foreach ($fontLevels as $level => $size) {
    $diff = abs($fontSizeUser - $size);
    if ($diff < $minDiff) {
        $minDiff = $diff;
        $selectedLevel = $level;
    }
}

// 如果用户指定了很小的字体,使用等级1
if ($fontSizeUser < 10) {
    $selectedLevel = 1;
}

$fontSize = $selectedLevel;

// 计算文本尺寸
$textWidth = imagefontwidth($fontSize) * strlen($text);
$textHeight = imagefontheight($fontSize);

// 如果文本太大,尝试较小的字体等级
while (($textWidth > $width * 0.9 || $textHeight > $height * 0.8) && $fontSize > 1) {
    $fontSize--;
    $textWidth = imagefontwidth($fontSize) * strlen($text);
    $textHeight = imagefontheight($fontSize);
}

// 计算居中位置(GD内置字体)
$x = ($width - $textWidth) / 2;
$y = ($height - $textHeight) / 2;

// 添加文本(使用内置字体)
imagestring($image, $fontSize, intval($x), intval($y), $text, $textImageColor);

// 可选:添加边框
$borderColor = imagecolorallocate($image, 100, 100, 100);
imagerectangle($image, 0, 0, $width - 1, $height - 1, $borderColor);

// 输出PNG图片
imagepng($image);
imagedestroy($image);
?>

发表评论

验证码