以图片的中心为基准,按照任意尺寸自动调整大小并截取出规定的素材,保存为缩略图或以php形式输出为图片

这个类库可以在比例不失真的前提下,让图片按照期望的宽和高来显示,多余的部分自动被裁切掉。当然,如果你能够提供存储路径,该类库可以将生成的图片按该路径保存下来(以jpeg格式保存)。

经过这样处理后的图像可以有统一的尺寸,您可以将图片尺寸与容器尺寸保持一致。这样一来不会因为图片宽高比与容器宽高比不符而出现的空白区域。

举例说明吧,为了增加阅读友好度,此处不得不上点美图了。题外话,现在百度图片的尺度好大,我选一张比较正常的!

例如你期望的图片容器尺寸为w300×h319,而你的图片素材尺寸为w254×h330,现在想把这个图片放到容器中,此时的显示效果是怎样?

我们先看一下做法A:将素材的高度减小至h319,那么它的宽度此时为w246,通过css控制水平居中后显示如图:

此时图片两侧有白边。在用户体验被逐渐重视的今天,这种视觉效果可以说不是很友好。如果这是一组美女还好,但是在一些商业网站,例如产品展示的画廊中,这种显示效果就很不理想了。

再看做法B:

我们将素材的宽度调整为容器的宽度w300,此时素材高度为h389。在现阶段的大部分浏览器环境中,不是用javascript和css hack的前提下,显示效果为:

请注意,上图边框以外的素材部分都将会被隐藏。仍以商业网站举例,很多时候,一个产品图片的素材,其重点在图片中心附近。因此做法B的显示效果会存在一个隐患,就是当图片高度较大时,图片重心会下移到底部甚至超过图片容器。以上图为例,大腿没了,你看到的只有上半身了。对于这种问题,解决的办法就是通过css与javascript结合来使图片居中于容器。这样做的前提是需要获取图片的尺寸,如果等图片载入完毕再去获取尺寸并调整的话,在这个等待过程中,显示效果很不理想。好在js可以先隐藏图片,等待图片下载完毕后再调整位置并使其显示。另有些人将尺寸存于数据库中,前端可以通过读取尺寸并在生成页面时进行定位处理。

我们最终要达到的效果是这样的:

在这组容器尺寸和素材中,这种显示效果可以说是最好的,有胸有腿还有小脸蛋。整张构图基本保持原样。

但是上述做法麻烦吗?对于后端来说,需要将图片尺寸存于数据库中。对于前端,需要遍历找到需要重新设置的图片素材,调整位置并控制显隐。对于用户,如果图片很大,那么载入时间就会更长,而当前我们可能仅仅需要的是缩略图。

我也常常被这些问题所困扰,于是发生了如下类库。你可以在执行上传图片时,顺手生成一个缩略图,这个缩略图尺寸可以由你根据情况来设定。该类库会将图片的较短边调整至容器对应边的尺寸,高度等比调整,并居中截取图片,使其按照您要求的尺寸输出,完全不用担心出现白边的情况。并且你可以自定义缩略图的存储位置以和主图存储路径区分开来。

只要是可访问的本地服务器图片,该类库也支持动态生成图片。将源图片路径及期望的宽高提供给它,就能按照要求创建新图形并以图片流返回给客户端。

调用方式也很简单:

 1 //其他程序
 2 $url = 'someurl.png';
 3 $output_width = 300;
 4 $output_height = 600;
 5 $saveDir = 'demoPROJECT/uploads';
 6 $image = new Fillcanvasbysize();
 7 
 8 //如果您想保存成文件
 9 echo $image->execute($url,$output_width,$output_height,$saveDir,'_tiny');
10 
11 //如果您想直接生成图片链接交给前端
12 <img src="<?php echo "getimage.php"."?url=".$url."&w=".$output_width."&h=".$output_width;?>">

getimage.php的代码作为接受请求的端口(访问该链接就会返回一个图片),应该这样写:

1 require_once('Fillcanvasbysize.php');
2 
3 $url = $_SERVER['DOCUMENT_ROOT']."/uploads/".$_GET['url'];
4 $output_width = $_GET['w'];
5 $output_height = $_GET['h'];
6 
7 $image = new Fillcanvasbysize();
8 $image->execute($url,$output_width,$output_height);

参数如下:

$url为源文件路径,$output_width和$output_height为期望尺寸,$saveDir为保存路径(null则不保存直接返回图片),$suffix为缩略图后缀名

类库源码如下:

 1 class Fillcanvasbysize{
 2     public function execute( $url, $output_width=60,$output_height=60,$saveDir=false,$suffix='_thumb'){
 3         if(!file_exists($url)) {return false;}//判断远程文件@fopen( $url, 'r' )
 4         $img_info = getimagesize($url);   //得到图像的大小
 5         list($width, $height)=$img_info;
 6         
 7         if( ($width / $height) >= ($output_width / $output_height) )
 8         {
 9             $ori_img=array(
10                 'x' => ceil(($width-$height*$output_width/$output_height)/2) ,
11                 'y' => 0,
12                 'w' => ceil($height*$output_width/$output_height) ,
13                 'h' => $height);
14             $op_img=array(
15                 'x' => 0,
16                 'y' => 0,
17                 'w' => $output_width,
18                 'h' => $output_height);
19         }
20         else
21         {
22             $ori_img=array(
23                 'x' => 0,
24                 'y' => ceil(($height-$width*$output_height/$output_width)/2),
25                 'w' => $width,
26                 'h' => ceil($width*$output_height/$output_width) );
27             $op_img=array(
28                 'x' => 0,
29                 'y' => 0,
30                 'w' => $output_width,
31                 'h' => $output_height);
32         }
33         
34         switch($img_info[2]){ //取得图片的格式
35             case 1:$src=imagecreatefromgif($url);break;
36             case 2:$src=imagecreatefromjpeg($url);break;
37             case 3:$src=imagecreatefrompng($url);break;
38             default:return false;//未知的文件格式
39         }
40         $dst = imagecreatetruecolor($output_width, $output_height); //新建一个真彩色图像
41         imagecopyresampled($dst, $src, $op_img['x'], $op_img['y'], $ori_img['x'], $ori_img['y'], $op_img['w'], $op_img['h'], $ori_img['w'], $ori_img['h']);        //重采样拷贝部分图像并调整大小
42         if($saveDir!=false){
43             $filename = end(explode('/' , $url));
44             $filename = (explode('.' , $filename,-1));
45             $filename = implode('.' , $filename);
46             $saveDir = $_SERVER['DOCUMENT_ROOT']."/".$saveDir."/".$filename.$suffix.".jpeg";
47         }else{
48             header('Content-Type: image/jpeg');
49             $saveDir = null;
50         }
51         imagejpeg($dst,$saveDir,100);
52         imagedestroy($src);
53         imagedestroy($dst);
54         return $saveDir;
55     }
56 }

 

posted @ 2013-07-12 23:33  huangpu  阅读(670)  评论(0编辑  收藏  举报