上篇文章我们已经学习了一个 GD 库的应用,那就是非常常用的制作验证码的功能。不过在现实的业务开发中,这种简单的验证码已经使用得不多了,大家会制作出更加复杂的验证码来使用。毕竟现在的各种外挂软件已经能够轻松地破解这种简单的图片验证码了。当然,我们也可以简单地对他进行变形,比如使用中文然后按顺序点击之类的,这些都比较简单地就能实现。更复杂的验证码则推荐使用一些开源的库或者api来实现。

今天,我们将继续学习 GD 库的一些常用的应用。依然是通过一些小例子来进行学习,同样也是我们在日常开发中非常常用的一些功能。

生成缩略图

在日常的开发过程中,不管是客户还是我们自己在后台上传的图片,大小可能都不一定是我们需要的尺寸,这个时候缩略图的功能就比较重要了。一般我们会在保留原图的基础上生成对应原图的一张缩略图用于前台统一尺寸页面的展示。

$w = imagesx($im);
$h = imagesy($im); $imNew = imagecreatetruecolor($w / 2, $h / 2); imagecopyresized($imNew, $im, 0, 0, 0, 0, $w / 2, $h / 2, $w, $h); header("Content-type: image/jpg");
imagejpeg($imNew);
imagedestroy($imNew);

上述代码中,我们生成的缩略图是原图的一半大小,使用的就是 imagecopyresized() 这个函数,它的参数依次是新图画布、原图、新图的x和y坐标起始点、原图的x和y坐标起始点、新图的大小、原图的大小。参数比较多,但也比较好理解,就是将原图缩小到指定的大小并放到新的画布上就可以了。

imagesx() 和 imagesy() 函数不要从字面理解为什么 x 、 y 坐标点之类的,它们其实是获得图像句柄文件的宽和高。如果我们输出的是 jpg 格式的图片,还可以指定它的压缩比率。

$w = imagesx($im);
$h = imagesy($im); $imNew = imagecreatetruecolor($w / 2, $h / 2); imagecopyresized($imNew, $im, 0, 0, 0, 0, $w / 2, $h / 2, $w, $h); header("Content-type: image/jpg");
imagejpeg($imNew, null, 10);
imagedestroy($imNew);

也就是 imagejpeg() 函数的最后一个参数,就和 PS 导出图片时的压缩比率一样,如果数字越小,压缩比越高,数字越大,压缩比越低,图片质量也就越好。默认值为 75 ,可以设置从 0 到 100 的压缩比。第二个参数依然是保存图片的路径,我们这里测试的代码还是直接从浏览器输出的,所以我们这里是给的一个 null 。

从图片的画质来看,确实比上一张直接缩小的图片模糊了许多。当然,图片的大小也小了很多。对于网站的优化来说,jpg 图片的压缩比例一般都会在默认值的 75 左右。如果太小就会出现这种过于模糊的情况从而影响用户的体验。具体业务具体分析,需要多大的图片大小还是要根据我们实际的情况来定。

生成指定大小的等比例缩略图

还有一种业务情况是,我们前台的图片展示大小都是一样的,比如商品图片在列表中的显示。这时,很多图片直接压缩可能就会丢失比例,比如我们上传了一张 16:9 的大宽图,而前台列表页的图片位置是 4:3 的图,这里我们就要等比例按照最大宽度或者最大高度进行缩小,同时多出来的部分留白边或者透明边,这时,只要计算一下图片的比例情况就可以了。

$w = imagesx($im);
$h = imagesy($im); $imNew = imagecreatetruecolor(202, 152);
imagefill($imNew, 0, 0, imagecolorallocate($imNew, 255, 255, 255));
imagerectangle($imNew, 0, 0, 201, 151, imagecolorallocate($imNew, 0, 0, 0)); $sW = 0;
$sH = 0;
if ($w / $h > 200 / 150) {
$q = 200 / $w;
$sH = $h * $q;
$sW = $w * $q;
$sX = 0;
$sY = (150 - $sH) / 2;
} else {
$q = 150 / $h;
$sH = $h * $q;
$sW = $w * $q;
$sX = (200 - $sW) / 2;
$sY = 0;
} imagecopyresized($imNew, $im, $sX + 2, $sY + 1, 0, 0, $sW, $sH, $w, $h); header("Content-type: image/jpg");
imagejpeg($imNew);
imagedestroy($imNew);

