php自定义获取图片不同尺寸
以图片的中心为基准,按照任意尺寸自动调整大小并截取出规定的素材,保存为缩略图或以php形式输出为图片
这个类库可以在比例不失真的前提下,让图片按照期望的宽和高来显示,多余的部分自动被裁切掉。当然,如果你能够提供存储路径,该类库可以将生成的图片按该路径保存下来(以jpeg格式保存)。
经过这样处理后的图像可以有统一的尺寸,您可以将图片尺寸与容器尺寸保持一致。这样一来不会因为图片宽高比与容器宽高比不符而出现的空白区域。
举例说明吧,为了增加阅读友好度,此处不得不上点美图了。题外话,现在百度图片的尺度好大,我选一张比较正常的!
例如你期望的图片容器尺寸为w300×h319,而你的图片素材尺寸为w254×h330,现在想把这个图片放到容器中,此时的显示效果是怎样?
我们先看一下做法A:将素材的高度减小至h319,那么它的宽度此时为w246,通过css控制水平居中后显示如图:
此时图片两侧有白边。在用户体验被逐渐重视的今天,这种视觉效果可以说不是很友好。如果这是一组美女还好,但是在一些商业网站,例如产品展示的画廊中,这种显示效果就很不理想了。
再看做法B:
我们将素材的宽度调整为容器的宽度w300,此时素材高度为h389。在现阶段的大部分浏览器环境中,不是用javascript和css hack的前提下,显示效果为
请注意,上图边框以外的素材部分都将会被隐藏。仍以商业网站举例,很多时候,一个产品图片的素材,其重点在图片中心附近。因此做法B的显示效果会存在一个隐患,就是当图片高度较大时,图片重心会下移到底部甚至超过图片容器。以上图为例,大腿没了,你看到的只有上半身了。对于这种问题,解决的办法就是通过css与javascript结合来使图片居中于容器。这样做的前提是需要获取图片的尺寸,如果等图片载入完毕再去获取尺寸并调整的话,在这个等待过程中,显示效果很不理想。好在js可以先隐藏图片,等待图片下载完毕后再调整位置并使其显示。另有些人将尺寸存于数据库中,前端可以通过读取尺寸并在生成页面时进行定位处理。
我们最终要达到的效果是这样的:
在这组容器尺寸和素材中,这种显示效果可以说是最好的,有胸有腿还有小脸蛋。整张构图基本保持原样。
但是上述做法麻烦吗?对于后端来说,需要将图片尺寸存于数据库中。对于前端,需要遍历找到需要重新设置的图片素材,调整位置并控制显隐。对于用户,如果图片很大,那么载入时间就会更长,而当前我们可能仅仅需要的是缩略图。
我也常常被这些问题所困扰,于是发生了如下类库。你可以在执行上传图片时,顺手生成一个缩略图,这个缩略图尺寸可以由你根据情况来设定。该类库会将图片的较短边调整至容器对应边的尺寸,高度等比调整,并居中截取图片,使其按照您要求的尺寸输出,完全不用担心出现白边的情况。并且你可以自定义缩略图的存储位置以和主图存储路径区分开来。
只要是可访问的本地服务器图片,该类库也支持动态生成图片。将源图片路径及期望的宽高提供给它,就能按照要求创建新图形并以图片流返回给客户端。
调用方式也很简单:
//其他程序
$url = someurl.png;
$output_width = 300;
$output_height = 600;
$saveDir = demoPROJECT/uploads;
$image = new Fillcanvasbysize();
//如果您想保存成文件
echo $image->execute($url,$output_width,$output_height,$saveDir,_tiny);
//如果您想直接生成图片链接交给前端
<img src="<?php echo "getimage.php"."?url=".$url."&w=".$output_width."&h=".$output_width;?>">
getimage.php的代码作为接受请求的端口(访问该链接就会返回一个图片),应该这样写:
require_once(Fillcanvasbysize.php);
$url = $_SERVER[DOCUMENT_ROOT]."/uploads/".$_GET[url];
$output_width = $_GET[w];
$output_height = $_GET[h];
$image = new Fillcanvasbysize();
$image->execute($url,$output_width,$output_height);
参数如下:
$url为源文件路径,$output_width和$output_height为期望尺寸,$saveDir为保存路径(null则不保存直接返回图片),$suffix为缩略图后缀名
类库源码如下:
class Fillcanvasbysize{
public function execute( $url, $output_width=60,$output_height=60,$saveDir=false,$suffix=_thumb){
if(!file_exists($url)) {return false;}//判断远程文件@fopen( $url, r )
$img_info = getimagesize($url); //得到图像的大小
list($width, $height)=$img_info;
if( ($width / $height) >= ($output_width / $output_height) )
{
$ori_img=array(
x => ceil(($width-$height*$output_width/$output_height)/2) ,
y => 0,
w => ceil($height*$output_width/$output_height) ,
h => $height);
$op_img=array(
x => 0,
y => 0,
w => $output_width,
h => $output_height);
}
else
{
$ori_img=array(
x => 0,
y => ceil(($height-$width*$output_height/$output_width)/2),
w => $width,
h => ceil($width*$output_height/$output_width) );
$op_img=array(
x => 0,
y => 0,
w => $output_width,
h => $output_height);
}
switch($img_info[2]){ //取得图片的格式
case 1:$src=imagecreatefromgif($url);break;
case 2:$src=imagecreatefromjpeg($url);break;
case 3:$src=imagecreatefrompng($url);break;
default:return false;//未知的文件格式
}
$dst = imagecreatetruecolor($output_width, $output_height); //新建一个真彩色图像
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]); //重采样拷贝部分图像并调整大小
if($saveDir!=false){
$filename = end(explode(/ , $url));
$filename = (explode(. , $filename,-1));
$filename = implode(. , $filename);
$saveDir = $_SERVER[DOCUMENT_ROOT]."/".$saveDir."/".$filename.$suffix.".jpeg";
}else{
ob_clean(); //关键代码,防止出现图像因其本身有错无法显示的问题。
header(Content-Type: image/jpeg);
$saveDir = null;
}
imagejpeg($dst,$saveDir,100); //返回资源;保存路径;质量0-100默认75
imagedestroy($src); //销毁一图像
imagedestroy($dst);
return $saveDir;
}
}