19.3图片处理
19.3 图片处理
本节将介绍对已有图片做处理,包括的内容有如何打开现有图片、如何获取和该图片有关的信息、加工处理后输出图片及生成缩略图等。
19.3.1 打开已经存在的图片
通过19.1.2小节对一些函数的介绍,读者可以了解到通过函数imagecreatefrompng()可以打开一个已经存在的PNG格式的图片,如代码19-6所示。
代码19-6 打开已存在的图片19-6.php
01 <?php
02 $img=imagecreatefromjpeg("tower.jpg"); //
打开指定的图片文件
03
04 Imagejpeg($img);
05 imagedestroy($img);
06 ?>
【代码解析】程序19-6.php通过函数imagecreatefromjpeg()打开当前目录下一张已存在的JPG格式的图片,如代码第02行所示。函数imagecreatefromjpeg()的参数即文件所在路径,返回值是参数所指图片的资源标识符。代码最后将图片显示到页面上。事实上,该函数是通过已有图像新建一个图像,并不是单纯打开原图像本身。这段代码的执行效果如图19-7所示。
如果将图片文件tower.jpg的后缀名强制改为.png,即便是使用函数imagecreatefrompng(),也无法打开文件,因为图片本质还是jpg格式的图片。读者可以自行实践一下,此种情况下会有如图19-8所示的警告提示信息。

图19-7 打开已存在的图片

图19-8 图像处理函数的警告提示信息
提示 这个警告信息提示用户,图片“tower.png”不是一个有效的PNG图片。
19.3.2 获取图片的相关属性
对打开的图片可以获取该图片的有关属性,如图片大小、图片的宽和高等。代码19-7演示了如何在PHP程序中获取图片的相关属性值。
代码19-7 获取图片的相关属性19-7.php
01 <?php
02 $img=imagecreatefromjpeg("tower.jpg"); //
打开指定的图片文件
03
04 $x = imageSX($img);
05 $y = ImageSY($img);
06 echo "
图片tower.jpg
的宽为:<b>$x</b> pixels";
07 echo "<br/>";
08 echo "<br/>";
09 echo "
图片tower.jpg
的高为:<b>$y</b> pixels";
10 ?>
【代码解析】代码的执行结果如图19-9所示。代码使用函数imageSX()获取已打开图片的宽度,其参数为所打开图像的资源标识符,返回值为图像的宽度,单位为像素。同理,调用函数imageSY()取得图片的高度。
另外,通过一个不属于GD库的函数getimagesize(),可以取得图片的大小等相关属性,该函数的语法如下。
array getimagesize(string $filename [, array &imageinfo])
该函数可以测定GIF、JPG、PNG、SWF、BMP、XBM等多种格式图片文件的大小。该函数第1个参数为要打开的图片的路径,该参数值可以是一个有效的URL地址。代码19-8演示了函数getimagesize()在PHP程序中的用法。
代码19-8 函数getimagesize()的用法19-8.php
01 <?php
02 $img_info=getimagesize("tower.jpg"); //
获取图片文件的大小信息
03
04 for($i=0; $i<4; ++$i)
05 {
06 echo $img_info[$i];
07 echo "<br/>";
08 }
09 ?>
【代码解析】 从程序19-8.php的执行结果如图19-10所示,可以看出,函数getimagesize()返回了一个关于该图片信息的数组,第1个、第2个元素是图像的宽、高;第3个元素是图片的格式,它的取值含义如下所示。
·取值1,表示该图片是GIF格式。
·取值2,表示该图片是JPG格式。
·取值3,表示改图片是PNG格式。
·取值4,表示该图片是SWF格式。
·取值5,表示该图片是PSD格式。
·取值6,表示该图片是BMP格式。
第4个元素是表示该图片宽、高的字串,从这个显示效果可以看出,这个宽、高字串正好可以用在HTML中表示图片的宽、高属性。比如可以按如下代码片段所示的方式使用。
<?php
$pic_name="some_image.png";
$pic_size=GetImageSize($pic_name);
?>
<img src="<?php echo $pic_name;?>" <?php echo $pic_size[3];?> >
注意 这里再次强调,该函数不属于GD库,无需GD库支持即可使用。

图19-9 获取图像的宽、高属性

