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 给图片加文字
共有条评论 网友评论