Adicionando uma marca d'água a todas as imagens do site

Um aplicativo veio do cliente, no site antigo, para atualizar todas as imagens, ou seja, para adicionar uma marca d'água com um logotipo nelas. O problema era que havia mais de 10.000 fotos e elas estavam em pastas diferentes e em pastas.


Decidimos escrever um script universal que possa ser executado no console ou diretamente no navegador e atualizar todas as imagens no site.


E assim a tarefa:


  1. As imagens estão na pasta img na raiz do site;
  2. Adicione uma marca d'água no centro da imagem;
  3. Transfira todas as fotos para a pasta img2;

No processo de solução do problema, descobriu-se que todas as imagens também têm tamanhos diferentes de 200 a 7000 pixels de largura, e a marca d'água na forma de um logotipo deve ter alguma forma.


Etapa 1. Ignorar todos os arquivos


Primeiro, você precisa descobrir com o que trabalharemos e, para isso, exibimos todos os arquivos e pastas que estão na pasta img no site.


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

E a função de ignorar todos os elementos da pasta:


 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); 

Como você pode ver na lista, a função é recursiva; como resultado do trabalho desse script, muitas linhas com caminhos absolutos para os arquivos no site aparecerão na tela.


A única coisa que não é implementada aqui é a verificação de imagens, mas não foi útil para nós.


Etapa 2. Recrie a estrutura da pasta


Como temos muitas pastas, com subpastas e até o nível 10, para a operação bem-sucedida de todas as funções de copiar e mover arquivos, precisamos de uma estrutura pronta.


Para fazer isso, determinamos o nome da pasta, é claro, e se não estiver lá, criamos:


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

Este código é inserido após: echo $ check; e, quando executado, gera uma nova estrutura de pastas no servidor, enquanto você pode executá-lo infinitamente várias vezes, não danifica a estrutura, mas cria uma pasta img2 adjacente.


Etapa 3. Adicione um logotipo às fotos


Para fazer isso, usaremos quatro funções padrão: imagecreatefrompng , imagecreatefjpg , imagecopy , imagejpeg e alguns outros tipos adicionais: imagedestroy , imagesx .


Tudo isso é uma biblioteca GD para PHP, está conectada para todos por padrão e, portanto:


 $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); //   

Assim, após 3-5 minutos do script, dependendo do número de arquivos, obtemos uma cópia de todas as imagens na pasta img2, mas o logotipo está no canto inferior direito e todas as imagens têm tamanhos diferentes. Você pode brincar com números na imagecopy, mas não haverá efeito disso. As imagens são diferentes, o que significa que a marca d'água deve ser diferente, então vamos para o estágio 4.


4ª etapa. Personalização e alinhamento do logotipo


Para fazer isso, precisamos converter o logotipo original stamp.png para o tamanho da imagem em que o colocaremos e colar exatamente no meio.
Prossiga:


 $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)); //    

Se na etapa 3, na imagecopy, usamos imagesx ($ stamp) como as dimensões da imagem inserida, aqui já usamos as dimensões do novo logotipo imagesx ($ sim).


O logotipo contém recuos de 10 pixels à esquerda e à direita e é definido respectivamente pelos números 20 e 10 no código.


Etapa 5. Adicione a função de conversão ao nosso loop:


Como o script ficaria no joelho, naturalmente pode ser simplificado e aprimorado, suas sugestões nos comentários. Mas aqui está uma versão de trabalho:


 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); 

Basta colocá-lo na pasta raiz do site, definir a pasta de origem e destino com imagens e executar se houver muitas fotos. Adicione primeiro:


 ignore_user_abort(); set_time_limit(0); 

E corra a partir do console para ver as etapas do trabalho.


É melhor fazer experiências com a inserção do logotipo e a seleção do grau de transparência na pasta de destino, para isso, na linha $ root = $ path. ”/ Add / your / path / to / folders” ou coloque o script na pasta de destino e execute a partir daí.


Usamos um logotipo da empresa padrão com 60% de transparência.


Conclusão


Quando a pasta com os novos arquivos estiver pronta, basta renomeá-la de img2 para img. Como resultado, seu site terá uma pasta com arquivos de origem que podem ser arquivados ou excluídos e uma pasta com fotos marcadas com um logotipo.


Esse script é relevante para uso em projetos nos quais as imagens de produtos ou artigos já foram carregados e não há possibilidade de instalar um script para adicionar ou não uma marca d'água.


A próxima tarefa é substituir os dados exif em todas as imagens do mesmo site. Para o que é e como é implementado, contaremos no próximo artigo.

Source: https://habr.com/ru/post/pt424693/


All Articles