Na continuação desta posta, venho agora falar-vos de sombras.
O Imagick tem uma instrução própria para gerar sombras, shadowImage
, que aceita quatro parâmetros: opacidade, sigma, x e y. Uma das vantagens mais fascinantes é que, se a imagem passada tiver transparência, a sombra segue o contorno da mesma. Ideal para usar com botões, ícones…
No entanto, a instrução tem várias armadilhas. Logo a abrir, a instrução não aplica a sombra à imagem, gera uma sombra isolada a partir da imagem, o que nos obriga, logo à partida, a uma composição posterior:
// criar um novo objecto Imagick para a sombra, // que é um clone da imagem original $sombra = $img->clone(); // como vamos sombrear, precisamos definir qual é // a cor da sombra, via cor de fundo da imagem // esta função aceita as cores de várias maneiras: // "black", "#000000", "rgb(0, 0, 0)" ou "cmyk(0, 0, 0, 100)" $sombra->setImageBackgroundColor("black"); // finalmente, vamos aplicar a sombra // opacidade: 60%; sigma: 2; posição: 5, 5 $sombra->shadowImage(60, 2, 5, 5); // neste momento já temos a sombra, vamos compor // a imagem original por cima $sombra->compositeImage($img, Imagick::COMPOSITE_OVER, 0, 0);
Não esquecer que o sombreado irá gerar imagens com transparência parcial, pelo que que as técnicas discutidas nos cantos arredondados – conversão para PNG ou composição sobre um fundo sem transparência – devem ser aplicadas.
Outra armadilha é o valor do sigma: à primeira vista, pode parecer que é o esborratamento da sombra, algo como shadow blur dos pacotes de edição de imagem, mas, ao brincar com o parâmetro, chegamos à conclusão que é isso, mas não só. Veremos, também, que os valores de x e y acabam por ser completamente descartados. Em teoria, estes valores posicionam a sombra; na prática, ao fazer a composição da imagem original, o eixo referencial é perdido, e a sombra acaba por ir dar sempre ao mesmo lado. Vejam o que mudaria com as seguintes instruções:
// alteração do sigma - comparem com o original $sombra->shadowImage(60, 20, 5, 5); // alteração de x - teoricamente, a imagem ficaria com // muito mais sombra à direita do que por baixo $sombra->shadowImage(60, 20, 50, 5);
Na prática, mudar o x e o y não resulta em alterações visíveis e o valor do sigma altera tanto o esborratamento, que era o pretendido, como o posicionamento da sombra, e consequente tamanho final da imagem. Além disso, como é fácil de verificar, é impossível gerar sombras noutras posições que não a sudeste que estamos a ver em todas as imagens. O que é necessário é descartar os valores de x e y na geração da sombra, e usá-los depois na composição, para situar a sombra onde queremos. Será possível, inclusivamente, simular um halo com o sombreado.
// valores iniciais $opacidade = 60; $sigma = 4; $x = 10; $y = 10; // criar a sombra como clone $sombra = $img->clone(); // definir a cor de fundo $sombra->setImageBackgroundColor("black"); // gerar a sombra, com x e y a zeros $sombra->shadowImage($opacidade, $sigma, 0, 0); // criar uma nova imagem para compor tudo $resultado = new imagick(); // definir o tamanho da nova imagem a partir do // tamanho da sombra mais o posicionamento da sombra // que é pedido $resultado->newImage($shadow->getImageWidth() + $x, $shadow->getImageHeight() + $y, 'transparent' ); // Compor a sombra // As contas do posicionamento em x e y referem-se à posição // que queremos que a sombra tenha // Isto é, se queremos a sombra a sair 10 pixels abaixo e à // esquerda, temos que mover a sombra 10 pixels e compensar // o valor do sigma - reparem que, se o deslocamento for // negativo, a sombra fica na origem (quem mexe é a imagem // original abaixo) $resultado->compositeImage($shadow, Imagick::COMPOSITE_OVER, (($x < 0) ? 0 : $x) - $sigma * 2, (($y < 0) ? 0 : $y) - $sigma * 2 ); // finalmente, vamos compor a imagem original, precisamente // com o mesmo género de contas, mas ao contrário - reparem // que as verificações do deslocamento são as inversas do // que foi feito para a sombra $resultado->compositeImage($img, Imagick::COMPOSITE_OVER, (($x > 0) ? 0 : -$x) + $sigma * 2, (($y > 0) ? 0 : -$y) + $sigma * 2 );
Um exemplo com a sombra noutra posição:
// valores iniciais $opacidade = 60; $sigma = 4; $x = -10; $y = 10;
Para fazer um halo, basta que o deslocamento seja 0, 0:
// valores iniciais $opacidade = 60; $sigma = 4; // aumentei o sigma para se ver melhor o halo $x = 0; $y = 0; // também mudei a cor para "darkred"