在网站的所有图片上添加水印

来自旧站点上的客户端的应用程序用于更新所有图像,即在图像上添加带有徽标的水印。 问题是有超过10,000张图片,它们分别在不同的文件夹中和文件夹下。


我们决定编写一个通用脚本,该脚本可以从控制台运行,也可以直接在浏览器中运行,并更新站点上的所有图片。


任务如下:


  1. 图片位于网站根目录的img文件夹中;
  2. 在图片中心添加水印;
  3. 将所有图片传输到img2文件夹;

在解决问题的过程中,事实证明所有图片的大小也都在200到7000像素之间,并且以徽标形式的水印也完全没有问题,我们如何解决此问题:


阶段1.绕过所有文件


首先,您需要找出我们将使用的工具,为此,我们显示了站点上img文件夹中的所有文件和文件夹。


$path = $_SERVER['DOCUMENT_ROOT']; //  $root = $path."/img"; //  

以及绕过文件夹所有元素的功能:


 function find_new($dir) { $new_dir = null; $dir_files = opendir($dir); while(false !== ($file = readdir($dir_files))) { if($file != '.' && $file != '..') $new_dir[] = $dir."/".$file; } if($new_dir) foreach($new_dir as $check ) { if(is_file($check)) { echo $check . "<br>"; } elseif(is_dir($check)) find_new($check); } } find_new($root); 

从清单中可以看到,该函数是递归的,由于此脚本的工作,屏幕上会出现许多带有指向站点文件绝对路径的行。


此处唯一未实现的是检查图片,但这对我们没有用。


阶段2.重新创建文件夹结构


由于我们有很多文件夹,包括子文件夹等等,直到10级,为了成功执行复制和移动文件的所有功能,我们需要一个现成的结构。


为此,我们确定文件夹的名称,如果不存在,我们创建:


 $fileName = basename($check); //   $new = str_replace("img","img2",$check); //   $put = substr($new,0,-strlen($fileName)); //    if (!file_exists($put)) { mkdir($put, 0777, true); //  ,   } 

该代码插入到: echo $ check;之后 执行后,它将在您的服务器上生成一个新的文件夹结构,尽管您可以无限次运行它,但它不会损坏该结构,但会创建一个相邻的img2文件夹。


第3阶段。在图片中添加徽标


为此,我们将使用四个标准函数: imagecreatefrompngimagecreatefromjpegimagecopyimagejpeg和其他几个类型: imagedestroyimagesx


所有这些都是PHP的GD库,默认情况下每个人都可以连接它,因此:


 $stamp = imagecreatefrompng('stamp.png'); //,   $sx = imagesx($stamp); //  $sy = imagesy($stamp); // $im = imagecreatefromjpeg($check); //  imagecopy($im, $stamp, imagesx($im) - $sx - 10, imagesy($im) - $sy - 10, 0, 0, imagesx($stamp), imagesy($stamp)); //    imagejpeg($im, $new, 100); //  imagedestroy($im); //   

因此,在脚本执行3-5分钟后,根据文件数,我们将获得img2文件夹中所有图像的副本,但是徽标位于右下角,并且所有图片的大小均不同。 您可以在影印本中玩数字游戏,但不会有任何效果。 图片不同,这意味着水印必须不同,所以我们进入阶段4。


第四阶段。 徽标定制和对齐


为此,我们需要将原始徽标stamp.png转换为将其放置在其上的图像的大小,并准确地粘贴在其中。
继续:


 $stamp = imagecreatefrompng('stamp.png'); //,    2000*1500 $sx = imagesx($stamp); //  $sy = imagesy($stamp); // $im = imagecreatefromjpeg($check); //  ///    $w = imagesx($im) - 20; //    $koe=$sx/$w; //   $h=ceil($sy/$koe); //   //echo $sx."-".$sy." ".$w."-".$h." ".$koe."<BR>"; //   $sim = imagecreatetruecolor($w, $h); //     $transparent = imagecolorallocatealpha($sim, 0, 0, 0, 127); //    imagefill($sim, 0, 0, $transparent); //    imagesavealpha($sim, true); //    imagecopyresampled($sim,$stamp,0,0,0,0,$w,$h,$sx,$sy); //    $sim $cn = ceil((imagesy($im) - $h)/2); //     imagecopy($im, $sim, imagesx($im) - $w - 10, $cn, 0, 0, imagesx($sim), imagesy($sim)); //    

如果在imagecopy的第3阶段,我们使用imagesx($印记)作为插入图像的尺寸,那么在这里我们已经使用了新徽标imagesx($ sim)的尺寸。


徽标的左右两侧各有10个像素的缩进,分别由代码中的数字20和10设置。


步骤5.将转换函数添加到我们的循环中:


由于脚本即将出现,因此可以自然地对其进行简化和改进,您可以在注释中提出建议。 但是这是一个工作版本:


 path = $_SERVER['DOCUMENT_ROOT']; $root = $path."/img"; $stamp = imagecreatefrompng('stamp.png'); $sx = imagesx($stamp); $sy = imagesy($stamp); function find_new($dir) { global $stamp; global $sx; global $sy; $new_dir = null; $dir_files = opendir($dir); while(false !== ($file = readdir($dir_files))) { if($file != '.' && $file != '..') $new_dir[] = $dir."/".$file; } if($new_dir) foreach($new_dir as $check ) { if(is_file($check)) { $w='';$h='';$koe='';$sim=''; //echo $check . "<br>"; $im = imagecreatefromjpeg($check); ///    $w = imagesx($im) - 20; //    $koe=$sx/$w; $h=ceil($sy/$koe); //  //echo $sx."-".$sy." ".$w."-".$h." ".$koe."<BR>"; $sim = imagecreatetruecolor($w, $h); $transparent = imagecolorallocatealpha($sim, 0, 0, 0, 127); //    imagefill($sim, 0, 0, $transparent); //    imagesavealpha($sim, true); //    imagecopyresampled($sim,$stamp,0,0,0,0,$w,$h,$sx,$sy); $cn = ceil((imagesy($im) - $h)/2); //     //    imagecopy($im, $sim, imagesx($im) - $w - 10, $cn, 0, 0, imagesx($sim), imagesy($sim)); $fileName = basename($check); $put = substr($check,0,-strlen($fileName)); $put = str_replace("img","cache",$put); if (!file_exists($put)) { mkdir($put, 0777, true); } $new = str_replace("img","cache",$check); imagejpeg($im, $new, 100); imagedestroy($im); } elseif(is_dir($check)) find_new($check); } } find_new($root); 

只需将其放在站点的根文件夹中,为源和目标文件夹设置图片,然后在图片很多的情况下运行即可。 首先添加:


 ignore_user_abort(); set_time_limit(0); 

并从控制台运行以查看工作阶段。


最好在目标文件夹中完成插入徽标和选择透明度的实验,为此,在$ root = $ path行中。“ / Add / your / path / to / folder”或将脚本放入目标文件夹并从那里运行。


我们使用具有60%透明度的标准公司徽标。


结论


准备好包含新文件的文件夹后,只需将其从img2重命名为img。 因此,您的站点将具有一个包含可归档或删除的源文件的文件夹,以及一个带有标有徽标的照片的文件夹。


该脚本适用于已经上传了产品或商品图片的项目,并且无法安装脚本来添加水印或根本不添加水印。


下一个任务是替换同一站点的所有图片上的exif数据。 关于它是什么以及如何实现,我们将在下一篇文章中讲述。

Source: https://habr.com/ru/post/zh-CN424693/


All Articles