在之前的文章中我们介绍了,如何使用 GD
库 更换小程序码中的logo;
这里我们来具体介绍一下,如何使用 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;
}
/**
* [text_writer 画布写入字体]
* @param [type] $text [字体]
* @param [type] $color [颜色]
* @param [type] $text_size [大小]
* @param [type] $text_fonts [样式]
* @return [type] [description]
*/
public function text_writer($text, $color, $text_size, $text_fonts, $text_x, $text_y)
{
// 获取文字信息(基点位置及宽高)
$text_info = self::text_image($text_size, $angle=0, $text_fonts, $text);
// 设置字体颜色(十六进制颜色码转换RGB颜色值与透明度)
$color = self::color_16($color);
$color = imagecolorallocatealpha(self::$canvas, $color[0], $color[1], $color[2], $color[3]);
// 计算文字文字在画布中的位置(以基点为准,文字在图像中的位置)
$text_x = $text_x ?? (imagesx(self::$canvas) - $text_info['w'])/2 + $text_info['x'];
if ($text_x < 0) {
$text_x = imagesx(self::$canvas) - $text_info['w'] + $text_x;
}
$text_y = $text_y ?? (imagesy(self::$canvas) - $text_info['h'])/2 + $text_info['y'];
// 图片添加字体
imagettftext(self::$canvas, $text_size, 0, $text_x, $text_y, $color, $text_fonts, $text);
}
/**
* [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();
本文为冯奎原创文章,转载无需和我联系,但请注明来自冯奎博客fengkui.net
最新评论