web网站最让人头疼的是图片缩略图的管理, 需求的变化多端让图片的设计显得非常笨拙. 如列表缩略图可能是240px, 而首页缩略图则是650px, 还有其它地方展示480px, 图片如何显示才好, 如何缩略才好呢?
理论上讲, web网站架构是100%的相对尺寸, 但图片无法做成这种计算方式, 400x200的图片, 100%那就惨不忍睹了. 假如要一张图片缩略成400宽度, 那理论上讲高度其实也是需要定义, 或者是60%于宽度的算法.主要是我们在网页上是无法欣赏缩略图高度比宽度大. 如200X800这种缩略图尺寸, 适合的场景就极少了.
本人开发phpnew blog程序, 属于展示型程序, 对图文展示效果有很高的要求. 可以参考os688.com演示站. 其中首页的缩略图固定了宽度为650px, 高度设置了强制小于, 永远不会超过650px, 里面还有比例换算等考虑. 其中列表页上有两种尺寸缩略图. 基本上做了一个折中的办法.
以下是程序用到的php缩略图函数. 显示效果非常给力. 大家可以测试一下.
function fun_index_resize($src_file, $dst_file, $new_width=0, $new_height=0){
if (!is_file($src_file)) {return false;}
// 图像类型
$type = exif_imagetype($src_file);
$support_type = array(
IMAGETYPE_JPEG,
IMAGETYPE_PNG,
IMAGETYPE_GIF);
if (!in_array($type, $support_type, true)){return false;}
//Load image
switch ($type) {
case IMAGETYPE_JPEG:
$src_img = imagecreatefromjpeg($src_file);
break;
case IMAGETYPE_PNG:
$src_img = imagecreatefrompng($src_file);
break;
case IMAGETYPE_GIF:
$src_img = imagecreatefromgif($src_file);
break;
default:
return false;
exit();
}
$w = imagesx($src_img);
$h = imagesy($src_img);
$ratio = 1;
# 自动计算缩略图尺寸.
if(!$new_height){
$newh = 1;
$new_height = ($new_width * $h) / $w;
}
if(!$new_width)
$new_width = ($new_height * $w) / $h;
$ratios = sprintf('%0.2f',$w/$h);
if($newh && ($new_height / $new_width) >= $ratios){
$new_height = min($new_width*0.45, $new_width * $ratios);
}
$ratio_w = $ratio * $new_width / $w;
$ratio_h = $ratio * $new_height / $h;
$ratio = $ratio;
$spnMatrix = array( array(-1,-1,-1,),
array(-1,16,-1,),
array(-1,-1,-1));
$divisor = 8;
$offset = 0;
// 生成的图像的高宽比原来的都小,或都大 ,原则是 取大比例放大,取大比例缩小(缩小的比例就比较小了)
if (($ratio_w < 1 && $ratio_h < 1) || ($ratio_w > 1 && $ratio_h > 1)) {
if ($ratio_w < $ratio_h) {
$ratio = $ratio_h; // 情况一,宽度的比例比高度方向的小,按照高度的比例标准来裁剪或放大
} else {
$ratio = $ratio_w;
}
// 定义一个中间的临时图像,该图像的宽高比 正好满足目标要求
$inter_w = (int)($new_width / $ratio);
$inter_h = (int)($new_height / $ratio);
$inter_img = imagecreatetruecolor($inter_w, $inter_h);
imagecopy($inter_img, $src_img, 0, 0, 0, 0, $inter_w, $inter_h);
// 生成一个以最大边长度为大小的是目标图像$ratio比例的临时图像
// 定义一个新的图像
$new_img = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($new_img, $inter_img, 0, 0, 0, 0, $new_width, $new_height, $inter_w, $inter_h);
imageconvolution($new_img, $spnMatrix, $divisor, $offset);
switch ($type) {
case IMAGETYPE_JPEG:
imagejpeg($new_img, $dst_file, 100); // 存储图像
break;
case IMAGETYPE_PNG:
imagepng($new_img, $dst_file, 9);
break;
case IMAGETYPE_GIF:
imagegif($new_img, $dst_file);
break;
default:
return false;
exit();
}
}else{
$ratio = $ratio_h > $ratio_w ? $ratio_h : $ratio_w; //取比例大的那个值
// 定义一个中间的大图像,该图像的高或宽和目标图像相等,然后对原图放大
$inter_w = (int)($w * $ratio);
$inter_h = (int)($h * $ratio);
$inter_img = imagecreatetruecolor($inter_w, $inter_h);
//将原图缩放比例后裁剪
imagecopyresampled($inter_img, $src_img, 0, 0, 0, 0, $inter_w, $inter_h, $w, $h);
// 定义一个新的图像
$new_img = imagecreatetruecolor($new_width, $new_height);
imagecopy($new_img, $inter_img, 0, 0, 0, 0, $new_width, $new_height);
imageconvolution($new_img, $spnMatrix, $divisor, $offset);
switch ($type) {
case IMAGETYPE_JPEG:
imagejpeg($new_img, $dst_file, 100); // 存储图像
break;
case IMAGETYPE_PNG:
imagepng($new_img, $dst_file, 9);
break;
case IMAGETYPE_GIF:
imagegif($new_img, $dst_file,100);
break;
default:
return false;
exit();
}
}
return $dst_file;
} 目前缩略图工作在首页点击时执行, 这有点损失性能, 压力很大. 结合实际情况, 个人觉得在发表主题时, 就把缩略图都处理好是最省心的.