在测试代码中,我们规定的大小是 200*150 的图片大小,也就是 4:3 的图片规格。而需要操作的图片则是 300*244 的一张不太规范的图片。这时,我们通过计算 宽/高 的比例,来确定是以宽为基准进行缩小还是以高为基准进行缩小。如果原图的宽高比大于我们规定的图片宽高比,则认为是以宽度为基准进行缩小。反之,就是以高度进行缩小。同样地,具体的宽高结果的算法都都是基于对应的比率进行等比例缩小的。同时,我们还要计算图片的位置,要放在居中的位置。最后,再将缩小的大小放入到指定大小的画布中。

我们这段测试代码中的画布多了两个像素,是为了画那个黑色的边框,目的也是为了演示能够看清楚。

可以看到,我们等比例缩放之后是以原图的高为基准进行缩放的,所以图片的两边会出现白边。如果是以宽为基准的,那么图片上下会出现白边。当然,如果原图的比例和我们需要的比例是一样的,就会完整地撑满整个画布。大家可以自己用其它大小的图片测试一下。

图片加水印

除了缩略图之外,加水印的功能也是很多业务开发中必备的功能。直接的文字水印其实就不用多说了,上篇文章中的 imagettftext() 就可以直接加了,只需要给它用 imagecolorallocatealpha() 函数指定一个带透明的颜色就可以了。今天我们主要来讲的是图片水印的添加。

$imNew = imagecreatetruecolor(150, 30);

imagecolortransparent($imNew, imagecolorallocatealpha($imNew, 255, 255, 255, 128));
imagesavealpha($imNew, true); $font = '../font/msyh.ttf';
imagettftext($imNew, 16, 0, 11, 21, imagecolorallocate($imNew, 255, 255, 255), $font, '硬核项目经理'); if (imagesx($im) > 150 + 10 && imagesy($im) > 60 + 10) {
imagecopy($im, $imNew, imagesx($im) - 150 - 10, imagesy($im) - 30 - 10, 0, 0, 150, 30); imagecopymerge($im, $imNew, imagesx($im) - 150 - 10, imagesy($im) - 60 - 10, 0, 0, 150, 30, 50);
} header("Content-type: image/jpg");
imagejpeg($im);
imagedestroy($im);

首先,我们通过 imagecolortransparent() 和 imagesavealpha() 指定一个透明画布。然后通过 imagettftext() 生成一张文字图片。注意,这里是图片哦,不是直接添加的文字。

接着,使用 imagecopy() 或 imagecopymerge() 来将水印图片拷贝到原始图片上。这两个函数的区别就是 imagecopymerge() 在图片合并的时候多了一个参数可以指定通道的透明度,也就是说,如果是一张不带透明度的图片可以直接使用这个函数来让图片增加透明的效果。

在添加水印之前的判断是用于判断图片大小是否适合添加水印,如果图片比水印文件还小的话,那么就不要添加水印了,或者再将水印也缩小后再进行添加。

这样,简单地水印添加就完成了。网上其实能找到很多前辈已经封装好的添加水印的类,或者 Composer 中也有很多现成的库,这里只是手写一个简单的效果供大家学习复习。

总结

关于图片 GD 库的功能函数还有很多,但说实话,笔者现在都已经用得不多了。为什么呢?在实际的业务开发中,大家其实都已经习惯使用 oss 、七牛、upyun 之类的云存储了。不管是图片缩放、添加水印,甚至是简单地进行一些 PS 编辑,都非常方便。而且最主要的是不需要再占用我们的服务器存储资源以及带宽资源,何乐而不为呢。像我现在的工作中,程序代码服务器基本上只需要原始的 20G 左右大小就可以了,只是运行代码,不存储上传的文件、图片以及静态资源。

测试代码:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202012/source/3.一起学习PHP中GD库的使用(三).php

参考文档:

https://www.php.net/manual/zh/book.image.php

关注公众号:【硬核项目经理】获取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免费得PHP、项目管理学习资料

知乎、公众号、抖音、头条搜索【硬核项目经理】

B站ID:482780532

