PHP核心编程——GD图像处理

GD图像处理基本技术

目录

GD图像处理基本技术

GD库的引入和介绍

创建画布资源

操作画布资源

输出画布资源

销毁画布资源

获取图片信息

验证码的实现

缩略图的实现

水印图


GD库的引入和介绍

API:外部提供的应用接口,已经准备好了一套处理某些功能的机制,用户只需要按照指定的数据要求,调用指定的函数或者方法(类)就可以实现某个功能。

1)GD库的概念:Graphics Device,图像处理扩展(外部提供的API),能够允许PHP在脚本中使用对应的函数来实现某些图像制作功能

2)GD库的引入:GD库是外部提供的API,已经被集成到PHP扩展库中,(不需要下载),但是需要在PHP配置文件中开启对应的扩展。GD扩展(GD2)

注意:记得重启Apache

 

创建画布资源

1)imagecreate(int $x_size , int $y_size):创建一个空白画布(背景色是白色的)

2)imagecreatetruecolor(int $width , int $height):创建一个真彩画布(背景色是黑色的,需要填充)

 

3)imagecreatefromjpeg(string $filename):打开一个jpeg格式的图片资源

4)imagecreatefromgif(string $filename):打开一个GIF格式资源(PHP中无法实现动态)

5)imagecreatefrompng(string $filename):打开png格式图片资源

如果从已知文件创建图片资源,那么一定要匹配打开方式,否则会出错。

 

操作画布资源

说明:所有的画布资源操作都是需要指定画布资源,而且都是第一个参数

 

1)分配颜色:imagecolorallocate(resource $image , int $red , int $green , int $blue):根据RGB三色组给指定画布资源分配一组颜色,会返回一个颜色句柄(一组整数)。

在真彩图片资源中,所有分配的颜色都不会自动给图片资源上色,是用来后续操作图片资源的时候,指定着色的;但是如果当前使用imagecreate创建的图片资源,那么第一个分配的颜色,会自动被着色为图片背景色。

注意:凡是给图片增加内容,基本都需要分配颜色(每一个操作图片的函数之前,都需要先调用分配颜色的函数得到一个颜色)。

2)填充区域:imagefill(resource $image , int $x , int $y , int $color):指定位置开始填充指定颜色

Imagefill的填充逻辑:从指定点开始自动匹配相邻点,如果颜色一致,自动渲染,扩展到全图。

3)画直线:imageline(resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color):制作一条直线

4)画矩形:imagerectangle(resource $image , int $x1 , int $y1 , int $x2 , int $y2 , int $color):制作一个矩形

5)画圆弧:imagearc(resource $image , int $cx , int $cy , int $w , int $h , int $s , int $e , int $color):imagearc() 以 cx,cy(图像左上角为 0, 0)为中心在 image 所代表的图像中画一个椭圆弧。w 和 h 分别指定了椭圆的宽度和高度,起始和结束点以 s 和 e 参数以角度指定。0°位于三点钟位置,以顺时针方向绘画。

6)在画布上写字:

imagestring(resource $image , int $font , int $x , int $y , string $s , int $col):用来书写ASCII对应的字符(英文),imagestring() 用 col 颜色将字符串 s 画到 image 所代表的图像的 x,y 坐标处(这是字符串左上角坐标,整幅图像的左上角为 0,0)。如果 font 是 1,2,3,4 或 5,则使用内置字体。

 imagettftext(resource $image , float $size , float $angle , int $x , int $y , int $color , string $fontfile , string $text):用来数学任意文字(中文)。需要指定字体路径(ttf文件:默认是Windows/fonts/)

 

输出画布资源

1)输出为图片文件;以图片文件形式保存到本地文件夹

2)输出为网页图片:以图片展示给HTML(用户):服务器需要告知服务器当前内容是图片(修改响应头)

Image+图片格式:返回值为bool

imagejpeg(resource $image [, string $filename [, int $quality ]]):保存成jpg格式图片,quality 为可选项,范围从 0(最差质量,文件更小)到 100(最佳质量,文件最大)。默认为 IJG 默认的质量值(大约 75)。

imagepng(resource $image [, string $filename ]):保存成png格式图片

imagegif(resource $image [, string $filename ]):保存GIF格式图片

 

如果图片只是提供了图片资源,不指定保存文件位置,系统认为是输出给浏览器;如果指定了保存位置,系统认为是保存到本地(第二个参数)。

 

 

细节1:如果图片输出或者保存出错,浏览器看到的永远是告诉你图片错了,但是绝对不会告知错误原因在哪,需要关闭header图片输出,再看问题。

 

 

