最近要把項目中的圖片全部生成webp格式, 過程整理一下, (直接存在本地,或者圖片鏈接存在數據庫都可以看看)
首先,肯定是批量處理, 一個php處理不了這么多, 會爆內存的, 個人建議用ajax循環調用php文件
下面貼ajax代碼, 小白和我看看就行, 老人跳過
------------------------------------------------------------------------
本文是利用ajax遞歸調用的方式循環調用php文件,
另附一篇用隊列而不是遞歸的批量處理文件的方法,
http://www.cnblogs.com/lz0925/p/7716628.html
------------------------------------------------------------------------
<!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文件如下

1 <?php 2 ini_set ('gd.jpeg_ignore_warning', 1); //忽略 3 set_time_limit(0);//0表示不限時 4 $dsn='mysql:host=192.168.1.1;dbname=yourdbname'; 5 $user='root'; 6 $password=''; 7 $status=1; //看個人需要了,這個參數 8 9 $data = $_POST; 10 11 try { 12 $sql='select thumbnail_pic,small_pic,big_pic from sdb_goods'; 13 $sql .= " limit {$data['limit']} offset {$data['offset']}"; // 偏移分頁查詢/ 14 $dbh=new PDO($dsn,$user,$password); 15 $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION); 16 $stmt=$dbh->prepare($sql); 17 $stmt->bindParam(':status',$status); //綁定參數的樣例, 喜歡參數綁定的看這里,其他人無視這行 18 $stmt->execute(); 19 20 $flag = false; //這里設置一個標識,如果沒走while函數, 那么flag依然為false 21 while ($row=$stmt->fetch(PDO::FETCH_ASSOC)) { 22 $flag = true; //只要有查詢到的內容, flag就會true 23 $count = $data['count']; 24 25 $ptn = "/http.*?fs_storage/"; 26 foreach ($row as $k=>$v){ 27 28 preg_match_all($ptn,$v,$res); 29 if(empty($res[0])) 30 { 31 continue; 32 } 33 foreach ($res as $kk=>&$vv) //這層遍歷不需要, 誰可以優化下貼上來. 34 { 35 $vv[0] = rtrim($vv[0],'fs_storage');//圖片遠程路徑 36 $vv[0] = rtrim($vv[0],'|');//圖片遠程路徑 37 $ptn01 = "/http.*?\|/"; 38 $src = preg_replace($ptn01,'',$vv[0]); //遠程路徑標准版 39 40 if(empty($src)) 41 { 42 continue; 43 } 44 45 //這里獲取到表中圖片的地址, 整理成本地的地址 46 $ptn02 = "/.*com/"; 47 $local = preg_replace($ptn02,'.',$src); //本地路徑 48 $ptn03 = "/:88/"; 49 $local = preg_replace($ptn03,'',$local); //本地路徑+文件名 50 $path = pathinfo($local,PATHINFO_DIRNAME); 51 if(empty($path)) 52 { 53 continue; 54 } 55 if(!is_dir($path)) 56 { 57 mkdir($path,777,true); // 58 } 59 60 61 //下面這行會報個warning, 忘了是啥, 直接抑制掉了 62 @$img = file_get_contents($src); 63 if (!$img) 64 { 65 continue; 66 } 67 file_put_contents($local,$img); 68 //根據數據庫的地址下載圖片到本地// 69 70 71 turnType($local); 72 //此行代碼調用函數, 在文件夾中生成一個同名的webp圖片; 73 //接着應該把地址存到數據庫中 74 //拼接成你線上的url圖片地址,然后存到數據庫就行了 75 //但是沒必要,名字都是一樣的,只是后綴不一樣 76 } 77 } 78 } 79 echo $flag; 80 $flag = false; //這行也是不需要的, 但是為了祭奠我的老師, 容許我放在這里占個位/ 81 } catch (PDOException $e) { 82 echo 'SQL Query:'.$sql.'</br>'; 83 echo 'Connection failed:'.$e->getMessage(); 84 } 85 ?>
關於上面這個文件,while中的代碼, 主要是正則 拼接地址,這部分可以不看, 每個人的業務都不一樣, 所以看了也白看, 直接看其他部分(gd庫函數和最后的調用函數)
我這里是1次查50張圖片, 然后遍歷, 一張圖片一張圖片生成webp,效率非常不高///////////
pictest.php文件如下,(上個文件中有調用, )
單個圖片生成webp

1 <?php 2 /* 3 ** webp格式轉換函數, 4 ** 參數為具體的圖片路徑加上文件名, 5 ** 例:D:\workspaces\upload\images\2017\demo.jpeg 6 */ 7 function turnType($file) 8 { 9 if(is_file($file)) 10 { 11 //獲取文件后綴名 12 $ext = pathinfo($file,PATHINFO_EXTENSION);; 13 14 //根據后綴名把jpg或者png轉成webp 15 if($ext == 'jpeg' || $ext == 'jpg' || $ext == 'png') 16 { 17 //生成新的文件名 18 $newpic = rtrim($file,$ext).'webp'; 19 20 if($ext == 'jpg' ) 21 { 22 $ext = 'jpeg'; 23 } 24 25 $funName = 'imagecreatefrom'.$ext; //拼接函數名imagecreatefromjpeg 還是 imagecreatefrompng 26 27 $hImg = $funName($file); //打開這個圖片資源, 28 29 imagewebp($hImg,$newpic); //用這個圖片資源創建一個webp圖片, 存在路徑$tdir 30 31 imagedestroy($hImg); //銷毀畫布資源 32 } 33 } 34 } 35 36 ?>
以上三個代碼放在一個文件夾中/ 主要改第二個文件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); } } } ?>
pictest.php文件