温馨提示: 这篇文章于2527天前编写,现在可能不再适用或落后.

jpg,png这些图片是不是很慢呢?现在浏览器很多人都是用chrome内核的浏览器了吧,既然用chrome为啥不试试把网站图片转成webp的格式呢?

这样还可以加快图片加载速度呢.webp格式目前只可以在谷歌浏览器(内核)下使用,其他浏览器并不可以.

首先怎么弄呢?如果是你用的云服务转的webp格式图片,那么可以无视这篇文章了.

这篇文章主要是针对图片存在自己网站服务器里面的,比如我....

关于转换webp格式图片有很多方法,

1,可以用php的gd库的webp转(貌似一些服务器默认都是不装的..我也没找到这个扩展)

2.使用谷歌的libwebp进行转换(推荐)

3.使用php其他扩展(反正都慢...)

4.使用手动转(这....)

首先下载libwebp,可以从官网下载也可以从一些镜像站下载.

注:linux版(windows版?没有 快滚)

下载地址:http://mirrors.bysb.net/libwebp/

下载了之后就可以安装了

tar --strip-components 1 -xzvf libwebp*.gz -C /usr/local

命令可以使用

cwebp 需要转的图片地址 -o 输出的图片地址

恩,就这样...这样就完了吗?当然没有,这要是就完了那就干脆不写了....

然后按照图片在本地的管理,难道你要一个一个的转换?没睡醒吧..

我写了一个php脚本,可以直接运行php进行转换图片

2017052522450961315

md,,水印越来越有问题了..

上图为转换完成的图片...

脚本如下(autoToWebp)

