昨天在用GD库的imagettftext在图片上写字的时候,发现写字的坐标并不是很精确的按照指定的参数的位置插入字体的,一直觉得很诡异。由于GD库中很多画图操作都是以坐标为基础的,因而就花了点时间了解了一下GD的坐标系统。

1.建立画布

$im = imagecreatetruecolor(200,200);

$im = imagecreatetruecolor(200,200);

当然也可以直接从png,gif,jpg等图片直接建立画布(或者称为资源、图片区域)。

画布建好之后,就可以在该画布的范围内(也就是说,如果你的画图操作超出了画图的范围,是无法体现在图像中的)进行画图操作了。

建好画布之后,我们做的测试步骤如下:

2.格式栅栏化画布。

通过imageline每隔20px花一条直线,作为识别的参考物。

for($start_x = 0;$start_x <= $canvas_w;$start_x += 20){

if($start_x == $font_x){

imageline($im,$start_x,0,$start_x,$width,$mixed);

}else{

imageline($im,$start_x,0,$start_x,$width,$red);

}

}

for($start_y = 0;$start_y <= $canvas_h;$start_y += 20){

if($start_y == $font_y){

imageline($im,0,$start_y,$height,$start_y,$mixed);

}else{

imageline($im,0,$start_y,$height,$start_y,$red);

}

}

格式栅栏化后的画布类似于下图:

3.在指定的位置添加文字

这里用到的函数是imagettftext

该 函数的接口: array imagettftext ( resource $image, float $size , float $angle , int $x , int $y , int $color , string $fontfile, string $text )

其中$x 和 $y 是文字的baseline的起点(也就是文字左下角的点的坐标,换言之,字体只是以baseline为参考,无法保证所有字符都在baseline之上)

imagettftext($im,$fontsize,0,$font_x,$font_y,$green ,$fontfile ,$text);

其中$font_x=40,$font_y=40

写出的字如下所示:

可以看出,字母g的下端已经超过了baseline的范围

4.   确定字符的盒装矩形范围

GD库提供了imagettfbbox函数用于返回字符串所占的盒装区域(矩形区域)的4个坐标(当然imagettftext本身也会返回字符串所占区域的坐标,只是在字符串画在图片上之后返回)

$box = imagettfbbox($fontsize,0,$fontfile,$text);

我们打印出来box的值为:

Array

(

[0] => 0

[1] => 7

[2] => 70

[3] => 7

[4] => 70

[5] => -23

[6] => 0

[7] => -23

)

注意观察其中有负值的坐标。

同样观察坐标值我们发现:没有任何一个点的坐标是字体盒子的坐标原点。

我们接着将盒子的矩形区域画出来:

$box_width = max(abs($box[2] - $box[0]),abs($box[4] - $box[6]));

$box_height = max(abs($box[7] - $box[1]),abs($box[5] - $box[3]));

$abs_y1 = abs($box[1]);

$abs_y2 = abs($box_height - $abs_y1);

$left_bottom_x = $font_x +$box[0];

$left_bottom_y = $font_y +$box[1];

$right_bottom_x = $left_bottom_x + $box_width;

$right_bottom_y = $left_bottom_y;

$right_top_x = $right_bottom_x;

$right_top_y = $right_bottom_y-$box_height;

$left_top_x = $left_bottom_x;

$left_top_y = $right_top_y;

imageline($im,$left_bottom_x,$left_bottom_y,$right_bottom_x,$right_bottom_y,$blue);

imageline($im,$right_bottom_x,$right_bottom_y,$right_top_x,$right_top_y,$blue)

imageline($im,$right_top_x,$right_top_y,$left_top_x,$left_top_y,$blue);

imageline($im,$left_top_x,$left_top_y,$left_bottom_x,$left_bottom_y,$blue);

画出的盒子的范围如下图中蓝色框所示(浅青色的横线为字体的baseline线):

观察字体所占矩形区域的位置和字体的baseline的位置关系,可以猜测,在字体所在的box中,字体的坐标大致是这样的:

同时我们也猜测:将字体画到图片上的时候,实际上是以字体所在区域的baseline的最左侧坐标与写字体指定的坐标位置重合而得到的,也就是类似于平移操作。下图示意:

写的寥寥草草,一片混沌,权当笔记。

需要注意的是:

1.imagettftext 中写入文字时,使用的是UTF-8的编码,要特别注意。

2.imagettftext写文字不支持自动换行,需要你手动去控制。

完整的测试代码如下:

$width = 200;

$height = 200;

$canvas_w = $height + 1;

$canvas_h = $height + 1;

$im = imagecreatetruecolor($canvas_w,$canvas_h);

$white = imagecolorallocate($im, 255, 255, 255);

$red = imagecolorallocate($im, 255, 0, 0);

$green = imagecolorallocate($im, 0, 255, 0);

$blue = imagecolorallocate($im, 0, 0, 255);

$mixed = imagecolorallocate($im, 0, 255, 255);

$line_color = $blue;

imagefill($im, 0, 0, $white);

$fontsize = 20;

$fontfile = "msyh.ttf";

$text = "string";

$font_x = 40;

$font_y = 40;

for($start_x = 0;$start_x <= $canvas_w;$start_x += 20){

if($start_x == $font_x){

imageline($im,$start_x,0,$start_x,$width,$mixed);

}else{

imageline($im,$start_x,0,$start_x,$width,$red);

}

}

for($start_y = 0;$start_y <= $canvas_h;$start_y += 20){

if($start_y == $font_y){

imageline($im,0,$start_y,$height,$start_y,$mixed);

}else{

imageline($im,0,$start_y,$height,$start_y,$red);

}

}

imagettftext($im ,$fontsize,0,$font_x,$font_y,$green ,$fontfile ,$text);

$box = imagettfbbox($fontsize,0,$fontfile,$text);

$left_bottom = array($box[0],$box[1]);

$right_bottom = array($box[2],$box[3]);

$right_top = array($box[4],$box[5]);

$left_top = array($box[6],$box[7]);

$box_width = max(abs($box[2] - $box[0]),abs($box[4] - $box[6]));

$box_height = max(abs($box[7] - $box[1]),abs($box[5] - $box[3]));

$abs_y1 = abs($box[1]);

$abs_y2 = abs($box_height - $abs_y1);

$left_bottom_x = $font_x +$box[0];

$left_bottom_y = $font_y +$box[1];

$right_bottom_x = $left_bottom_x + $box_width;

$right_bottom_y = $left_bottom_y;

$right_top_x = $right_bottom_x;

$right_top_y = $right_bottom_y-$box_height;

$left_top_x = $left_bottom_x;

$left_top_y = $right_top_y;

imageline($im,$left_bottom_x,$left_bottom_y,$right_bottom_x,$right_bottom_y,$blue);

imageline($im,$right_bottom_x,$right_bottom_y,$right_top_x,$right_top_y,$blue);

imageline($im,$right_top_x,$right_top_y,$left_top_x,$left_top_y,$blue);

imageline($im,$left_top_x,$left_top_y,$left_bottom_x,$left_bottom_y,$blue);

imagejpeg($im,'res.jpg',100);

imagedestroy($im);

