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