细节2:如果图片输出之后没有成功,但是关闭header之后也看不到错误:最大的可能是图片输出之前输出了别的额外的内容(喜欢输出pre),应该查看网页源码,看看图片输出之前是否有任何输出:尤其是空格空行

销毁画布资源

从内存中将画布资源清理掉,释放内存。

imagedestory(resource $image)

 

获取图片信息

1)获取画布尺寸:imagesx(resource $image),imagesy(resource $image)

2)获取图片尺寸:getimagesize(string $filename [, array &$imageinfo ])

 

 

 

 

 

验证码的实现

验证码(CAPTCHA),全自动区分计算机和人类的图灵测试的缩写。由计算机生成并评判,但是必须只有人类才能解答。

图片验证码:计算机将拿到的验证码存放到图片中,然后用户看到然后识别,然后提交给服务器,服务器再根据用户提交的和服务器之前生成的进行比较。

1)实现验证码图片展示

a.生成图片资源:背景色设定

b.生成文字

c.输出图片给浏览器

d.关闭资源

 

2)实现验证码文字的随机变换:有一串文字可以随机选择

a.制作目标字符串集:从哪里选内容

b.如何随机从字符串中取出对应的汉字:含在在utf-8字符集中一个字占用3个字节,英文字母只占一个字节。

c.随机取出字符

d.将取到的字符放在图片指定位置

 

3)实现验证码文字的颜色的随机变化

 

4)实现验证码背景或干扰噪点:增加一些额外不影响用户看,但是会产生模糊效果的内容,(点或者线):imagestring/imageline/imagesetpixel

imagesetpixel — 画一个单一像素

改变文字大小和位置以及其他可变信息

 

 

5)实现点击刷新验证码功能:实现验证码在浏览器显示的功能

a.创建一个表单文件,里面有一个img标签能够显示图片

b.实现点击更换验证码。让HTML重新请求PHP脚本,产生一张新的图片。因此需要增加一个点击事件:img的src是否重新发起请求,取决于浏览器;浏览器是否重新发起请求,取决于src是否改变。如何让其点击一次变换一次。

 

 

缩略图的实现

1)制作图片缩略图的原理:

缩略图:将原图得到一个较小的图(尺寸上)

缩略图原理:将原图打开,然后放到另一个较小的图片资源中,最后进行保存即可。

2)实现固定宽高的缩略图

a.得到一张原图资源

b.得到一个缩略图资源

c.实现图片采样复制:GD提供了函数:imagecopyresampled(resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h)

d.保存缩略图

e.销毁所有资源:原图和缩略图

 

3)实现等比例缩放的固定宽或高的缩略图

优点:图片不会变形

缺点:缩略图有些部分需要进行额外填充(白色填充:补白)

1、计算缩略图宽高比和原图宽高比

2、如果缩略图宽高比大于原图宽高比,将缩略图中用原图的高尽可能填满:缩略图的高是完整的,宽度不够(补白);如果缩略图的宽高比小于原图宽高比,将缩略图中用原图的宽尽可能填满:缩略图宽是完整的,高度不够(补白)

3、将图片放到缩略图中间

 

 

 

水印图

水印图:watermark,在某个图片上增加一个透明的印记(马赛克)

水印图用途:版权操作

1)制作图片水印图的原理

水印图制作原理:将一个带有明显标志的图片放到另外一张需要处理的图片之上。

2)实现固定位置的水印图:左上角

a.获取原图资源(放上水印图)

b.获取水印图资源

c.合并图片(把图片合到目标图上)

imagecopymerge(resource $dst_im , resource $src_im , int $dst_x , int $dst_y , int $src_x , int $src_y , int $src_w , int $src_h , int $pct)

将 src_im 图像中坐标从 src_x,src_y 开始,宽度为 src_w,高度为 src_h 的一部分拷贝到 dst_im 图像中坐标为 dst_x 和 dst_y 的位置上。两图像将根据 pct 来决定合并程度,其值范围从 0 到 100。当 pct = 0 时,实际上什么也没做,当为 100 时对于调色板图像本函数和 imagecopy() 完全一样,它对真彩色图像实现了 alpha 透明。

d.保存输出

e.清除资源

 

3)实现可选9个位置的水印图:封装制作水印图的函数

a.创建一个制作水印图的函数结构:制作水印图需要提供哪些条件?原图资源,水印图资源,位置选择?9个 透明度,保存位置路径

b.结果是希望产生水印图,但是可能产生成功,返回文件保存名字。但是如果产生失败,返回false,但是还需要告知外界原因:通过引用传参解决

c.水印图前提:原图和对应的水印图都存在

d.判定保存路径是否存在

e.打开原图和水印图资源

1)想办法确定用什么函数来打开图片资源,通过图片的MIME类型:获取图片信息