class ToWebp{
    private $rootDir = './';
    private $quality = 75;
    private $ext = ['jpg','jpeg','png','gif'];
    private $rule = [];
    private $errorList = [];
    private $runtime = 0;
    private $count = 0;
    private $success = 0;
    private $error = 0;
    private $path = "/usr/local/bin/";
    public function __construct($rootDir,$ext,$rule){
        if(!$rootDir){
            echo "\|反斜杠033[31m请设置图片文件夹反斜杠|反斜杠"{$rootDir}反斜杠|反斜杠"反斜杠|反斜杠033[0m反斜杠|反斜杠n";
            exit;
        }
        $this->rule = $rule;
        $this->rootDir = $rootDir;
        if(substr($this->rootDir,strlen($rootDir)-1)!="/")$this->rootDir.="/";
        $this->ext = $ext;
    }
    public function check(){
        if(!file_exists($this->path."cwebp")){
            echo "反斜杠|反斜杠033[31m转换工具cwebp不存在,即将开始下载....反斜杠|反斜杠033[33m反斜杠|反斜杠n";
            shell_exec("wget http://mirrors.bysb.net/libwebp/libwebp-0.6.0-linux-x86-64.tar.gz&&tar --strip-components 1 -xzvf libwebp*.gz -C /usr/local");
            if(!file_exists($this->path."cwebp")){
                throw new Exception("下载libwebp失败....");
            }    
            echo "反斜杠|反斜杠033[32m下载完成=>>>开始转换反斜杠|反斜杠033[0m反斜杠|反斜杠n";
        }
        
        foreach($this->rule as $ext=>$type){
            if(!file_exists($this->path.$type)){
                throw new Exception("转换工具:{$type}不存在");
            }
        }
    }
    public function start($quality){
        try{
            $this->quality = $quality;
            $this->runtime = microtime();
            echo "反斜杠|反斜杠033[32m================================================反斜杠|反斜杠n";
            echo "开始准备转换{$this->rootDir}目录下的所有图片为Webp反斜杠|反斜杠n";
            echo "================================================反斜杠|反斜杠033[0m反斜杠|反斜杠n";
            $this->check();
            $this->change($this->rootDir);
        }catch(Exception $e){
            echo "反斜杠|反斜杠033[31m================================================反斜杠|反斜杠n";
            echo "转换失败,耗时{$this->runtime()}!反斜杠|反斜杠n";
            echo "转换图片时发生错误:{$e->getMessage()}反斜杠|反斜杠n";
            echo "反斜杠|反斜杠033[33m总共所要转换的图片数量:{$this->count}张反斜杠|反斜杠n";
            echo "反斜杠|反斜杠033[32m成功转换为webp格式的数量:{$this->success}张反斜杠|反斜杠n";
            echo "反斜杠|反斜杠033[31m转换失败的图片数量:{$this->error}张反斜杠|反斜杠033[0m反斜杠|反斜杠n";
            foreach($this->errorList as $k=>$file)echo "反斜杠|反斜杠033[31m失败的图片".($k+1).":{$file}反斜杠|反斜杠033[32m反斜杠|反斜杠n";
            exit;
        }
    }
    private function runtime(){
        $time = $this->runtime;
        $start_date = explode(" ",$time);
        $startMs = floor(current($start_date)*1000);
        $startS = end($start_date);
        $end_date = explode(" ",microtime());
        $endMs = floor((current($end_date)*1000));
        $endS = end($end_date);
        if($startS==$endS){
            return $endMs-$startMs."ms";
        }else{
            if($startMs>$endMs){
                $endS-=1;
                $ms = $endMs+1000-$startMs;
            }else{
                $ms = $endMs-$startMs;
            }
            return $endS-$startS.".{$ms}s";
        }
    }
    private function change($root){
        if(is_null($root)||!is_dir($root))throw new Exception("文件夹目录不存在:反斜杠|反斜杠"{$root}反斜杠|反斜杠"");
        $dir = scandir($root);
        foreach($dir as $file){
            if($file!='.'&&$file!='..'){
                if(is_dir($root.$file)){
                    $this->change($root.$file."/");
                }else if(is_file($root.$file)){
                    $this->toWebp($root,$file);
                }else{
                    throw new Exception("未知文件{$root}{$file}");
                }
            }
        }
        if($this->rootDir==$root){
            echo "反斜杠|反斜杠033[32m================================================反斜杠|反斜杠n";
            echo "目录反斜杠|反斜杠033[35m{$root}反斜杠|反斜杠033[32m下的图片转换完成,总共耗时反斜杠|反斜杠033[35m{$this->runtime()}反斜杠|反斜杠033[32m!反斜杠|反斜杠n";
            echo "反斜杠|反斜杠033[33m总共所要转换的图片数量:{$this->count}张反斜杠|反斜杠n";
            echo "反斜杠|反斜杠033[32m成功转换为webp格式的数量:{$this->success}张反斜杠|反斜杠n";
            echo "反斜杠|反斜杠033[31m转换失败的图片数量:{$this->error}张反斜杠|反斜杠033[32m反斜杠|反斜杠n";
            foreach($this->errorList as $k=>$file)echo "反斜杠|反斜杠033[31m失败的图片".($k+1).":{$file}反斜杠|反斜杠033[32m反斜杠|反斜杠n";
            echo "图片全部转换为webp格式完成,请检查是否转换完成!反斜杠|反斜杠n";
            echo "自动转换脚本By:幻音丶小涛!https://www.acgxt.com反斜杠|反斜杠n";
            echo "================================================反斜杠|反斜杠033[0m反斜杠|反斜杠n";
        }
    }
    private function toWebp($path,$file){
        $fileData = pathinfo($file);
        $fileName = $fileData['filename'];
        if(isset($fileData['extension'])&&in_array($fileData['extension'],$this->ext)&&$fileData['extension']!="webp"){
            $this->count++;
            echo "反斜杠|反斜杠033[33m";
            $c = "cwebp";
            
            foreach($this->rule as $ext=>$cc){
                if($fileData['extension']==$ext){
                    $c = $cc;
                    break;
                }
            }
            shell_exec("{$c} -q {$this->quality} ".$path.$file." -o ".$path.$fileName.".webp");
            if(is_file($path.$fileName.'.webp')){
                $this->success++;
            }else{
                $this->error++;
                array_push($this->errorList,($path.$file));
            }
            echo "反斜杠|反斜杠033[0m反斜杠|反斜杠n";
        }
    }

}
//开始运行
if(substr(php_sapi_name(), 0, 3) !== 'cli')die("PHP文件必须在cli模式下运行.反斜杠|反斜杠n");
//图片根目录
$root = null;
$quality = 75;
$root = isset($argv[1])?$argv[1]:$root;
//webp质量 0-100
$quality = isset($argv[2])?$argv[2]:$quality;
//需要允许转换的图片格式,请设置libwebp允许的格式,否则可能会报错
$ext = ['jpg','jpeg','png','gif'];
//使用什么libwebp处理
//默认使用cwebp
$rule = [
    //图片格式  //使用的工具
    'gif'=>'gif2webp'
];
(new ToWebp($root,$ext,$rule))->start($quality);

