生成缩微图

课后整理 2021-1-12

上传图片是一个比较常见的功能,但是在输出上传图片时可能会遇到一些问题,由于上传图片的大小没有固定,从而导致图片在输出时变形。如果在上传图片时直接将其生成一个固定大小的缩略图,并同时保存上传的原始图片,那么在输出时就不会有任何问题。

本节示例将实现了这样一个功能,即在将图片上传到服务器的同时生成图片的缩略图,浏览的是图片的缩略图,而如果要查看或下载图片,则仍是原始图片。本实例的运行效果如图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)

参数说明如下:

该文件的完整代码如下所示:

<?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个单元的数组:

然后,对上传图片的大小与指定缩略图的大小进行比较,看其是否需要创建缩略图。

接着,根据判断结果应用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 )

参数说明如下:

imagecopyresampled()函数将一幅图像中的一块正方形区域复制到另一个图像中,平滑地插入像素值,在减小图像大小的同时,仍然保持了极大的清晰度。

如果源图像和目标图像的宽度和高度不同,则会进行相应的图像收缩和拉伸。坐标指的是左上角。本函数可用来在同一幅图内部复制(如果dst image和src_image相同的话)区域,但如果区域交迭的话则结果不可预知。

如果成功则返回TRUE,失败则返回FALSE。

最后,为重新生成的图像添加水印,可以选择文字水印或者图像水印。

添加文字水印应用ImageTTFText()函数,如果页面使用的不是UTF-8编码,那么还要对水印文字的编码格式进行转换,因为ImageTTFText()函数只支持UTF-8编码。

添加图像水印应用imagecopy(函数,完成对图像的复制操作。