一起学习PHP中GD库的使用(三)的更多相关文章

  1. 一起学习PHP中GD库的使用(二)

    在日常的开发过程中,GD 库最常用的功能就是帮我们对图片进行一些处理,当然,除了处理已有的图片之外,它也可以直接来画图,就像我们最常见的图片验证码.今天的内容主要就是和画图有关,所以最后我们也会做一个 ...

  2. 一起学习PHP中GD库的使用(一)

    又到了一个大家非常熟悉的库了,对于图像图形的处理来说,GD 库是 PHPer 们绕不过去的一道坎.从很早很早的 CMS 或者 Discuz 时代,各类开源软件在安装的时候就会明确地指出 GD 库是它们 ...

  3. 【代码学习】PHP中GD库的使用

    PHP--GD库 ================================================ 一.支持: 需要php支持GD库 二.作用: 验证码.水印.缩放等 三.绘画步骤: ...

  4. php中GD库的简单使用

    在php中需要图像处理的地方GD库会发挥重要的作用,php可以创建并处理包括GIF,PNG,JPEG,WBMP以及XPM在内的多种图像格式,简单的举几个例子: 1.用GD库会创建一块空白图片,然后绘制 ...

  5. php中GD库的一些简单使用

    今天了解了一些GD库的简单使用,现在稍微做一下总结! GD库是什么?,graphic device,图像工具库,gd库是php处理图形的扩展库,gd库提供了一系列用来处理图片的API,使用GD库可以处 ...

  6. (转)php中GD库的配置,解决dedecms安装中GD不支持问题

    了解gd库 在php中,使用gd库来对图像进行操作,gd库是一个开放的动态创建的图像的源代码公开的函数库,可以从官方网站http://www.boutell.com/gd处下载.目前,gd库支持gif ...

  7. PHP中GD库安装

    安装gd库扩展不能像其他扩展安装一样,直接./configure --prefix=/xxx 还需要激活png,jpeg,字库等支持 ./configure --prefix=/xxx --with- ...

  8. PHP中GD库是做什么用的? PHP GD库介绍11111111

    什么是gd库?    gd库是php处理图形的扩展库,gd库提供了一系列用来处理图片的API,使用GD库可以处理图片,或者生成图片. 在网站上GD库通常用来生成缩略图或者用来对图片加水印或者对网站数据 ...

  9. 关于织梦系统不支持php中GD库的问题

    大多数人在显成的PHP的CMS时,如织梦CMS,安装的时候不支持GD库,就导致整个网站的验证码不显示,以下是个人对此类问题的解决办法: 1.首先找到wamp的安装目录,找到PHP的文件夹,打开php. ...

随机推荐

  1. linux的iptables设置

    添加规则 -A 在链末尾追加一条规则 -I 在链开头或某序号前插入一条规则 查看规则 -L 列出所有规则 -n 数字显示地址和端口信息 -v 详细信息 -line-numbers 显示规则序号 删除规 ...

  2. Golang语言系列-01-Go语言简介和变量

    Go语言简介 Go(又称Golang)是Google开发的一种静态强类型.编译型.并发型,并具有垃圾回收功能的编程语言. 罗伯特·格瑞史莫(Robert Griesemer),罗勃·派克(Rob Pi ...

  3. 【笔记】ROC曲线

    ROC曲线 前文讲了PR曲线 这里说ROC曲线,其描述的是TPR和FPR之间的关系 TPR是什么呢,TPR就是召回率 FPR是什么呢,FPR就是和TPR对应的,即真实值为0的一行中的预测为1的部分比例 ...

  4. 更好地使用Atom支持基于Jupyter的Python开发

    有关于使用Atom进行Python开发的网上资料比较少,最近发现使用Atom结合Hydrogen插件进行Python开发,尤其是数据挖掘相关的工作,整体体验要好于Vscode,Vscode虽然说也有连 ...

  5. shodan搜索

    扫描一切联网的设备 www.shodan.io 一.ip 直接搜索:123.123.123.123 二.搜索服务 http http country:"DE" 指定搜索德国 htt ...

  6. Blazor+Dapr+K8s微服务之状态管理

    1         状态管理服务器端接口 1.1         添加Dapr.AspNetCore包 在DaprTest1.Server项目中添加Dapr.AspNetCore包,该包实现了ASP. ...

  7. com.github.ulisesbocchio:jasypt-spring-boot-starter:2.0.0引用了sping cloud Finchley.M8版本,一直报错说不能从阿里云下载

    解决方法: 1.找到idea或者eclipase中maven插件引向得settings.xml文件 2.修改文件中<mirror/>标签(配置仓库镜像用得)中<mirrorOf/&g ...

  8. jdbc获取PreparedStatement最终执行的sql语句

    //直接打印PreparedStatement对象 System.out.println(ps); 输出结果: com.mysql.jdbc.JDBC42PreparedStatement@5f205 ...

  9. 八:Filter(过滤器)

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...

  10. 创建File类 及 this.getClass().getResource()方法 用到的文件路径的问题

    1 package test; 2 3 import java.io.*; 4 import java.util.Scanner; 5 6 public class TestResource { 7 ...