Maison  >  Article  >  développement back-end  >  Résoudre le problème de la conversion du format d'image par lots php

Résoudre le problème de la conversion du format d'image par lots php

黄舟
黄舟original
2017-10-20 09:18:402014parcourir

最近要把项目中的图片全部生成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: &#39;POST&#39;,
                data: {limit: limit, offset: offset},
                success:function(data)
                {                    if(data)
                    {
                        offset = offset + 50;
                        toPhp(); //根据后台返回的内容,继续调用自己
                    }else
                    {
                        alert(&#39;这里是limit---&#39; + limit);
                        alert(&#39;这里是data---&#39; + data);
                        alert(&#39;完成&#39;);
                    }

                },

                error:function()
                {
                    alert(&#39;失败&#39;);
                },

                dataType:&#39;text&#39;
            });
        }

    $("#but01").click(toPhp);  // 点击按钮执行程序</script>
</html>

下面是php处理文件, sqlsrc.php主要是处理那种图片路径存在数据库里的,

以下本人是把数据库的图片拉到本地同时生成webp格式/  

你可以直接在项目所在的目录运行此脚本,

注意   sqlsrc.php中的地址要自己拼~     

sqlsrc.php文件如下

<?php
ini_set (&#39;gd.jpeg_ignore_warning&#39;, 1);   //忽略
set_time_limit(0);//0表示不限时
$dsn=&#39;mysql:host=192.168.1.1;dbname=yourdbname&#39;;
$user=&#39;root&#39;;
$password=&#39;&#39;;
$status=1;  //看个人需要了,这个参数

$data = $_POST;

try {
    $sql=&#39;select thumbnail_pic,small_pic,big_pic from sdb_goods&#39;;
    $sql .= " limit {$data[&#39;limit&#39;]} offset {$data[&#39;offset&#39;]}"; //  偏移分页查询/
    $dbh=new PDO($dsn,$user,$password);
    $dbh->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
    $stmt=$dbh->prepare($sql);
    $stmt->bindParam(&#39;:status&#39;,$status);    //绑定参数的样例, 喜欢参数绑定的看这里,其他人无视这行
    $stmt->execute();
    
    $flag = false; //这里设置一个标识,如果没走while函数, 那么flag依然为false
    while ($row=$stmt->fetch(PDO::FETCH_ASSOC)) {
        $flag = true;  //只要有查询到的内容, flag就会true
        $count = $data[&#39;count&#39;];
        
        $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],&#39;fs_storage&#39;);//图片远程路径
                $vv[0] = rtrim($vv[0],&#39;|&#39;);//图片远程路径
                $ptn01 = "/http.*?\|/";
                $src = preg_replace($ptn01,&#39;&#39;,$vv[0]); //远程路径标准版
                
                if(empty($src))
                {
                    continue;
                }
                
                //这里获取到表中图片的地址, 整理成本地的地址
                $ptn02 = "/.*com/";
                $local = preg_replace($ptn02,&#39;.&#39;,$src); //本地路径
                $ptn03 = "/:88/";
                $local = preg_replace($ptn03,&#39;&#39;,$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 &#39;SQL Query:&#39;.$sql.&#39;</br>&#39;;
    echo &#39;Connection failed:&#39;.$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 == &#39;jpeg&#39; || $ext == &#39;jpg&#39; || $ext == &#39;png&#39;)
        {
            //生成新的文件名
            $newpic = rtrim($file,$ext).&#39;webp&#39;;
                        
            if($ext == &#39;jpg&#39; )
            {
                $ext = &#39;jpeg&#39;;
            }
            
            $funName = &#39;imagecreatefrom&#39;.$ext;  //拼接函数名imagecreatefromjpeg 还是 imagecreatefrompng
            
            $hImg = $funName($file); //打开这个图片资源,
            
            imagewebp($hImg,$newpic);  //用这个图片资源创建一个webp图片, 存在路径$tdir
            
            imagedestroy($hImg);     //销毁画布资源
        }
    }
}

?>

单个文件生成webp

单个文件生成webp

以上三个代码放在一个文件夹中/   主要改第二个文件sqlsrc.php中拼接地址的部分(或者删除)    ,图片直接在本地的...可以参考下面的代码,

怎么限制每次查询的数量没考虑, 谁有建议可以贴上来/

这里还有直接遍历整个目录, 然后批量生成webp格式的代码. 数据量小的可以参考下/;


<?php 

$dir = &#39;../images&#39;;   //这里设置目录, 会遍历整个目录,然后生成一个webp格式的图片/   数量太大会超内存,有需要的可以参考imgtype($dir);//这里调用函数


//格式转换函数function jpgturn ($sdir,$tdir,$ext)
{    if($ext == &#39;jpeg&#39; || $ext == &#39;jpg&#39;)
    {        $hImg = imagecreatefromjpeg($sdir);
    }    if($ext == &#39;png&#39; || $ext == &#39;PNG&#39;)
    {        $hImg = imagecreatefrompng($sdir);
    }
    imagewebp($hImg,$tdir);   
    
    imagedestroy($hImg);
    
}// 自定义函数---获取后缀名;function get_extension($file)
{    return pathinfo($file,PATHINFO_EXTENSION);
}// 遍历目录, 递归调用, 拼接新文件名, 然后调用格式转换函数function imgtype ($dir)
{    $dir = rtrim($dir,&#39;/&#39;).&#39;/&#39;;    $hd = opendir($dir);            //    
    while($hf=readdir($hd))         //    {        if($hf==&#39;.&#39;||$hf==&#39;..&#39;)
        {            continue;
        }    if(is_file($dir.$hf))
    {        //获取文件后缀名的自定义函数
        $ext = get_extension($dir.$hf);        
        //根据后缀名把jpg转成webp
        if($ext == &#39;jpeg&#39; || $ext == &#39;jpg&#39; || $ext == &#39;png&#39; || $ext == &#39;PNG&#39;)
        {            //生成新的文件名
            $new = rtrim($dir.$hf,$ext);            $new .= &#39;webp&#39;;
            jpgturn($dir.$hf,$new,$ext);
        }
        
    }if(is_dir($dir.$hf))//递归调用    {
        imgtype($dir.$hf);
    }
  }
}?>

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn