PHP的GD库PNG透明底图片添加文字及图片水印
时间:2019-11-28 23:30:48|栏目:|点击: 次
这里我们来具体介绍一下,如何使用GD库 中的相关函数;
生成 PNG 透明底图像,并且在图像上添加文字及图像水印。
首先我们要生成一张透明底的画布:
// 创建 PNG透明底 画布 $canvas = imagecreatetruecolor('720', '480'); // 为一幅图像分配颜色和透明度 $background = imagecolorallocatealpha($canvas, 0, 0, 0, 127); // 区域填充背景颜色 imagefill($canvas, 0, 0, $background); // 将某个颜色定义为透明色 imagecolortransparent($canvas, $background);
画布生成了,下面就是对文字和LOGO图像进行处理了,
这里我们使用imagecreatefromstring从字符串中的图像流新建一LOGO图像;
然后使用imagecopyresampled将LOGO图像合并到画布上:
$logo = @file_get_contents($logo_url); // 将 logo 读取到字符串中 $logo_img = imagecreatefromstring($logo); // 从字符串中的图像流新建一图像 // 将logo合并到画布上 imagecopyresampled($canvas, $logo_img, 30, 115, 0, 0, 250, 250, imagesx($logo_img), imagesy($logo_img));
下面对文字的相关信息进行获取,字体基点的位置,以及字体的宽高,
使用imagettftext将字体添加到画布上,
(重要:这里图像在画布中的位置不是以字体的左下角为准,而是以字体的基点位置为准)
计算字体的相关信息:
/** * [text_image 获取字体相关属性] * @param [type] $size [像素单位的字体大小] * @param [type] $angle [text 将被度量的角度大小] * @param [type] $fontfile [TrueType 字体文件的文件名] * @param [type] $text [要度量的字符串] * @return [type] [description] */ public static function text_image($size, $angle=0, $fontfile, $text) { //获取文字信息 $info = imagettfbbox($size, $angle=0, $fontfile, $text); $minx = min($info[0], $info[2], $info[4], $info[6]); $maxx = max($info[0], $info[2], $info[4], $info[6]); $miny = min($info[1], $info[3], $info[5], $info[7]); $maxy = max($info[1], $info[3], $info[5], $info[7]); // var_dump($minx.' '.$maxx.' '.$miny.' '.$maxy); /* 计算文字初始坐标和尺寸 */ $x = $minx; $y = abs($miny); $w = $maxx - $minx; $h = $maxy - $miny; $re = array( 'x' => $x, // 基点 X 位置 'y' => $y, // 基点 Y 位置 'w' => $w, // 字体宽度 'h' => $h, // 字体高度 ); return $re; }将字体添加到画布上:
// 设置字体颜色(十六进制颜色码转换RGB颜色值与透明度) $color = self::color_16($text_color); $color = imagecolorallocatealpha($canvas, $color[0], $color[1], $color[2], $color[3]); // 计算文字文字在画布中的位置(以基点为准,文字在图像中的位置) $text_x = 30 + 250 + 30; $text_y = $text_info['y'] + (480-$text_info['h'])/2; // 图片添加字体 imagettftext($canvas, $text_size, 0, $text_x, $text_y, $color, $text_fonts, $text);
如何输出真正透明底的图像:
// (很重要)不合并颜色,直接用 PNG 图像颜色替换,包括透明色; imagealphablending($canvas, false); // (很重要)设置标记以在保存 PNG 图像时保存完整的 alpha 通道信息; imagesavealpha($canvas, true);
完整代码:
<?php /** * @Author: [FENG] <1161634940@qq.com> * @Date: 2019-07-16T22:26:38+08:00 * @Last Modified by: [FENG] <1161634940@qq.com> * @Last Modified time: 2019-07-16T23:03:51+08:00 */ Class Image { protected static $canvas = ''; public static function canvas_image() { // 创建 PNG透明底 画布 self::$canvas = imagecreatetruecolor('720', '480'); // 为一幅图像分配颜色和透明度 $background = imagecolorallocatealpha(self::$canvas, 0, 0, 0, 127); // 区域填充背景颜色 imagefill(self::$canvas, 0, 0, $background); // 将某个颜色定义为透明色 imagecolortransparent(self::$canvas, $background); $text = '代码驿站'; $text_fonts = './jianti.ttf'; $text_color = '#000000'; $text_size = 60; $logo_url = './logo.png'; // logo 路径 // 获取文字信息(基点位置及宽高) $text_info = self::text_image($text_size, $angle=0, $text_fonts, $text); $logo = @file_get_contents($logo_url); // 将 logo 读取到字符串中 $logo_img = imagecreatefromstring($logo); // 从字符串中的图像流新建一图像 // 将logo合并到画布上 imagecopyresampled(self::$canvas, $logo_img, 30, 115, 0, 0, 250, 250, imagesx($logo_img), imagesy($logo_img)); // 设置字体颜色(十六进制颜色码转换RGB颜色值与透明度) $color = self::color_16($text_color); $color = imagecolorallocatealpha(self::$canvas, $color[0], $color[1], $color[2], $color[3]); // 计算文字文字在画布中的位置(以基点为准,文字在图像中的位置) $text_x = 30 + 250 + 30; $text_y = $text_info['y'] + (480-$text_info['h'])/2; // 图片添加字体 imagettftext(self::$canvas, $text_size, 0, $text_x, $text_y, $color, $text_fonts, $text); //输出到浏览器上面并且告诉浏览器这个一个图像 header('content-type:image/png'); // 设置header头 imagealphablending(self::$canvas, false); // (很重要)不合并颜色,直接用 PNG 图像颜色替换,包括透明色; imagesavealpha(self::$canvas, true); // (很重要)设置标记以在保存 PNG 图像时保存完整的 alpha 通道信息; imagepng(self::$canvas); // 保存图片为png imagedestroy(self::$canvas); // 清除画布资源 } /** * [text_image 获取字体相关属性] * @param [type] $size [像素单位的字体大小] * @param [type] $angle [text 将被度量的角度大小] * @param [type] $fontfile [TrueType 字体文件的文件名] * @param [type] $text [要度量的字符串] * @return [type] [description] */ public static function text_image($size, $angle=0, $fontfile, $text) { //获取文字信息 $info = imagettfbbox($size, $angle=0, $fontfile, $text); $minx = min($info[0], $info[2], $info[4], $info[6]); $maxx = max($info[0], $info[2], $info[4], $info[6]); $miny = min($info[1], $info[3], $info[5], $info[7]); $maxy = max($info[1], $info[3], $info[5], $info[7]); // var_dump($minx.' '.$maxx.' '.$miny.' '.$maxy); /* 计算文字初始坐标和尺寸 */ $x = $minx; $y = abs($miny); $w = $maxx - $minx; $h = $maxy - $miny; $re = array( 'x' => $x, // 基点 X 位置 'y' => $y, // 基点 Y 位置 'w' => $w, // 字体宽度 'h' => $h, // 字体高度 ); return $re; } /** * [color_16 十六进制颜色码转换RGB颜色值与透明度] * @param string $color [十六进制颜色码] * @return [type] [description] */ public static function color_16($color='#FFFFFF') { if (is_string($color) && 0 === strpos($color, '#')) { $color = str_split(substr($color, 1), 2); $color = array_map('hexdec', $color); if (empty($color[3]) || $color[3] > 127) { $color[3] = 0; } return $color; } else { return false; } } } Image::canvas_image();生成的字体效果: