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:
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.