Imagens em alta resolução podem aumentar significativamente o tempo de carregamento de uma página, principalmente em galerias com dezenas de arquivos. Uma solução é gerar miniaturas WebP em PHP e carregar essas versões menores na listagem, mantendo a imagem original apenas para visualização ampliada. Neste exemplo, utilizaremos a extensão GD do PHP para redimensionar e converter automaticamente as imagens.
Por que gerar miniaturas WebP em PHP?
Imagine uma galeria contendo 50 fotografias, cada uma com aproximadamente 3 MB. Se o navegador carregar todas as imagens originais, a página poderá transferir mais de 150 MB apenas em imagens.
Mesmo quando o CSS limita visualmente uma imagem para 300 ou 400 pixels, o navegador continua baixando o arquivo original completo. Portanto, utilizar apenas width e height no HTML não resolve o problema de transferência.
A estratégia é manter dois arquivos:
- a imagem original, utilizada quando o usuário deseja ampliar a fotografia;
- uma miniatura WebP, utilizada na listagem ou galeria.
Uma estrutura possível fica assim:
uploads/
└── fotos/
└── 104/
├── foto1.jpg
├── foto2.jpg
└── mini/
├── foto1.webp
└── foto2.webp |
Dessa forma, a página inicial da galeria pode transferir arquivos muito menores, enquanto a resolução original continua disponível quando realmente necessária.
Requisitos para gerar miniaturas WebP em PHP
A implementação utiliza a extensão GD. Além disso, a instalação do PHP precisa possuir suporte à função imagewebp().
O próprio código pode verificar esses requisitos antes de tentar processar a imagem:
if (!extension_loaded('gd') || !function_exists('imagewebp')) { return false; } |
Também é possível verificar a extensão GD diretamente no PHP:
var_dump(extension_loaded('gd')); var_dump(function_exists('imagewebp')); |
Quando as duas verificações retornarem true, o ambiente possui os recursos necessários para executar a função apresentada a seguir.
Função para gerar miniaturas WebP em PHP
A função gerarMiniatura() recebe o caminho absoluto da imagem original, define uma largura máxima para a miniatura e permite controlar a qualidade do arquivo WebP.
Por padrão, a miniatura terá no máximo 600 pixels de largura e qualidade 80.
/** * Gera uma miniatura WebP ao lado da imagem enviada, na pasta "mini". * * @param string $caminhoImagem Caminho absoluto da imagem original. * @param int $larguraMaxima Largura máxima da miniatura, em pixels. * @param int $qualidade Qualidade da imagem WebP (0 a 100). * @return string|false Caminho absoluto da miniatura ou false em caso de falha. */ function gerarMiniatura(string $caminhoImagem, int $larguraMaxima = 600, int $qualidade = 80) { if ( $larguraMaxima < 1 || $qualidade < 0 || $qualidade > 100 || !is_file($caminhoImagem) || !extension_loaded('gd') || !function_exists('imagewebp') ) { return false; } $dadosImagem = @getimagesize($caminhoImagem); $conteudo = @file_get_contents($caminhoImagem); $imagemOriginal = $conteudo !== false ? @imagecreatefromstring($conteudo) : false; if ($dadosImagem === false || $imagemOriginal === false) { return false; } [$larguraOriginal, $alturaOriginal] = $dadosImagem; if ($larguraOriginal < 1 || $alturaOriginal < 1) { imagedestroy($imagemOriginal); return false; } $larguraMini = min($larguraOriginal, $larguraMaxima); $alturaMini = (int) round($alturaOriginal * ($larguraMini / $larguraOriginal)); $imagemMini = imagecreatetruecolor($larguraMini, $alturaMini); if ($imagemMini === false) { imagedestroy($imagemOriginal); return false; } imagealphablending($imagemMini, false); imagesavealpha($imagemMini, true); $pastaMini = dirname($caminhoImagem) . DIRECTORY_SEPARATOR . 'mini'; if ( !is_dir($pastaMini) && !mkdir($pastaMini, 0755, true) && !is_dir($pastaMini) ) { imagedestroy($imagemMini); imagedestroy($imagemOriginal); return false; } $nomeMiniatura = pathinfo($caminhoImagem, PATHINFO_FILENAME) . '.webp'; $caminhoMiniatura = $pastaMini . DIRECTORY_SEPARATOR . $nomeMiniatura; $redimensionada = imagecopyresampled( $imagemMini, $imagemOriginal, 0, 0, 0, 0, $larguraMini, $alturaMini, $larguraOriginal, $alturaOriginal ); $salva = $redimensionada && imagewebp( $imagemMini, $caminhoMiniatura, $qualidade ); imagedestroy($imagemMini); imagedestroy($imagemOriginal); if (!$salva) { if (is_file($caminhoMiniatura)) { unlink($caminhoMiniatura); } return false; } return $caminhoMiniatura; } |
Como a função gerarMiniatura funciona
1. Validação dos parâmetros e do ambiente
Antes de processar qualquer arquivo, a função verifica se a largura e a qualidade são válidas, se a imagem realmente existe e se o PHP possui suporte ao GD e ao WebP.
if ( $larguraMaxima < 1 || $qualidade < 0 || $qualidade > 100 || !is_file($caminhoImagem) || !extension_loaded('gd') || !function_exists('imagewebp') ) { return false; } |
Isso evita executar o restante do processamento em um ambiente incompatível ou com parâmetros incorretos.
2. Carregamento da imagem original
A função utiliza getimagesize() para identificar as dimensões do arquivo e imagecreatefromstring() para criar o recurso de imagem que será manipulado pelo GD.
$dadosImagem = @getimagesize($caminhoImagem); $conteudo = @file_get_contents($caminhoImagem); $imagemOriginal = $conteudo !== false ? @imagecreatefromstring($conteudo) : false; |
Uma vantagem dessa abordagem é não precisar selecionar manualmente uma função diferente para JPEG, PNG ou outros formatos que possam ser interpretados pela instalação do GD.
3. Cálculo proporcional da miniatura
A largura é limitada pelo parâmetro $larguraMaxima, enquanto a altura é calculada proporcionalmente.
$larguraMini = min($larguraOriginal, $larguraMaxima); $alturaMini = (int) round( $alturaOriginal * ($larguraMini / $larguraOriginal) ); |
Se uma fotografia possuir 3962 pixels de largura, por exemplo, ela poderá ser reduzida para 600 pixels sem alterar sua proporção.
O uso de min() também impede que uma imagem originalmente menor seja ampliada desnecessariamente.
4. Criação automática da pasta mini
A pasta mini é criada dentro do mesmo diretório da fotografia original.
$pastaMini = dirname($caminhoImagem) . DIRECTORY_SEPARATOR . 'mini'; if ( !is_dir($pastaMini) && !mkdir($pastaMini, 0755, true) && !is_dir($pastaMini) ) { return false; } |
Assim, uma imagem armazenada em:
uploads/fotos/104/foto1.jpg |
terá sua miniatura armazenada em:
uploads/fotos/104/mini/foto1.webp |
5. Redimensionamento com imagecopyresampled
O redimensionamento é realizado com imagecopyresampled(), utilizando as dimensões originais e as dimensões calculadas para a miniatura.
$redimensionada = imagecopyresampled( $imagemMini, $imagemOriginal, 0, 0, 0, 0, $larguraMini, $alturaMini, $larguraOriginal, $alturaOriginal ); |
O objetivo é produzir uma versão menor da fotografia preservando sua proporção.
6. Conversão para WebP
Independentemente da extensão da imagem de origem, a miniatura gerada recebe a extensão .webp.
$nomeMiniatura = pathinfo( $caminhoImagem, PATHINFO_FILENAME ) . '.webp'; |
O arquivo final é salvo com imagewebp():
$salva = $redimensionada && imagewebp( $imagemMini, $caminhoMiniatura, $qualidade ); |
O parâmetro $qualidade permite ajustar a relação entre tamanho do arquivo e qualidade visual. Neste exemplo, o valor padrão utilizado é 80.
Como chamar a função
Considerando que a aplicação conhece o caminho absoluto da imagem, basta chamar:
$caminhoMiniatura = gerarMiniatura( '/caminho/absoluto/uploads/fotos/104/foto1.jpg' ); if ($caminhoMiniatura !== false) { echo 'Miniatura criada: ' . $caminhoMiniatura; } else { echo 'Não foi possível gerar a miniatura.'; } |
Também é possível informar largura e qualidade diferentes:
$caminhoMiniatura = gerarMiniatura( '/caminho/absoluto/uploads/fotos/104/foto1.jpg', 400, 75 ); |
Nesse caso, a miniatura terá no máximo 400 pixels de largura e será salva com qualidade WebP 75.
Usando a miniatura na galeria
A principal vantagem aparece quando a página passa a utilizar o arquivo localizado em mini na listagem, deixando o arquivo original para o link de ampliação.
Conceitualmente, o HTML pode seguir esta estrutura:
<a href="uploads/fotos/104/foto1.jpg">
<img
src="uploads/fotos/104/mini/foto1.webp"
alt="Foto"
loading="lazy"
>
</a> |
Nesse exemplo, o navegador baixa inicialmente foto1.webp. Quando o usuário acessa a fotografia ampliada, a aplicação utiliza foto1.jpg.
O atributo loading="lazy" também pode ajudar em galerias extensas, pois permite adiar o carregamento de imagens que ainda estão fora da área visível da página.
Quando gerar as miniaturas
Existem duas estratégias principais. A miniatura pode ser criada imediatamente após o upload da fotografia ou pode ser gerada posteriormente por um script que percorra as imagens existentes.
Para novos uploads, gerar a miniatura no momento em que o arquivo é recebido normalmente simplifica o funcionamento da aplicação. Para um acervo que já possui centenas ou milhares de imagens, pode ser mais conveniente executar uma rotina separada para criar as miniaturas existentes.
Como validar a geração da miniatura
Após executar gerarMiniatura(), verifique primeiro se a função retornou um caminho em vez de false.
Em seguida, confirme se foi criada a pasta:
mini/ |
e se dentro dela existe o arquivo correspondente com extensão .webp.
Por exemplo:
foto1.jpg mini/ └── foto1.webp |
Também é recomendável comparar o tamanho dos dois arquivos. Em fotografias de alta resolução, a miniatura deverá possuir dimensões e tamanho em disco consideravelmente menores que o arquivo original.
Problemas comuns ao gerar miniaturas
A função sempre retorna false
Verifique inicialmente se a extensão GD está habilitada e se existe suporte ao WebP:
var_dump(extension_loaded('gd')); var_dump(function_exists('imagewebp')); |
Também confirme se o caminho informado para gerarMiniatura() é absoluto e aponta para um arquivo existente.
A pasta mini não é criada
O processo responsável pela execução do PHP precisa possuir permissão para criar a pasta dentro do diretório da imagem. A função utiliza mkdir() com permissão 0755.
Não é recomendado resolver problemas de permissão simplesmente aplicando chmod 777. O ideal é verificar proprietário, grupo e permissões adequadas ao servidor utilizado.
Imagens muito grandes consomem muita memória
Um ponto importante é que o GD precisa carregar a imagem original em memória antes de redimensioná-la. O tamanho do JPEG armazenado em disco não representa necessariamente a quantidade de memória necessária durante o processamento.
Em aplicações que recebem imagens com resoluções muito altas, é importante considerar esse consumo e os limites configurados no PHP.
Resumo prático
Gerar miniaturas WebP em PHP é uma solução simples para reduzir o volume de dados transferidos em galerias de imagens. A fotografia original permanece disponível para ampliação, enquanto a página utiliza uma versão reduzida no carregamento inicial.
A função apresentada cria automaticamente a pasta mini, mantém a proporção da fotografia, limita a largura, converte a miniatura para WebP e permite configurar a qualidade da imagem.
Para galerias com muitas fotografias em alta resolução, combinar miniaturas WebP com loading="lazy" pode reduzir significativamente o carregamento desnecessário de arquivos originais.