图19-10 函数getimagesize()的用法
19.3.3 对图片加水印效果
对图片可以做各式各样的处理,以达到修饰图片的作用。本小节通过为图片添加水印效果为例,向读者介绍如何对图片做效果处理。
为图片添加水印通常有以下步骤。
(1)获取要添加水印的图片的宽、高值。
(2)确定图片大小是否满足水印文字大小。
(3)确定水印效果在图片中的位置。
(4)设定图像的混色模式。
(5)生成水印效果。
(6)释放资源。
该实例允许用户通过从Web页面上传图片,然后生成上传图片的水印效果。通常水印效果可以由文字生成,也可以由某个图片生成,本例将以文字生成水印效果为例。首先看完整的实例代码,然后对这些代码加以说明。代码19-9是为图片添加水印效果的完整程序。
代码19-9 为上传图片添加水印效果19-9.php
01 <?php
02 function makeImageWaterMark($image,$pos,$water_text,$font_size,$color)
03 {
04 $font_type ="C://WINDOWS//Fonts//cour.ttf";
05
06 if(!empty($image) && file_exists($image))
07 {
08 $img_info = getimagesize($image);
09 $g_w = $img_info[0]; //
取得背景图片的宽
10 $g_h = $img_info[1]; //
取得背景图片的高
11
12 switch($img_info[2]) //
取得背景图片的格式
13 {
14 case 1:
15 $img = imagecreatefromgif($image);
16 break;
17 case 2:
18 $img = imagecreatefromjpeg($image);
19 break;
20 case 3:
21 $img = imagecreatefrompng($image);
22 break;
23 default:
24 die("
图片格式错误!");
25 }
26 }
27 else
28 {
29 die("
需要加水印的图片不存在!");
30 }
31
32 //
取得使用 TrueType
字体的文本的范围
33 $temp = imagettfbbox(ceil($font_size*2.5),0,$font_type,$water_text);
34 $w = $temp[2] - $temp[6];
35 $h = $temp[3] - $temp[7];
36 if(($g_w<$w) || ($g_h<$h))
37 {
38 echo "
需要加水印的图片的大小比水印文字区域小,无法生成水印!";
39 return;
40 }
41
42 //
设置4
种水印效果位置:0
和默认是随机位置,1
为顶端居左,2
为中部居中,3
为底端居右
43 switch($pos)
44 {
45 case 0:
46 $pos_x = rand(0,($g_w - $w));
47 $pos_y = rand(0,($g_h - $h));
48 break;
49 case 1:
50 $pos_x = 0;
51 $pos_y = 0;
52 break;
53 case 2:
54 $pos_x = ($g_w - $w)/2;
55 $pos_y = ($g_h - $h)/2;
56 break;
57 case 3:
58 $pos_x = $g_w - $w;
59 $pos_y = $g_h - $h;
60 break;
61 default:
62 $pos_x = rand(0,($g_w - $w));
63 $pos_y = rand(0,($g_h - $h));
64 break;
65 }
66
67 imagealphablending($img, true); //
设置图像混色模式
68
69 if(!empty($color) && (strlen($color)==7))
70 {
71 $R = hexdec(substr($color,1,2));
72 $G = hexdec(substr($color,3,2));
73 $B = hexdec(substr($color,5));
74 }
75 else
76 {
77 die("
水印文字颜色格式不正确!");
78 }
79 $text_color = imagecolorallocate($img, $R, $G, $B);
80
81 imagettftext($img, $font_size, 0, $pos_x, $pos_y, $text_color, $font_type, $water_text);
82 switch($img_info[2]) //
取得背景图片的格式
83 {
84 case 1:
85 imagegif($img,$image);
86 break;
87 case 2:
88 imagejpeg($img,$image);
89 break;
90 case 3:
91 imagepng($img,$image);
92 break;
93 default:
94 die("
不被支持格式的图片!");
95 }
96
97 imagedestroy($img);
98 }
99
100 if(isset($_FILES) && !empty($_FILES["userfile"]) && $_FILES["userfile"]["size"]>0)
101 {
102 $uploadfile = "./".time()."_".$_FILES["userfile"]["name"];
103 if (copy($_FILES["userfile"]["tmp_name"], $uploadfile))
104 {
105 makeImageWaterMark($uploadfile,2,"Photo by Mac",16,"#43042A");
106 echo "<img src=\"".$uploadfile."\" border=\"0\">";
107 }
108 else
109 {
110 echo "
文件上传错误!<br/>";
111 }
112 }
113 ?>
114
115 <html>
116 <head><title>19-9.php</title></head>
117 <body>
118
119 <form enctype="multipart/form-data" method="POST">
120
选择上传图片: <input name="userfile" type="file">
121 <input type="submit" value="
上传">
122 </form>
123
124 </body>
125 </html>
【代码解析】代码第02行开始定义为图片添加水印效果的处理函数makeImageWaterMark(),这个自定义函数有5个参数。第1个参数$image是要添加水印效果的图片的资源标识符,第2个参数$pos是水印效果在原图片上的位置,第3个参数$water_text标识水印文字的字符串,第4个参数$font_size是水印文字的大小,最后一个参数$color是水印文字的颜色。
自定义函数makeImageWaterMark()为3种格式的图片添加水印效果,这3种图片格式是GIF、JPG和PNG,对图片格式的判断是代码第06~30行。
接着从代码第33~40行对TrueType字体的文本的范围进行判断,以保证水印所采用的字体大小符合原图片大小。函数imagettfbbox()用来取得使用TrueType字体的文本的范围,语法如下。
array imagettfbbox(float $size, float $angle, string $fontfile, string $text)
该函数计算并返回一个包围着TrueType文本范围的虚拟方框的像素大小,参数$size表示像素单位的字体大小,参数$angle表示文本显示的角度,参数$fontfile是字体文件的文件名,参数$text表示要检测的TrueType字体的文本。
代码第43行开始设置水印的4种位置,其中默认情况下采用随机位置显示水印文字。代码第67行使用函数imagealphablending()设置图像混色模式,以求达到最佳图像显示效果,语法如下。
bool imagealphablending(resource $image, bool $blendmode)
函数imagealphablending()的第1个参数是图像标识符,第2个参数如果设定为TRUE,则启用混色模式,否则关闭。该函数执行成功则返回TRUE,否则返回FALSE。
代码第69~74行,通过函数hexdec获取颜色设定值,在第79行使用函数imagecolorallocate()确定水印文字的文本颜色。
代码第81行使用函数imagettftext向图片写入文本内容,该函数在19.2.4小结介绍过,这里不再赘述。
接下来就是文件上传部分的代码,这里只需说明,当文件上传后,程序会将文件改名,以当前时间戳和原文件名组合作为新文件名。水印效果将在这个改名后的文件中生成,如代码第102、第103和第105行所示。最后在代码第106行向页面显示该文件。
通过浏览器访问19-9.php,可以看到如图19-11所示的效果。
选择当前目录下需要添加水印的图片tower1.jpg,单击页面上的“上传”按钮,如果一切正常,会看到如图19-12所示的效果。

图19-11 上传图片界面

图19-12 为图片添加水印效果
19.3.4 生成已有图片的缩略图
为一张大图生成一个缩略图,也可以看做是图片效果处理的一部分。使用GD库的“复制并调整大小”的函数可以很容易实现生成缩略图,这个函数就是imagecopyresized(),代码19-10演示了通过该函数为图片生成缩略图的过程代码。
代码19-10 生成已有图片的缩略图19-10.php
01 <?php
02 $img_name="tower.jpg";
03 $src_img=imagecreatefromjpeg($img_name);
04
05 $ow=imagesx($src_img); //
取得原图的宽
06 $oh=imagesy($src_img); //
取得原图的高
07
08 $nw=round($ow*200.0/$ow); //
计算新图的宽度
09 $nh=round($oh*200.0/$oh); //
计算新图的高度
10
11 $desc_img=imagecreate($nw, $nh); //
建立新图
12
13 imagecopyresized($desc_img, $src_img, 0, 0, 0, 0, $nw, $nh, $ow, $oh);
//
生成缩略图
14 imagejpeg($desc_img);
15
16 imagedestroy($desc_img);
17 imagedestroy($src_img);
18 ?>
【代码解析】 代码执行结果如图19-13所示,将原图缩小为了宽200、高200像素的图像,函数imagecopyresized()的将一幅图像中的一块正方形区域复制到另一个图像中,语法如下。
bool imagecopyresized(resource $dst_img, resource $src_img, int $d_x, int $d_y, int $s_x, int $s_y, int $d_w, int $d_h, int $s_w, int $s_h)
函数imagecopyresized()参数很多,但都很好理解。第1个和第2个参数分别是目标图像、原图像的标识符,接下来4个参数是目的图像和原图像的复制位置的坐标,最后4个参数是目的图像和原图像的复制区域的宽高。这段代码的执行结果如图19-13所示。
从这个结果可以看出,缩略图的效果并不能令人满意。使用函数imagecopyresampled()可以获取更好的缩略图效果,该函数重采样复制部分图像并调整大小,代码19-11演示了该函数的用法。
代码19-11 在程序中使用函数imagecopyresampled()19-11.php
01 <?php
02 $img_name="tower.jpg";
03 $percent = 0.2;
04
05 $src_img=imagecreatefromjpeg($img_name);
06
07 $ow=imagesx($src_img); //
取得原图的宽
08 $oh=imagesy($src_img); //
取得原图的高
09
10 $nw=$ow * $percent;
11 $nh=$oh * $percent;
12
13 $desc_img = imagecreatetruecolor($nw, $nh);
14 imagecopyresampled($desc_img,$src_img,0, 0, 0, 0, $nw, $nh, $ow, $oh); //
生成缩略图
15
16 imagejpeg($desc_img);
17 imagedestroy($desc_img);
18 imagedestroy($src_img);
19 ?>
这段代码的执行结果如图19-14所示。

图19-13 使用函数imagecopyresized()生成缩略图

图19-14 使用函数imagecopyresampled()对图像重新采样
【代码解析】从图19-14可以看出,使用函数imagecopyresampled()创建出了一个效果更佳的缩略图。函数imagecopyresampled()的语法如下。
bool imagecopyresampled(resource $dst_img, resource $src_img, int $d_x, int $d_y, int $s_x, int $s_y, int $d_w, int $d_h, int $s_w, int $s_h)
该函数各参数的意义和函数imagecopyresized()一样,这里不再赘述。
19.3.5 对图片加文字效果
除了给图片加水印外,给图片加文字也是很常用到的功能。是否有一张图片很希望加自己的个性签名上去呢?还有看到很多广告说可以给你设计签名的,其实掌握了这节内容以后,也许自己也可以做一个。
对图片添加文字,可用imagettftext()函数,使用语法如下。
array imagettftext ( resource image, float size, float angle, int x, int y, int color, string fontfile, string text )
imagettftext()使用TrueType字体向图像写入文本。需要对其提供8个输入参数,它们分别代表的意义如下。
·image:图像资源。
·size:字体大小。根据GD版本不同,应该以像素大小指定(GD1)或点大小(GD2)。
·angle:角度制表示的角度,0°为从左向右读的文本,更高数值表示逆时针旋转。例如90°表示从下向上读的文本。
·x:由x、y所表示的坐标定义了第一个字符的基本点(大概是字符的左下角)。这和imagestring()不同,其x、y定义了第一个字符的左上角。例如top left为0,0。
·y:Y坐标。它设定了字体基线的位置,不是字符的最底端。
·color:颜色索引。使用负的颜色索引值具有关闭防锯齿的效果。
·fontfile:想要使用的TrueType字体的路径。
·text:文本字符串。
因为有时候需要使用中文文字,而这个函数接受的文本字符串需要UTF-8格式编码。所以如果输入的字符串是中文,需要用UTF-8对其先进行编码转换。这里介绍一个在编码转换时很常用的函数mb_convert_encoding()函数,使用语法如下。
string mb_convert_encoding ( string str, string to_encoding [, mixed from_encoding] )
mb_convert_encoding()函数接受3个参数,把输入的str字符从from_encoding编码转换到to_encoding编码。当第3个参数省略时,会被自动设定为PHP文件的编码。
技巧 当不确定需要转换的字符串是什么格式的时候,可以设定from_encoding为定多个字符集,使用逗号隔开,如“UTF8,GBK,GB2312”。
代码19-12是给图片加文字的一个示例。
代码19-12 生成带有底纹的数字验证码图片19-12.php
01 <?php
02 $image = imagecreatefromjpeg("images/green.jpg"); //
从JPEG
文件新建一图像
03 $pink = ImageColorAllocate($image, 255, 255, 255);
04 $font_file = "C:\WINDOWS\Fonts\msyhbd.ttf";// $fontfile
字体的路径,
视操作系统而定,
可以
05
是 simhei.ttf(
黑体)
、SIMKAI.TTF(
楷体)
、SIMFANG.TTF(
仿宋)
、SIMSUN.TTC(
宋体&
新宋体)
等 GD
支持的06
中文字体
07 $str = "
我喜欢PHP
!^^";
08 $str = mb_convert_encoding($str, "UTF-8", "GBK"); //
字符转码
09 imagettftext($image, 25, 10, 140, 240, $pink, $font_file, $str); //
设置文字颜色
10 imagejpeg($image, "images/green_ttf.jpg", 100); //
将带有水印的图像保存到文件
11 imagedestroy($image); //
清除占用的内存
12 ?>
13 <b>
使用PHP
给图片加文字</b><hr />
14 <table>
15 <tr>
16 <td>
原图:</td>
17 <td>
加文字后的图片:</td>
18 </tr>
19 <tr>
20 <td><img src="images/green.jpg" /></td>
21 <td><img src="images/green_ttf.jpg" /></td>
22 </tr>
23 </table>
【代码解析】以上代码首先使用imagecreatefromjpeg()函数将图片载入,然后使用imagettftext()函数将需要写入的字符串画到底图上。图19-15所示是代码运行后的效果。

图19-15 给图片加文字
上一篇:19.2图像的建立
