最近要把項目中的圖片全部產生webp格式, 過程整理一下, (直接存在本地,或者圖片連結存在資料庫都可以看看)
首先,肯定是批量處理, 一個php處理不了這麼多, 會爆記憶體的, 個人建議用ajax迴圈調用php檔案
下面貼ajax代碼, 小白和我看看就行, 老人跳過
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>更換圖片</title> <script type="text/javascript" src="./jquery-1.8.3.min.js"></script></head><body> <button id="but01">點我就幫你轉圖片</button></body><script type="text/javascript"> var limit = 50; //每次50條 var offset = 0; //位移量,每次自增50 function toPhp(){ $.ajax({ url: "./sqlsrc.php", //幕後處理程式 type: 'POST', data: {limit: limit, offset: offset}, success:function(data) { if(data) { offset = offset + 50; toPhp(); //根據後台返回的內容,繼續調用自己 }else { alert('這裡是limit---' + limit); alert('這裡是data---' + data); alert('完成'); } }, error:function() { alert('失敗'); }, dataType:'text' }); } $("#but01").click(toPhp); // 點擊按鈕執行程式</script></html>
下面是php處理檔案, sqlsrc.php主要是處理那種圖片路徑存在資料庫裡的,
以下本人是把資料庫的圖片拉到本地同時產生webp格式/
你可以直接在項目所在的目錄運行此指令碼,
注意 sqlsrc.php中的地址要自己拼~
sqlsrc.php檔案如下
<?phpini_set ('gd.jpeg_ignore_warning', 1); //忽略set_time_limit(0);//0表示不限時$dsn='mysql:host=192.168.1.1;dbname=yourdbname';$user='root';$password='';$status=1; //看個人需要了,這個參數$data = $_POST;try { $sql='select thumbnail_pic,small_pic,big_pic from sdb_goods'; $sql .= " limit {$data['limit']} offset {$data['offset']}"; // 位移分頁查詢/ $dbh=new PDO($dsn,$user,$password); $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); $stmt=$dbh->prepare($sql); $stmt->bindParam(':status',$status); //綁定參數的範例, 喜歡參數綁定的看這裡,其他人無視這行 $stmt->execute(); $flag = false; //這裡設定一個標識,如果沒走while函數, 那麼flag依然為false while ($row=$stmt->fetch(PDO::FETCH_ASSOC)) { $flag = true; //只要有查詢到的內容, flag就會true $count = $data['count']; $ptn = "/http.*?fs_storage/"; foreach ($row as $k=>$v){ preg_match_all($ptn,$v,$res); if(empty($res[0])) { continue; } foreach ($res as $kk=>&$vv) //這層遍曆不需要, 誰可以最佳化下貼上來. { $vv[0] = rtrim($vv[0],'fs_storage');//圖片遠程路徑 $vv[0] = rtrim($vv[0],'|');//圖片遠程路徑 $ptn01 = "/http.*?\|/"; $src = preg_replace($ptn01,'',$vv[0]); //遠程路徑標準版 if(empty($src)) { continue; } //這裡擷取到表中圖片的地址, 整理成本地的地址 $ptn02 = "/.*com/"; $local = preg_replace($ptn02,'.',$src); //本地路徑 $ptn03 = "/:88/"; $local = preg_replace($ptn03,'',$local); //本地路徑+檔案名稱 $path = pathinfo($local,PATHINFO_DIRNAME); if(empty($path)) { continue; } if(!is_dir($path)) { mkdir($path,777,true); // } //下面這行會報個warning, 忘了是啥, 直接抑制掉了 @$img = file_get_contents($src); if (!$img) { continue; } file_put_contents($local,$img); //根據資料庫的地址下載圖片到本地// turnType($local); //此行代碼調用函數, 在檔案夾中產生一個同名的webp圖片; //接著應該把地址存到資料庫中 //拼接成你線上的url圖片地址,然後存到資料庫就行了 //但是沒必要,名字都是一樣的,只是尾碼不一樣 } } } echo $flag; $flag = false; //這行也是不需要的, 但是為了祭奠我的老師, 容許我放在這裡佔個位/} catch (PDOException $e) { echo 'SQL Query:'.$sql.'</br>'; echo 'Connection failed:'.$e->getMessage(); }?>sqlsrc
關於上面這個檔案,while中的代碼, 主要是正則 拼接地址,這部分可以不看, 每個人的業務都不一樣, 所以看了也白看, 直接看其他部分(gd庫函數和最後的調用函數)
我這裡是1次查50張圖片, 然後遍曆, 一張圖片一張圖片產生webp,效率非常不高///////////
pictest.php檔案如下,(上個檔案中有調用, )
單個圖片產生webp
<?php /* ** webp格式轉換函式, ** 參數為具體的圖片路徑加上檔案名稱, ** 例:D:\workspaces\upload\images\2017\demo.jpeg */function turnType($file){ if(is_file($file)) { //擷取檔案尾碼名 $ext = pathinfo($file,PATHINFO_EXTENSION);; //根據尾碼名把jpg或者png轉成webp if($ext == 'jpeg' || $ext == 'jpg' || $ext == 'png') { //產生新的檔案名稱 $newpic = rtrim($file,$ext).'webp'; if($ext == 'jpg' ) { $ext = 'jpeg'; } $funName = 'imagecreatefrom'.$ext; //拼接函數名imagecreatefromjpeg 還是 imagecreatefrompng $hImg = $funName($file); //開啟這個圖片資源, imagewebp($hImg,$newpic); //用這個圖片資源建立一個webp圖片, 存在路徑$tdir imagedestroy($hImg); //銷毀畫布資源 } }}?>單個檔案產生webp
單個檔案產生webp
以上三個代碼放在一個檔案夾中/ 主要改第二個檔案sqlsrc.php中拼接地址的部分(或者刪除) ,圖片直接在本地的...可以參考下面的代碼,
怎麼限制每次查詢的數量沒考慮, 誰有建議可以貼上來/
這裡還有直接遍曆整個目錄, 然後批量產生webp格式的代碼. 資料量小的可以參考下/;
<?php $dir = '../images'; //這裡設定目錄, 會遍曆整個目錄,然後產生一個webp格式的圖片/ 數量太大會超記憶體,有需要的可以參考imgtype($dir);//這裡調用函數//格式轉換函式function jpgturn ($sdir,$tdir,$ext){ if($ext == 'jpeg' || $ext == 'jpg') { $hImg = imagecreatefromjpeg($sdir); } if($ext == 'png' || $ext == 'PNG') { $hImg = imagecreatefrompng($sdir); } imagewebp($hImg,$tdir); imagedestroy($hImg); }// 自訂函數---擷取尾碼名;function get_extension($file){ return pathinfo($file,PATHINFO_EXTENSION);}// 遍曆目錄, 遞迴調用, 拼接新檔案名稱, 然後調用格式轉換函式function imgtype ($dir){ $dir = rtrim($dir,'/').'/'; $hd = opendir($dir); // while($hf=readdir($hd)) // { if($hf=='.'||$hf=='..') { continue; } if(is_file($dir.$hf)) { //擷取檔案尾碼名的自訂函數 $ext = get_extension($dir.$hf); //根據尾碼名把jpg轉成webp if($ext == 'jpeg' || $ext == 'jpg' || $ext == 'png' || $ext == 'PNG') { //產生新的檔案名稱 $new = rtrim($dir.$hf,$ext); $new .= 'webp'; jpgturn($dir.$hf,$new,$ext); } }if(is_dir($dir.$hf))//遞迴調用 { imgtype($dir.$hf); } }}?>