上传图片是一个比较常见的功能,但是在输出上传图片时可能会遇到一些问题,由于上传图片的大小没有固定,从而导致图片在输出时变形。如果在上传图片时直接将其生成一个固定大小的缩略图,并同时保存上传的原始图片,那么在输出时就不会有任何问题。
本节示例将实现了这样一个功能,即在将图片上传到服务器的同时生成图片的缩略图,浏览的是图片的缩略图,而如果要查看或下载图片,则仍是原始图片。本实例的运行效果如图10.33所示.。
上传图片 预览缩微图
查看原图
图10.33 生成缩微图
【操作步骤】
第1步,创建index.php文件,设计一个上传图片的表单。
<form action="index_ok.php" method="post" enctype="multipart/form-data" name="form1"> <h3>请选择要上传的图片:</h3> <p><input name="picture[]" type="file" id="picture[]" size="30"></p> <p><input name="picture[]" type="file" id="picture[]" size="30"></p> <p><input name="picture[]" type="file" id="picture[]" size="30"></p> <p><input name="picture[]" type="file" id="picture[]" size="30"></p> <p><input type="reset" name="reset" value="重 置"> <input type="submit" name="submit" value="上 传"></p> </form>
第2步,在index.php文件内编写PHP脚本,设计如果获取到查询字符串信息,则在当前页面预览缩微图,否则仅显示图片上传的表单。
<?php if (!empty($_GET['thumbnail'])){ echo "<h2>上传图片预览</h2>"; $arr = explode('%', $_GET['thumbnail']); foreach ($arr as $val) { $src = substr($val,10); echo "<a href='original/$src' title='查看大图'><img class='thumbnail' src='$val'></a>"; } echo '<p><a href="index.php">继续上传</a></p>'; }else{ ?>
在上面代码中,使用$_GET获取查询字符串中'thumbnail'参数,URL字符串格式如下所示:
http://localhost/index.php?thumbnail=thumbnail/14880761060.jpg%thumbnail/14880761071.jpg%thumbnail/14880761072.jpg%thumbnail/14880761073.jpg
然后使用字符串操作函数explode()把'thumbnail'参数值以'%'为分隔符劈开为数组,然后使用 foreach语句读取每个缩微图的src信息,并以图片的形式显示在页面中。最后,为每个缩微图绑定超链接,单击时将显示原始大图。
第3步,创建index_ok.php文件,用于图片上传的后期处理。
<?php header ( "Content-type: text/html; charset=UTF-8" ); //设置文件编码格式 include "thumbnail.php"; if (!empty( $_FILES ["picture"]) ) { $data = date ( "Y-m-d H:m:s" ); function check($var) { //验证数组的返回值是否为空 return ($var != ""); } $array = array_filter ( $_FILES ["picture"] ["name"], "check" ); //去除数组中空值 $temp = ""; foreach ( $array as $key => $value ) { //循环读取数组中数据 $types = strtolower ( strstr ( $value, '.' ) ); //截取上传文件的后缀 if ($types == ".jpg" || $types == ".gif" || $types == ".png") { //判断上传文件的后缀是否符合要求 $thumbnail = 'thumbnail/'; $original = 'original/'; $file_name = time () . $key . strtolower ( strstr ( $value, "." ) ); //定义上传文件名称 $path = $original . $file_name; //定义原始文件的存储位置 $path_thumbnail = $thumbnail . $file_name; //定义缩略图的存储位置 $temp = $temp."$path_thumbnail%"; move_uploaded_file ( $_FILES ["picture"] ["tmp_name"] [$key], $path ); //执行上传操作 //生成缩略图 makethumb( $path, $path_thumbnail, "200", "200", "100", "www.mysite.com" ); } else { echo "上传文件" . $value . "类型不正确!"; } } $newtemp = "thumbnail=".substr($temp,0,strlen($temp)-1); echo "<script>alert('图片上传成功'); window.location.href='index.php?$newtemp';</script>"; } ?>
在上传文件的处理页index ok.php中,包含了一个thumbnail.php文件;重新定义上传文件的类型,并重新指定上传文件的存储位置,定义原始文件存储文件夹和缩略图存储文件夹;在通过move_uploaded_file()函数完成文件的上传操作后,调用thumbnail.php文件中包含的方法makethumb()将上传的图片生成缩略图,并添加文字水印。
图片上传成功之后,返回index.php页面,并以查询字符串的形式把所有缩微图信息传递给该文件。
第4步,创建thumbnail.php文件,定义makethumb()方法,完成缩略图的生成和水印的添加操作。自定义方法makethumb()的方法如下所示:
makethumb($srcFile, $dstFile, $dstW, $dstH, $rate = 100, $markwords = null, $markimage = null)
参数说明如下:
- $srcFile:图片文件名。
- $dstFile:另存文件名。
- $dstW:图片保存宽度。
- $dstH:图片保存高度。
- $rate:图片保存品质,默认值为100。
- $markwords:水印文字。
- $markimage:水印图片。
该文件的完整代码如下所示:
<?php function makethumb($srcFile, $dstFile, $dstW, $dstH, $rate = 100, $markwords = null, $markimage = null) { $data = GetImageSize ( $srcFile ); //获取上传图片的大小 switch ($data [2]) { //判断上传图片的类型 case 1 : $im = @ImageCreateFromGIF ( $srcFile ); //创建对应类型的图片 break; case 2 : $im = @ImageCreateFromJPEG ( $srcFile ); //创建对应类型的图片 break; case 3 : $im = @ImageCreateFromPNG ( $srcFile ); //创建对应类型的图片 break; } if (! $im) return False; $srcW = ImageSX ( $im ); //返回上传图片的宽 $srcH = ImageSY ( $im ); //返回上传图片的高 $dstX = 0; //定义缩略图的初始宽度变量 $dstY = 0; //定义缩略图的初始高度变量 //计算新建缩略图的大小 if ($srcW * $dstH > $srcH * $dstW) { $fdstH = round ( $srcH * $dstW / $srcW ); $dstY = floor ( ($dstH - $fdstH) / 2 ); $fdstW = $dstW; } else { $fdstW = round ( $srcW * $dstH / $srcH ); $dstX = floor ( ($dstW - $fdstW) / 2 ); $fdstH = $dstH; } $img = ImageCreateTrueColor ( $dstW, $dstH ); //创建一个真彩图像 $dstX = ($dstX < 0) ? 0 : $dstX; $dstY = ($dstX < 0) ? 0 : $dstY; $dstX = ($dstX > ($dstW / 2)) ? floor ( $dstW / 2 ) : $dstX; $dstY = ($dstY > ($dstH / 2)) ? floor ( $dstH / s ) : $dstY; $white = ImageColorAllocate ( $img, 255, 255, 255 ); //定义图像颜色 $black = ImageColorAllocate ( $img, 0, 0, 0 ); //定义图像颜色 /重采样拷贝部分图像并调整大小 imagecopyresampled ( $img, $im, $dstX, $dstY, 0, 0, $fdstW, $fdstH, $srcW, $srcH ); / if ($markwords != null) { //写入文字水印,参数依次为,文字大小|偏转度|横坐标|纵坐标|文字颜色|文字类型|文字内容 ImageTTFText ( $img, 10, 0, $dstW -102 , $dstH-4, $white, "font/FZHTJW.TTF", $markwords ); } elseif ($markimage != null) { $wimage_data = GetImageSize ( $markimage ); switch ($wimage_data [2]) { case 1 : $wimage = @ImageCreateFromGIF ( $markimage ); break; case 2 : $wimage = @ImageCreateFromJPEG ( $markimage ); break; case 3 : $wimage = @ImageCreateFromPNG ( $markimage ); break; } /写入图片水印,水印图片大小默认为88*31 imagecopy ( $img, $wimage, 500, 560, 0, 0, 88, 31 ); / imagedestroy ( $wimage ); } ImageJpeg ( $img, $dstFile, $rate ); //创建jpg格式的缩略图 imagedestroy ( $im ); //销毁图像 imagedestroy ( $img ); //销毁图像 } ?>
首先,通过getimagesize()函数获取上传图片的信息,包括大小、类型等,并根据其类型,新建一个对应类型的图像。
getimagesize()函数获取指定图像的大小,语法如下所示:
array getimagesize ( string $filename [, array &$imageinfo ] )
getimagesize()函数将测定任何GIF、JPG、PNG、SWF、SWC、PSD、TIFF、BMP、IFF、JP2、JPX、JB2、JPC、XBM或WBMP 图像文件的大小并返回图像的尺寸,以及文件类型和一个可以用于普通 HTML 文件中<img>标记中的 height/width文本字符串。
如果不能访问 filename 指定的图像或者其不是有效的图像,getimagesize() 将返回 FALSE 并产生一条错误。
该函数返回值是一个具有4个单元的数组:
- 索引0:包含图像宽度的像素值。
- 索引1:包含图像高度的像素值。
- 索引2:是图像类型的标记:1 = GIF,2 = JPG,3 = PNG,4 = SWF,5 = PSD,6 = BMP,7 = TIFF(intel byte order),8 = TIFF(motorola byte order),9 = JPC,10 = JP2,11 = JPX,12 = JB2,13 = SWC,14 = IFF,15 = WBMP,16 = XBM。这些标记与 PHP 4.3.0 新加的 IMAGETYPE 常量对应。
- 索引3:是文本字符串,内容为"height="yyy" width="xxx"",可直接用于<img>标记。
然后,对上传图片的大小与指定缩略图的大小进行比较,看其是否需要创建缩略图。
接着,根据判断结果应用imagecopyresampled()函数重新生成新的图像。
imagecopyresampled()函数从原图像中采样,复制部分图像重新生成图像,语法如下所示:
bool 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 )
参数说明如下:
- dst_image:目标图象连接资源。
- src_image:源图象连接资源。
- dst_x:目标X坐标点。
- dst_y:目标Y坐标点。
- src_x:源的X坐标点。
- src_y:源的Y坐标点。
- dst_w:目标宽度。
- dst_h:目标高度。
- src_w:源图象的宽度。
- src_h:源图象的高度。
imagecopyresampled()函数将一幅图像中的一块正方形区域复制到另一个图像中,平滑地插入像素值,在减小图像大小的同时,仍然保持了极大的清晰度。
如果源图像和目标图像的宽度和高度不同,则会进行相应的图像收缩和拉伸。坐标指的是左上角。本函数可用来在同一幅图内部复制(如果dst image和src_image相同的话)区域,但如果区域交迭的话则结果不可预知。
如果成功则返回TRUE,失败则返回FALSE。
最后,为重新生成的图像添加水印,可以选择文字水印或者图像水印。
添加文字水印应用ImageTTFText()函数,如果页面使用的不是UTF-8编码,那么还要对水印文字的编码格式进行转换,因为ImageTTFText()函数只支持UTF-8编码。
添加图像水印应用imagecopy(函数,完成对图像的复制操作。