有了脚本之后你可以不用去下载libwebp了,脚本会根据是否安装,自动下载libwebp

运行脚本(cli模式下运行):

sudo php autoToWebp ./upload 75  
./upload为需要转换的图片文件夹
75为图片质量

转换之后就可以成功转换了,最好在root下或sudo运行

转换了就完成了?当然没有,输出肯定还要写一个方法的....

然后先获取网站的全部生成的html内容,关于这个获取可以参考:https://www.acgxt.com/425.html通过拿缓存区的获取

然后拿到网站内容可以正则获取网站的img标签然后进行替换

function toWebp($content){
   $pre = "//i";
   if(preg_match_all($pre,$content,$m)){
      foreach($m[1] as $k=>$path){
         $content = str_replace($path,useWebp($path),$content);
      }
      return $content;
   }else{
      return $content;
   }
}
//最后输出

如果是单个域名可以用这个方法

下面的方法用于检查浏览器是否支持webp图片,并判断图片是否存在,如果你觉得麻烦,可以自己写一个

//单域名可用
function useWebp($path,$isForce=false){
   if(strpos($_SERVER['HTTP_ACCEPT'],"image/webp")===false){
      return $path;
   }else{
      $dir = ".";
      if(dirname($_SERVER['PHP_SELF'])!="/"){
         $count = count(explode("/",$_SERVER['PHP_SELF']))-2;
         for($i=0;$i<$count;$i++)$dir .= "/..";
      }
      $info = pathinfo($path);
      $dirname = $info['dirname'];
      if(substr($dirname,0,2)=="//"){
         $dirname = substr($dirname,2);
      }else if(substr($dirname,0,7)=="http://"){
         $dirname = substr($dirname,7);
      }else if(substr($dirname,0,8)=="https://"){
         $dirname = substr($dirname,8);
      }
      $domain = explode("/",$dirname);
      $domain = current($domain);
      $filepath = str_replace($domain,"",$dirname)."/";
      $file = $dir.$filepath.$info['filename'].".webp";
      if(is_file($file)){
         return $info['dirname']."/".$info['filename'].'.webp';
      }else{
         if(is_file($file)){
            return $info['dirname']."/".$info['filename'].'.webp';
         }else{
            if($isForce){
               return $info['dirname']."/".$info['filename'].'.webp';
            }else{
               return $path;
            }
         }
      }
   }
}

如果是泛域名类似我的网站这样可以用这个

//泛域名可用
function useWebp($path,$isForce=false,$isTop=false){
   if(strpos($_SERVER['HTTP_ACCEPT'],"image/webp")===false){
      return $path;
   }else{
      $dir = ".";
      if($isTop){
         $dir = ".";
      }else{
         if(dirname($_SERVER['PHP_SELF'])!="/"){
            $count = count(explode("/",$_SERVER['PHP_SELF']))-2;
            for($i=0;$i'../blog',
         'account.acgxt.com'=>'../account',
         'space.acgxt.com'=>'../space',
         'search.acgxt.com'=>'../search',
         'message.acgxt.com'=>'../message',
      ];
      $severName = $_SERVER['SERVER_NAME'];
      if(substr($dirname,0,2)=="//"){
         $dirname = substr($dirname,2);
      }else if(substr($dirname,0,7)=="http://"){
         $dirname = substr($dirname,7);
      }else if(substr($dirname,0,8)=="https://"){
         $dirname = substr($dirname,8);
      }
      $domain = explode("/",$dirname);
      $domain = current($domain);
      $filepath = str_replace($domain,"",$dirname)."/";
      $file = null;
      if(strpos($domain,$severName)===false){
         if(array_key_exists($domain,$rule)){
            $file = $rule[$domain].$filepath.$info['filename'].'.webp';
         }
      }else{
         $file = $dir.$filepath.$info['filename'].'.webp';
      }
      if(is_file($file)){
         return $info['dirname']."/".$info['filename'].'.webp';
      }else{
         if($isForce){
            return $info['dirname']."/".$info['filename'].'.webp';
         }else{
            return $path;
         }
      }
   }
}

自动转换脚本:http://dl.acgxt.com/autoToWebp

最后记得文件夹要有权限啊....

直接shell_exec调用命令转换就行了

    阁下需要登录后才可以查看评论哦~

    随便看看

      载入中...

      正在准备穿越次元,阁下请稍等片刻~