2)通过MIME类型得到要打开图片的函数:先设定一个数组进行匹配,匹配成功,自动构造创建函数(保存函数)失败则提示错误

3)匹配数据

4)组合函数名字:打开原图资源函数,打开水印图函数,保存水印图函数

f.合并图片资源:产生水印,位置需要计算

1)计算水印提在原图中的位置

2)合并图片资源

g.保存水印图片和销毁资源

 

实现代码:

<?php



       //制作水印图制作函数



       /*

        *@param1 string $src_image,原图路径

        *@param2 string $wat_image,水印图路径

        *@param3 string $path,水印图存储路径

        *@param4 string $error,记录错误信息的变量

        *@param5 int $position = 1,水印图加载位置:1代表左上角以此类推9代表右下角

        *@param6 int $pct = 20,透明度,默认20

       */



       function watermark($src_image,$wat_image,$path,&$error,$position = 1,$pct = 20){

              //验证原图和水印图都存在

              if(!is_file($src_image)){

                     $error = '原图不存在!';

                     return false;

              }

             

              if(!is_file($wat_image)){

                     $error = '水印图不存在!';

                     return false;

              }



              //判定路径保存是否存在

              if(!is_dir($path)){

                     $error = '保存位置不正确!';

                     return false;

              }

             

              //获取图片信息

              $src_info = getimagesize($src_image);

              $wat_info = getimagesize($wat_image);



              //定义一组数据:用来产生对应图片

              $allow=array(

                     'image/jpeg' => 'jpeg',

                     'image/jpg' => 'jpeg',

                     'image/gif' => 'gif',

                     'image/png' => 'png',

                     'image/pjpeg' => 'pjpeg',

                     'image/jpeg' => 'jpeg'    

              );

             

              //匹配数据

              if(!array_key_exists($src_info['mime'],$allow)){

                     $error = '当前文件资源不允许制作水印图';

                     return false;

              }



              if(!array_key_exists($wat_info['mime'],$allow)){

                     $error = '当前水印图不允许做资源使用!';

                     return false;

              }



              //组合函数

              $src_open = 'imagecreatefrom'.$allow[$src_info['mime']];

              $wat_open = 'imagecreatefrom'.$allow[$wat_info['mime']];

              $src_save = 'image'.$allow[$src_info['mime']];



              //打开资源

              $src = $src_open($src_image);

              $wat = $wat_open($wat_image);



              //计算水印图在原图中的位置

              $start_x = $start_y = 0;

              switch($position){

                     case 1:           //左上角

                            break;    

                     case 2:           //上中间

                            $start_x = ceil(($src_info[0] - $wat_info[0]) / 2);

                            break;

                     case 3:           //右上

                            $start_x = $src_info[0] - $wat_info[0];

                            break;

                     case 4:           //中左

                            $start_y = ceil(($src_info[1] - $wat_info[1]) / 2);

                            break;

                     case 5:           //正中

                            $start_x = ceil(($src_info[0] - $wat_info[0]) / 2);

                            $start_y = ceil(($src_info[1] - $wat_info[1]) / 2);

                            break;

                     case 6:           //中右

                            $start_x = $src_info[0] - $wat_info[0];

                            $start_y = ceil(($src_info[1] - $wat_info[1]) / 2);

                            break;

                     case 7:           //下左

                            $start_y = $src_info[1] - $wat_info[1];

                            break;

                     case 8:           //下中

                            $start_x = ceil(($src_info[0] - $wat_info[0]) / 2);

                            $start_y = $src_info[1] - $wat_info[1];

                            break;

                     case 9:           //下右

                            $start_x = $src_info[0] - $wat_info[0];

                            $start_y = $src_info[1] - $wat_info[1];

                            break;

                     default:

                            $error = '位置信息错误!(请选择数字1-9)';

                            return false;

              }





              //合并图片资源

              if(imagecopymerge($src,$wat,$start_x,$start_y,0,0,$wat_info[0],$wat_info[1],$pct)){

                     //成功  保存图片

                     //header('Content-type:'.$src_info['mime']);

                     $filename = 'watermark_'.trim(strrchr($src_image,'/'),'/');

                     //echo $filename;exit;

                     $src_save($src,$path.'/'.$filename);

                     //销毁资源

                     imagedestroy($src);

                     imagedestroy($wat);

                     return $filename;

              }else{

                     //失败

                     $error = '水印图制作(合并)失败!';

                     return false;

              }

       }



       //调用函数

       $res = watermark('../uploads/315177.jpg','water.jpg',__DIR__,$error,10);

       if($res){

              echo $res;

       }

       else{

              echo $error;

       }

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值