首先,為什么需要縮略圖?
以傳統的企業網站為例,一般有首頁、欄目頁和詳情頁面,對于首頁、欄目頁,調用的圖片很多,如果直接使用原圖勢必造成加載遲鈍的問題,所以,縮略圖是必須的!列表頁面調用縮略圖,詳情頁面調用原圖,這樣既不影響使用又能提升網站的響應速度。
對此,您可以在上傳圖片的時候自動生成縮略圖即可。
為什么需要不同尺寸的縮略圖?
以淘寶詳情頁面為例(類似的需求還有很多)。其中頂部大圖,有小圖、中等圖片和原圖三種形式,而事實上我們可能用到更多不同尺寸的縮略圖形式。此時,如果在上傳圖片的時候就生成多種尺寸的圖片,不是不行,缺點不少:
1、后期圖片尺寸要求發生變化,需要重新跑一遍。
2、有的圖片可能需要多種尺寸,而大部分圖片都不需要多尺寸,這時如果都生成勢必造成空間的浪費。
3、前臺需要按照后端生成的縮略圖的命名規則去調用
怎么按需生成縮略圖?
基本思路:針對圖像文件進行重定向,如果存在文件則直接返回,不存在則通過程序生成并返回。
apache的rewrite規則如下:
RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^upfiles/(.*)$ images.php?url=$1 [L]
iis的rewrite規則如下:
<rule name="picSRC"> <match url="^upfiles/(.*)$" /> <conditions logicalGrouping="MatchAny"> <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" /> <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" /> </conditions> <action type="Rewrite" url="image.php?url={R:1}" /> </rule>
php根據地址欄參數自動生成縮略圖的核心代碼:
$url = $_GET['url']; $src = './upfiles/' . preg_replace('/_(\d+)x(\d+)/', '', $url); $filename = './upfiles/' . $url; if (file_exists($filename)) { ob_start(); header('Content-type:image/jpeg'); readfile($filename); ob_flush(); flush(); } else { if(!preg_match('/_(\d+)x(\d+)/', $url, $wh)){ exit(); } $width = $wh[1]; $height = $wh[2]; thumb(realpath($src), $width, $height, $filename, 'crop', '85'); } function thumb($src, $width, $height, $filename, $mode = 'scale', $quality = '100') { try { $imageValue = getimagesize($src); //$mime=$imageValue['mime']; $sourceWidth = $imageValue[0]; //原圖寬 $sourceHeight = $imageValue[1]; //原圖高 $thumbWidth = $width; //縮略圖寬 $thumbHeight = $height; //縮略圖高 $_x = 0; $_y = 0; $w = $sourceWidth; $h = $sourceHeight; if ($mode == 'scale') { if ($sourceWidth <= $thumbWidth && $sourceHeight <= $thumbHeight) { $_x = floor(($thumbWidth - $sourceWidth) / 2); $_y = floor(($thumbHeight - $sourceHeight) / 2); $thumbWidth = $sourceWidth; $thumbHeight = $sourceHeight; } else { if ($thumbHeight * $sourceWidth > $thumbWidth * $sourceHeight) { $thumbHeight = floor($sourceHeight * $width / $sourceWidth); $_y = floor(($height - $thumbHeight) / 2); } else { $thumbWidth = floor($sourceWidth * $height / $sourceHeight); $_x = floor(($width - $thumbWidth) / 2); } } } else if ($mode == 'crop') { if ($sourceHeight < $thumbHeight) { //如果原圖尺寸小于當前尺寸 $thumbWidth = floor($thumbWidth * $sourceHeight / $thumbHeight); $thumbHeight = $sourceHeight; } if ($sourceWidth < $thumbWidth) { $thumbHeight = floor($thumbHeight * $sourceWidth / $thumbWidth); $thumbWidth = $sourceWidth; } $s1 = $sourceWidth / $sourceHeight; //原圖比例 $s2 = $width / $height; //新圖比例 if ($s1 == $s2) { } else if ($s1 > $s2) { //全高度 $y = 0; $ax = floor($sourceWidth * ($thumbHeight / $sourceHeight)); $x = ($ax - $thumbWidth) / 2; $w = $thumbWidth / ($thumbHeight / $sourceHeight); } else { //全寬度 $x = 0; $ay = floor($sourceHeight * ($thumbWidth / $sourceWidth)); //模擬原圖比例高度 $y = ($ay - $thumbHeight) / 2; $h = $thumbHeight / ($thumbWidth / $sourceWidth); } } //應該先縮放到目標尺寸再進行裁剪; switch ($imageValue[2]) { case 2: $source = imagecreatefromjpeg($src); break; case 1: $source = imagecreatefromgif($src); break; case 3: $source = imagecreatefrompng($src); break; case 6: $source = imagecreatefromwbmp($src); break; default: break; } header("Content-type: image/jpeg"); $thumb = imagecreatetruecolor($width, $height); imagefill($thumb, 0, 0, imagecolorallocate($thumb, 255, 255, 255)); imagecopyresampled($thumb, $source, 0, 0, $x, $y, $width, $height, $w, $h); imagejpeg($thumb, null, $quality); // if ($_SERVER['HTTP_REFERER'] || false !== stripos($_SERVER['HTTP_REFERER'], 'http://' . $_SERVER['SERVER_NAME'])) { imagejpeg($thumb, $filename, $quality); // } imagedestroy($thumb); imagedestroy($source); } catch (Exception $ex) { //defulat(); }
php根據地址欄參數自動生成縮略圖的調用方法:
<img src="/upfiles/xxx/demo_400x400.jpg" /> <img src="/upfiles/xxx/demo_400x300.jpg" /> <img src="/upfiles/xxx/demo_200x160.jpg" />
© 致遠 2021-05-07,原創內容,轉載請注明出錯:php根據地址欄參數自動生成縮略圖