php gd 坐标,【PHP】GD库笔记 初探GD库的坐标相关推荐

  1. 程序员的自我修养--链接、装载与库笔记:运行库

    1. 入口函数和程序初始化 程序从main开始吗?:操作系统装载程序之后,首先运行的代码并不是main的第一行,而是某些别的代码,这些代码负责准备好main函数执行所需要的环境,并且负责调用main函 ...

  2. docker php gd png.h,docker php 容器安装GD库

    用thinkphp 5 Image库,创建缩略图报错:Call to undefined function imagecreatefromjpeg(),度娘一下发现是php 环境没有配置GD库扩展,因 ...

  3. PHP 中 GD库(以及Jpgraph库) 的配置和使用。(满屏荒唐言,一把辛酸泪)

    PHP 中 GD库(以及Jpgraph库) 的配置和使用 (满屏荒唐言,一把辛酸泪)搞这种配置什么的真的太痛苦了! 一.安装前说明. 我的安装环境是,windows + IIS +php 首先我们要理 ...

  4. centos php gd库,Centos安装GD库

    tar zxvf ncurses-5.6.tar.gz 进入目录 cd ncurses-5.6 生成 makefile文件, 再进一步编译 ./configure --prefix=/usr --wi ...

  5. redhat php gd,RedHat下安装并开启PHP GD库的步骤

    RedHat下安装并开启PHP GD库的方法 GD库是PHP进行图文操作时一个重要的库.红帽系统适合用编译安装.具体各步骤如下: 1.准备工作: 需要的软件分别为:zlib-1.2.7.tar,lib ...

  6. Python 数据分析与展示笔记3 -- Matplotlib 库基础

    Python 数据分析与展示笔记3 – Matplotlib 库基础 Python 数据分析与展示系列笔记是笔者学习.实践Python 数据分析与展示的相关笔记 课程链接: Python 数据分析与展 ...

  7. 多线程编程学习笔记——任务并行库(二)

    接上文 多线程编程学习笔记--任务并行库(一) 三.   组合任务 本示例是学习如何设置相互依赖的任务.我们学习如何创建一个任务的子任务,这个子任务必须在父任务执行结束之后,再执行. 1,示例代码如下 ...

  8. Python 数据分析与展示笔记4 -- Pandas 库基础

    Python 数据分析与展示笔记4 – Pandas 库基础 Python 数据分析与展示系列笔记是笔者学习.实践Python 数据分析与展示的相关笔记 课程链接: Python 数据分析与展示 参考 ...

  9. Python 三维可视化笔记1 -- TVTK库

    Python 三维可视化笔记1 – TVTK库 Python 三维可视化系列笔记是笔者在学习黄天羽老师的<Python科学计算三维可视化>课程及笔者实践三维可视化的笔记. 课程链接: Py ...

最新文章

  1. 《科学》十大年度科学突破反映的新动向
  2. SQL Server 数据库崩溃后的恢复之法
  3. JHChart 1.1.0 iOS图表工具库中文ReadMe
  4. 正式发布! .NET开发控件集ComponentOne 新版本加入Blazor UI
  5. Unity学习疑问记录之图片画质
  6. 微信支付 H5 版本 PHP
  7. 国家电网车辆智能车载终端4G全网通T-BOX 、车联网OBD终端、4G TBOX终端
  8. C语言学习笔记(自用)(1):初识C语言
  9. 单声道蓝牙实现音乐播放
  10. 眼球追踪技术给各大科技巨头带来的四大应用前景
  11. 第29课:AD中class,设计参数,规则的设置
  12. Cobot与Jenkins集成
  13. oracle数据库 dmp文件,数据库DMP文件损坏怎么修复
  14. linux 命令 置顶,[置顶] Linux命令惯用法
  15. C++ 内存管理 —— 第一講:C++ 內存構件
  16. .NET ZXING 生成带logo的二维码和普通二维码及条型码
  17. Android 多线程详解
  18. Java多线程和多进程的优缺点
  19. 《好想好想谈恋爱》经典对白
  20. Mysql查询时强制指定索引

热门文章

  1. phpwind支持php7吗,PHPWind 7正式发布
  2. 活出生命的意义-读后感
  3. sketch里的ios控件_「插件」五分钟了解微信团队打造的 Sketch 插件 :WeSketch
  4. automagica 调用迅雷批量下载美剧
  5. 电脑操作及相关指令、命令
  6. DearMob iPhone Manager for Mac(iPhone手机数据加密传输软件)
  7. 安装图解:Linux Mint 4.0(Daryna)(或者说完美的桌面系统)
  8. linux 查看dhcp dns,RHEL6 DNS+DHCP+DDNS
  9. python 合并表格
  10. 我不 大冰2017新书pdf免费下载