Exemplos do ImageMagick -- Criação de Telas
As telas são usadas pelo ImageMagick tanto como imagem inicial para desenhar, quanto como fundos para sobrepor imagens com áreas transparentes, ou mesmo apenas como parte do processamento geral de imagens. Elas podem ser de cor sólida, ou uma faixa de cores, ou até mesmo um mosaico de uma imagem menor. Aqui vemos apenas alguns dos métodos que podem ser usados para gerar toda uma variedade de imagens de tela.
Telas de Cor Sólida
Geração Direta
Gerar uma tela de uma cor e tamanho específicos é muito simples. Basta especificar "[-size](https://imagemagick.org/command-line-options/#size)" (usando o padrão "1x1" se nenhum tamanho for dado), e então usar "canvas:" para gerar uma tela da cor dada. Se nenhuma cor for especificada, uma tela 'white' é gerada. Por exemplo... aqui gero uma tela de cor 'khaki'. |
magick -size 100x100 canvas:khaki canvas_khaki.gif
Mais comumente, um formato abreviado (e mais tradicional) de "xc:" (que significava "X Constant Image"). Isto é geralmente o que eu uso. Por exemplo, aqui está uma imagem usando a cor do X window 'wheat'. |
magick -size 100x100 xc:wheat canvas_wheat.gif
Usando alguns sofisticados Modificadores de Leitura de Imagem podemos simplesmente especificar uma imagem de tela de cor sólida como um único argumento. Esta técnica significa que você pode especificar uma imagem de tela 'xc' de um tamanho e cor específicos como um único argumento de 'imagem de entrada' para muitos scripts do ImageMagick. |
magick 'xc:Salmon[100x100!]' canvas_salmon.gif
| O '!' é necessário porque os números são valores de redimensionamento, caso contrário você não obterá o tamanho solicitado se ele não for quadrado.
---|---
Se você já criou uma tela, mas precisa de uma em cor diferente, pode substituir essa cor usando o operador "[-opaque](https://imagemagick.org/command-line-options/#opaque)". |
magick canvas_khaki.gif -fill tomato -opaque khaki canvas_tomato.gif
Você pode até pegar um único pixel de uma imagem existente e expandi-lo para o tamanho de tela desejado. Usamos "[-scale](https://imagemagick.org/command-line-options/#scale)" para um redimensionamento simples e rápido do único pixel. Aqui pegamos uma cor rosa da imagem interna "rose:". |
magick rose: -crop 1x1+40+30 +repage -scale 100x100\! canvas_rose_red.gif
Criar Imagem do mesmo tamanho
| Uma das técnicas mais básicas, ao usar o ImageMagick, é gerar uma tela do mesmo tamanho que alguma imagem existente. Isto pode ser feito convertendo essa imagem existente na tela necessária, mas preservando o tamanho original da imagem. Geralmente não é apenas o tamanho da imagem que precisa ser preservado, mas também todos os metadados da imagem. Isto em coisas como rótulos, comentários, perfis de cor, atrasos de tempo, bem como a compressão e a profundidade de salvamento. Esses metadados podem ser importantes se você quiser anotar tais informações na tela recém-esvaziada, ou se planeja sobrepor a imagem original sobre a nova tela e precisa preservar essa informação. Naturalmente, o IM fornece um grande número de maneiras de fazer isto, geralmente como efeito colateral do uso de várias operações de imagem. Apenas algumas são muito óbvias quanto ao seu uso para limpar uma imagem a uma cor sólida. À esquerda está uma imagem de teste... Não se preocupe com como eu realmente gerei esta imagem, não é importante para o exercício. Eu a projetei para conter uma variedade de cores, transparências e outras características, especificamente para dar ao IM um bom exercício quando usado. Se você estiver realmente interessado nos comandos usados para gerar esta imagem, pode olhar o script especial, "generate_test", que eu uso para criá-la. | ![]() |
|---|---|
Sobrepor uma Cor Específica
A partir do IM v6.4.2-1 você pode usar "[+level-colors](https://imagemagick.org/command-line-options/#level_colors)" com uma única cor e sem vírgulas, para definir todas as cores. |
magick test.png -alpha Opaque +level-colors Sienna color_levelc.gif
Observe o uso do operador "[-alpha](https://imagemagick.org/command-line-options/#alpha)" para definir a transparência para algo útil antes (ou depois) de a cor ser adicionada. Alternativamente, você poderia usar "-channel All" para garantir que o canal de transparência também seja definido pela operação de redefinição de cor. Outra técnica mais antiga é usar "[-colorize](https://imagemagick.org/command-line-options/#colorize)" para sobrepor a cor de preenchimento, mas com um valor totalmente opaco. Entretanto, antes do IM v6.7.9 ele não alterava o canal alfa da imagem original, então é uma boa ideia desabilitar o canal alfa primeiro, usando "[-alpha](https://imagemagick.org/command-line-options/#alpha) [Off](masking.html#alpha_off)", ou torná-lo opaco com "[-alpha](https://imagemagick.org/command-line-options/#alpha) [Opaque](masking.html#alpha_off)" mesmo que você obtivesse o mesmo resultado sem isto. |
magick test.png -alpha off -fill Chocolate -colorize 100%
color_colorize.gif
| Note que "[-alpha](https://imagemagick.org/command-line-options/#alpha) [Off](masking.html#alpha_off)" (ou o equivalente mais antigo "[-alpha off](https://imagemagick.org/command-line-options/#matte)") apenas desabilita o canal alfa. Se você o ligar On novamente depois, o canal alfa original (que foi preservado) será restaurado. Antes do IM v6.7.9 o alfa era preservado ao usar "[-colorize](https://imagemagick.org/command-line-options/#colorize)".
---|---
A partir do IM v6.4.3-0 você pode usar o operador "[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)" para definir algum ponto com a cor desejada e fazê-la espalhar-se para cobrir toda a imagem, usando praticamente qualquer método de coloração que ele fornece (veja Pontos Esparsos de Cor abaixo). |
magick test.png -alpha Off \
-sparse-color Voronoi '0,0 Peru' color_sparse.gif
Uma maneira mais geral é usar "[-draw](https://imagemagick.org/command-line-options/#draw)" para redefinir diretamente todas as cores da imagem atual para a cor "[-fill](https://imagemagick.org/command-line-options/#fill)" atual. |
magick test.png -fill Tan -draw 'color 0,0 reset' color_reset.gif
Este era o método recomendado no ImageMagick versão 5.
A principal reclamação sobre todos os métodos 'simples' acima é que nenhum simplesmente redefine a imagem para a cor "[-background](https://imagemagick.org/command-line-options/#background)" atual. O próximo conjunto de métodos faz uso da Composição Alfa para forçar vários operadores a substituir a imagem pela cor desejada. Essas técnicas de múltiplas imagens funcionam com operadores que usam "[-compose](https://imagemagick.org/command-line-options/#compose)". Por exemplo, você pode usar "[-flatten](https://imagemagick.org/command-line-options/#flatten)" (Veja o exemplo Achatar sobre o Fundo), que cria uma tela usando a cor "[-background](https://imagemagick.org/command-line-options/#background)". |
magick test.png -background Wheat \
-compose Dst -flatten color_flatten.gif
O acima usa o método de composição '[Dst](compose.html#Dst)' para ler apenas a tela de fundo e ignorar as cores dos pixels da imagem original. Se você quiser apenas pegar os metadados da imagem original (como os dados de comentário ou rótulo), mas substituir a própria imagem por uma imagem de tela de cor e tamanho específicos, então o operador "[-extent](https://imagemagick.org/command-line-options/#extent)" (Veja Extent, Ajuste Direto do Tamanho da Imagem) pode ser a melhor solução. Novamente o método de composição [Dst](compose.html#Dst)' é usado para que ele ignore os dados de pixel da imagem original, de modo a usar apenas a cor "[-background](https://imagemagick.org/command-line-options/#background)". |
magick test.png -background LemonChiffon \
-compose Dst -extent 100x100 color_extent.gif
Ou você pode usar "[-border](https://imagemagick.org/command-line-options/#border)" (Veja Adicionar uma Borda), usando "[-bordercolor](https://imagemagick.org/command-line-options/#bordercolor)" como fonte da cor. |
magick test.png -bordercolor Khaki \
-compose Dst -border 0 color_border.gif
Este último método tem a vantagem adicional de também permitir que você amplie ligeiramente a tela da imagem, em relação ao tamanho original da imagem. | O método "[-border](https://imagemagick.org/command-line-options/#border)" de gerar telas não funcionará com versões do IM anteriores à versão 6.1.4. Antes disso, o fundo gerado pelo operador "[-border](https://imagemagick.org/command-line-options/#border)" não era uma cor sólida simples, mas uma tela preta cercada pela cor da borda. Não muito útil.
---|---
Um método mais flexível (mas muito lento) de geração de telas era fornecido pelo operador "[FX, DIY Operator](transform.html#fx)". Você também precisará desligar o canal de transparência da imagem de entrada, pois por padrão "[-fx](https://imagemagick.org/command-line-options/#fx)" não toca no canal de transparência. |
magick test.png -alpha off -fx Gold color_fx_constant.gif
O operador "[-fx](https://imagemagick.org/command-line-options/#fx)" permite até que você faça um pouco de matemática de cores. Por exemplo, que tal uma cor dourada 70% mais escura... |
magick test.png -alpha off -fx "Gold*.7" color_fx_math.gif
Todos os métodos acima não apenas podem preencher usando uma cor totalmente opaca, mas também podem usar cores semitransparentes. Entretanto, é uma boa ideia garantir de antemão que a imagem tenha um canal de transparência. Aqui, por exemplo, criamos uma tela com um vermelho semitransparente. Entretanto, quando sobreposto ao fundo 'azulado' das páginas web, obtemos uma cor rosa-arroxeada esmaecida. |
magick test.png -alpha set -fill '#FF000040' -draw 'color 0,0 reset' \
color_semitrans.png
Observe também que, ao usar o operador "[-fx](https://imagemagick.org/command-line-options/#fx)" com transparência, você precisará definir "[-channel](https://imagemagick.org/command-line-options/#channel)" para modificar todos os quatro canais de cor 'RGBA'.
Esvaziar Imagem com Cor Selecionada
Esvaziar imagens usando uma cor da imagem original também é possível, embora possa ser complicado. É uma técnica útil quando você quer usar um pixel específico como 'cor de fundo'. Por exemplo, o pixel 0,0 é uma escolha comum.
Nos exemplos a seguir, selecionarei cores de vários pixels da imagem rose interna (mostrada à esquerda), enquanto esvazio a imagem. O método mais óbvio (embora lento) é simplesmente usar o "[FX, DIY Operator](transform.html#fx)" para selecionar o pixel a usar no esvaziamento de cor. |
magick rose: -fx 'p{0,0}' color_pick_fx.png
Entretanto, isto pode ser acelerado selecionando o pixel apenas uma vez. Isto pode ser feito usando a fórmula fx como argumento para Sparse Color. Pode parecer menos simples, mas é muito mais rápido. |
magick rose: -sparse-color voronoi '0,0 %[pixel:p{40,30}]'
color_pick_sparse.png
Outro método mais complexo é recortar aquele único pixel e ladrilhá-lo por toda a imagem, usando técnicas descritas em detalhe mais adiante em Ladrilhar com uma Imagem já na Memória |
magick rose: \( +clone -crop 1x1+64+22 -write MPR:pixel +delete \) \
-fill mpr:pixel -draw 'color 0,0 reset' \
color_pick_draw.png
magick rose: -set option:distort:viewport '%wx%h+0+0' \
-crop 1x1+10+25 +repage -distort SRT 0 \
color_pick_distort.png
Outras Técnicas de Tela
Há muitas outras maneiras de gerar telas de cores muito específicas, mas são bastante obscuras. Assim, sem alguns comentários pesados, pode não ser óbvio o que você está realmente fazendo quando olhar seu script do IM meses ou anos depois. Não recomendo essas técnicas, mas são úteis de conhecer se você estiver usando versões mais antigas e menos flexíveis do IM. Tela Preta-threshold", e então desligue o canal de transparência. Tradicionalmente, você pode criar uma tela preta usando "
magick test.png -threshold 100% -alpha off black_threshold.png
-level" com o mesmo argumento para ambos os pontos 'black' e 'white' terá o mesmo efeito. Fornecendo o operador "
magick test.png -level 100%,100% -alpha off black_level.png
-fx" fornece uma maneira mais óbvia de criar uma tela preta zerando todos os pixels. Entretanto, você também precisará redefinir o canal alfa para torná-lo totalmente opaco. O operador "
magick test.png -fx 0 -alpha off black_fx.png
-evaluate" disto deve ser mais rápida, particularmente em imagens maiores. Entretanto, o "
magick test.png -evaluate set 0 -alpha off black_evaluate.png
-gamma" para tornar uma imagem toda preta. Você também pode fazer uso indevido do "
magick test.png -gamma 0 -alpha off black_gamma.png
Uma maneira menos óbvia é 'posterizar' a imagem com poucos níveis de cor, resultando no uso de apenas uma cor, preto. |
magick test.png -posterize 1 -alpha off black_posterize.png
Operador Alpha Você pode garantir que a imagem esteja totalmente transparente e então 'extract' a máscara da imagem, usando o
magick test.png -alpha transparent -alpha extract black_alpha.png
Tela Branca-threshold". O valor, entretanto, deve ser um número negativo, apenas para garantir que todas as cores sejam mapeadas para branco, em todas as versões do IM. A maneira tradicional é novamente usar "
magick test.png -threshold -1 -alpha off white_threshold.png
-level" com o mesmo argumento para ambos os pontos 'black' e 'white' terá o mesmo efeito. Fornecendo o operador "
magick test.png -level -1,-1 -alpha off white_level.png
-fx". Você pode, é claro, definir os valores dos pixels diretamente usando o "
magick test.png -fx 1.0 -alpha off white_fx.png
-evaluate" disto deve ser mais rápida, particularmente em imagens maiores. Entretanto, o "
magick test.png -evaluate set 100% -alpha off white_evaluate.png
Ou negue algum outro método de geração de tela preta. |
magick test.png -posterize 1 -alpha off -negate white_posterize.png
Operador Alpha Você pode garantir que a imagem esteja totalmente opaca (sem transparência) e então 'extract' a máscara da imagem, usando o
magick test.png -alpha opaque -alpha extract white_alpha.png
Tela TransparenteProvavelmente a tela mais importante que você quer gerar a partir de uma imagem existente é uma tela transparente. Você pode então desenhar e adicionar coisas a esta tela, deixá-la do jeito que quiser, e sobrepô-la à imagem original. -alphatransparent" (adicionado no IM v6.4.3-7). A maneira mais rápida e fácil é simplesmente fazer o IM limpar a imagem diretamente para transparência, usando o operador "
magick test.png -alpha transparent trans_alpha.png
Entretanto, como esta é uma adição muito recente, provavelmente ainda não está amplamente disponível. ![[IM Output]](../static/img/canvas/trans_alpha.png)
Clear', com qualquer imagem de sobreposição (um único pixel "null:" neste caso), pois será ignorada. Podemos fazer uma tela 'black' totalmente transparente usando o operador de composição alfa '
magick test.png null: -alpha set -compose Clear -composite -compose Over \
trans_compose.png
-fill". Neste caso, torne-a totalmente transparente. Aqui usamos o operador "-draw matte" para substituir o valor do canal matte (transparência) pelo valor de transparência da configuração de cor "
magick test.png -alpha set -fill none -draw 'matte 0,0 reset'
color_matte.png
-fx" operador. Também podemos fazer isso de forma mais direta com o "
magick test.png -alpha set -channel A -fx 0 +channel trans_fx.png
-evaluate" desta operação deve ser mais rápida, particularmente em imagens maiores. Naturalmente, a versão "
magick test.png -alpha set -channel A -evaluate set 0 +channel \
trans_evaluate.png
-threshold" mas novamente limitando seus efeitos apenas ao canal de transparência. Outra forma de tornar a imagem totalmente transparente é usar "
magick test.png -channel A -threshold -1 +channel trans_threshold.png
Na verdade, neste caso estamos matematicamente lidando com um canal 'matte', usando o limiar para defini-lo como o valor máximo, em vez de zero como fizemos com o operador "-fx". É por isso que um '-1' foi usado acima, em vez de algo como 101%'. Em muitos dos resultados de imagem acima, as cores RGB originais da imagem original ainda estão presentes, apenas foram tornadas transparentes. Por exemplo, aqui lemos uma das imagens acima e pedimos ao IM que desligue o canal matte/alfa da imagem para tornar as cores visíveis novamente. |
magick trans_fx.png -alpha off trans_fx_alpha_off.jpg
Observe, no entanto, que nem todos os formatos de arquivo de imagem e muito poucas operações de imagem preservarão as cores RGB parcialmente transparentes que ainda estão presentes na imagem resultante. ![[IM Output]](../static/img/canvas/trans_fx_alpha_off.jpg)
Como mencionado antes, e vale repetir, muitos dos métodos acima dependem de a imagem já ter um canal alfa. Se não tiver, adicione um usando o "[-alpha](https://imagemagick.org/command-line-options/#alpha) [On](masking.html#alpha_on)", mas nesse caso é melhor simplesmente usar o operador "[-alpha](https://imagemagick.org/command-line-options/#alpha) Transparent". Veja os exemplos em Controlando a Transparência da Imagem. Coloração Diversa de TelaAlém de usar uma cor específica, apenas o operador "-gamma" é realmente flexível o suficiente para gerar uma tela de qualquer cor primária/secundária. Basicamente você usa 0 para zerar um canal e -1 para maximizar os valores de um canal. Por exemplo, aqui eu gero uma tela amarela... |
magick test.png -gamma -1,-1,0 -alpha off yellow_gamma.png
![[IM Output]](../static/img/canvas/yellow_gamma.png)
A partir do IM v6.4.2 você também pode usar o operador "[+level](https://imagemagick.org/command-line-options/#level)" para definir um nível de cinza específico para todos os canais de cor. |
magick test.png +level 40%,40% -alpha off grey_level.png
Gradientes de Cor
Como você viu acima, é fácil criar telas de cores sólidas. Mas às vezes você quer algo mais interessante. Um operador de criação de imagem muito útil é "gradient:". Por exemplo... |
magick -size 100x100 gradient: gradient.jpg
![[IM Output]](../static/img/canvas/gradient.jpg)
Como você pode ver, por padrão o "gradient:" criará uma imagem com branco no topo e preto na base, e um sombreamento suave de cinza ao longo da altura da imagem. Mas não precisa ser apenas um gradiente em tons de cinza; você também pode gerar um gradiente de cores diferentes especificando uma cor, ou ambas.
magick -size 100x100 gradient:blue gradient_range1.jpg
magick -size 100x100 gradient:yellow gradient_range2.jpg
magick -size 100x100 gradient:green-yellow gradient_range3.jpg
magick -size 100x100 gradient:red-blue gradient_range4.jpg
magick -size 100x100 gradient:tomato-steelblue gradient_range5.jpg
Observe que, quando dada uma única cor, a segunda cor será 'white' ou 'black', a que produzir a maior distância de cor em relação à cor dada. Assim, 'blue' produz um gradiente 'blue-white', enquanto 'yellow' gerou um gradiente 'yellow-black'. O gradiente 'red-blue' mostra uma faixa de tons de roxo bem mais escura no meio. Esse escurecimento é causado pelo espaço de cor sRGB não-linear mais escuro que está sendo usado, especialmente com cores primárias fortes. Veja Processando Imagens Reais para mais detalhes. | _"gradient:" atualmente entende apenas representações de cor do Espaço de Cor sRGB. Assim, você não pode usá-lo para gerar um gradiente 'purple' mais brilhante e mais correto usando cores 'red-blue' em um espaço de cor LAB linear.
Isso também significa que você não pode gerar gradientes 'arco-íris' multicoloridos usando o espaço de cor HSV.
No entanto, você pode 'improvisar' esses gradientes de forma relativamente simples. Veja Gradientes em outros Espaços de Cor abaixo.
---|---
| _Atualmente os gradientes não podem ser especificados em outros ângulos ou envolvendo mais de duas cores. No entanto, como essa capacidade é parte integral dos gradientes SVG, essa situação provavelmente mudará, com uma grande melhoria nas opções de gradiente.
---|---
Alguns gradientes particularmente bonitos incluem... |
magick -size 10x120 gradient:snow-navy gradient_ice-sea.jpg
magick -size 10x120 gradient:gold-firebrick gradient_burnished.jpg
magick -size 10x120 gradient:yellow-limegreen gradient_grassland.jpg
magick -size 10x120 gradient:khaki-tomato gradient_sunset.jpg
magick -size 10x120 gradient:darkcyan-snow gradient_snow_scape.jpg
![[IM Output]](../static/img/canvas/gradient_snow_scape.jpg)
| _A partir do IM v6.3.1 o algoritmo usado para gerar gradientes agora produz cores horizontalmente uniformes, de modo que todos os pixels de cada linha de uma imagem recebem a mesma cor. Ou seja, uma cor por linha.
Antes desta versão, o operador "gradient:" funcionava ignorando a largura da imagem e apenas atribuindo o próximo incremento de cor, indo linha por linha do canto superior esquerdo ao canto inferior direito da imagem.
Como resultado, o gradiente era predominantemente vertical, assim como é agora, mas não perfeito. Normalmente esse fato só era importante em casos especiais, como imagens de teste, e para uso em Mapeamento de Imagem.
_
---|---
Observe que o comportamento dos gradientes pode ser afetado por estes defines:
Gradientes Radiais
A partir do IM v6.4.4 você também pode gerar imagens de gradiente radial de forma semelhante. |
magick -size 100x100 radial-gradient: rgradient.jpg
![[IM Output]](../static/img/canvas/rgradient.jpg)
Observe que o gradiente é centralizado no meio da imagem gerada e tem um diâmetro ajustado para caber no maior entre o tamanho X ou Y da imagem. Portanto, se o tamanho da imagem não for quadrado, você obterá um gradiente radial 'cortado'. |
magick -size 100x60 radial-gradient: rgradient_clip.jpg
![[IM Output]](../static/img/canvas/rgradient_clip.jpg)
Isso permite gerar facilmente um gradiente radial quadrado do centro até um canto tornando uma borda 1.42 (raiz quadrada de 2) vezes maior e recortando-a. |
magick -size 100x142 radial-gradient: \
-gravity center -crop 100x100+0+0 rgradient_crop.jpg
![[IM Output]](../static/img/canvas/rgradient_crop.jpg)
As cores do próprio gradiente seguem as mesmas convenções do gerador de imagem linear "[gradient:](#gradient)" muito mais antigo.
magick -size 100x100 radial-gradient:blue rgradient_range1.jpg
magick -size 100x100 radial-gradient:yellow rgradient_range2.jpg
magick -size 100x100 radial-gradient:green-yellow rgradient_range3.jpg
magick -size 100x100 radial-gradient:red-blue rgradient_range4.jpg
magick -size 100x100 radial-gradient:tomato-steelblue rgradient_range5.jpg
Gradientes com Transparência
A partir do IM v6.2.9-8 o operador de criação de imagem "gradient:" (e mais tarde "radial-gradient:") entende o uso de cores transparentes e semitransparentes. |
magick -size 100x100 gradient:none-firebrick gradient_transparent.png
![[IM Output]](../static/img/canvas/gradient_transparent.png)
| _Antes do ImageMagick 6.5.4-7, gradientes envolvendo transparência total (como no último exemplo) geralmente produziam um halo preto.
O que acontecia é que o gradiente gerado ia da cor dada até a cor especial 'none' ou preto-transparente. Como resultado, as cores se sombreavam em direção a um preto semitransparente, antes de se tornarem totalmente transparentes.
A solução para esse problema era gerar um gradiente de transparência e então Colorizá-lo com a cor desejada._
---|---
|
magick -size 100x100 gradient:none-black \
-fill firebrick -colorize 100% gradient_trans_colorize.png
Gradientes por Ajuste de Histograma
Você pode criar um gradiente não-linear aplicando alguma forma de ajuste de histograma a um gradiente linear. Por exemplo, você pode usar uma função de Contraste Sigmoidal para criar um gradiente de aparência mais natural. |
magick -size 100x100 gradient: -sigmoidal-contrast 6,50% \
gradient_sigmoidal.jpg
![[IM Output]](../static/img/canvas/gradient_sigmoidal.jpg)
Esse tipo de gradiente é especialmente bom para gerar Fotos Sobrepostas, pois remove as mudanças bruscas de gradiente no início da região de sobreposição.
Gradientes com Evaluate/Function
Você também pode usar o Operador Evaluate e o Operador Function relacionado para modificar um gradiente linear simples. |
magick -size 100x100 gradient: -evaluate cos 0.5 -negate \
gradient_cosine.jpg
![[IM Output]](../static/img/canvas/gradient_cosine.jpg)
Ou vá um passo além e faça um pico parabólico suave no centro do gradiente linear. |
magick -size 100x100 gradient: -function Polynomial -4,4,0 \
gradient_peak.jpg
![[IM Output]](../static/img/canvas/gradient_peak.jpg)
Ou faixas ou um padrão ondulado... |
magick -size 100x100 gradient: -function sinusoid 4,-90 \
gradient_bands.jpg
![[IM Output]](../static/img/canvas/gradient_bands.jpg)
Ambos esses operadores intimamente relacionados permitem modificar imagens e gradientes com base em curvas senoidais, polinômios e funções matemáticas logarítmicas e de potência. Veja Funções Matemáticas do Evaluate e Function, Evaluate com Múltiplos Argumentos para mais exemplos.
Gradientes Distorcidos
Gradiente Rotacionado
Embora o método Sparse Color '[Barycentric](#barycentric)' (veja abaixo) forneça uma forma conveniente de gerar gradientes em qualquer ângulo, se o seu IM for anterior à versão 6.4.3-0 então você pode precisar usar outros métodos para gerar um gradiente diagonal ou rotacionado. Por exemplo, aumentando o tamanho da imagem do gradiente (multiplique pela raiz quadrada de 2, ou 1.42), depois rotacionando-a 45 graus e recortando a imagem para seu tamanho final, você pode criar um gradiente diagonal. |
magick -size 142x142 gradient: -rotate -45 \
-gravity center -crop 100x100+0+0 +repage \
gradient_diagonal.jpg
![[IM Output]](../static/img/canvas/gradient_diagonal.jpg)
A partir do IM v6.3.5 você tem uma forma muito mais rápida e simples de gerar um gradiente rotacionado usando uma Distorção SRT. Por exemplo, aqui está um gradiente de 100 pixels rotacionado 60 graus, em uma imagem de 100x100 pixels. |
magick -size 100x100 gradient: -distort SRT 60 gradient_srt.jpg
![[IM Output]](../static/img/canvas/gradient_srt.jpg)
Isso usa a configuração padrão Pixel Virtual, Edge para garantir que toda a imagem seja coberta pelo gradiente solicitado. Você também pode usar a configuração avançada Distort Viewport para mapear um gradiente em uma imagem maior, como para uso em Fotos Sobrepostas.
Gradientes Deformados
Mas você pode usar os mesmos métodos de distorção para fazer muito mais do que simples rotações. O gradiente também pode ser torcido... |
magick -size 100x100 gradient: -swirl 180 gradient_swirl.jpg
![[IM Output]](../static/img/canvas/gradient_swirl.jpg)
Você pode remapear o gradiente em uma forma trapezoidal. |
magick -size 100x100 gradient: -rotate -90 \
-distort Perspective '0,0 40,0 99,0 59,0 0,99 -10,99 99,99 109,99' \
gradient_trapezoid.jpg
![[IM Output]](../static/img/canvas/gradient_trapezoid.jpg)
Ou envolva o gradiente em arcos e círculos usando o Operador de Distorção Geral... |
magick -size 100x100 gradient: -distort Arc '180 0 50 0' \
gradient_arc.jpg
magick -size 100x100 gradient: -distort Arc '360 0 50 0' \
gradient_circle.jpg
![[IM Output]](../static/img/canvas/gradient_circle.jpg)
Embora o novo "[radial-gradient:](#radial-gradient)" seja provavelmente o método mais simples para gerar esses gradientes. Um gradiente muito útil, mas mais difícil de gerar, é um gradiente de ângulo polar. A forma exata desse gradiente depende de o gradiente dever ser centralizado em uma imagem de tamanho par ou de tamanho ímpar. Por exemplo, um Arc Distort pode ser usado para gerar imagens com um número par de dimensões em pixels, 76 pixels neste caso. |
magick -size 1x1000 gradient: -rotate 90 \
-distort Arc '360 -90 50 0' +repage \
-gravity center -crop 76x76+0+0 +repage gradient_angle_even.png
![[IM Output]](../static/img/canvas/gradient_angle_even.png)
O '-90' acima define o ângulo para a 'descontinuidade' onde 'zero' e 'máximo' se enrolam para o mesmo valor. O valor '50' deve ser mais que 1/2 do tamanho da imagem recortada final. Observe como usei um gradiente muito mais longo para gerar a imagem menor. Isso melhora a correção geral do resultado, especialmente à medida que a imagem fica maior. O Polar Distort intimamente relacionado também pode gerar tal gradiente, mas como ele tem controle sobre a posição exata do 'centro' da distorção você pode garantir que ele gere corretamente uma imagem de gradiente polar de tamanho ímpar em pixels. Neste caso, uma imagem de 75 pixels (raio = '36.5' ) |
magick -size 1x1000 gradient: -rotate 90 \
+distort Polar '36.5,0,.5,.5' +repage \
-transverse gradient_angle_odd.png
![[IM Output]](../static/img/canvas/gradient_angle_odd.png)
As duas últimas imagens podem parecer muito semelhantes, exceto pelo tamanho, mas o tratamento dos pixels mais centrais é ligeiramente diferente. Se você olhar com atenção verá que o último exemplo tem um pixel central cinza perfeito, enquanto o exemplo anterior não tem um único pixel central, mas quatro deles. O tamanho final da imagem foi determinado pelo valor '36.5', que é a metade dos '75' pixels desejados. Os deslocamentos '.5' são o aspecto importante para o tratamento correto do centro polar. Observe que, por padrão, a distorção coloca a descontinuidade no topo da imagem; por isso a Deformação Transverse corrige o ângulo e a localização da descontinuidade para corresponder à produzida pelo Arc Distort. Aqui está uma variante ligeiramente diferente que gera um gradiente angular, mas com uma máscara circular transparente. |
magick -size 50x1000 gradient: -rotate 90 -alpha set \
-virtual-pixel Transparent +distort Polar 49 +repage \
-transverse gradient_angle_masked.png
![[IM Output]](../static/img/canvas/gradient_angle_masked.png)
O valor '49' é o raio menos 1, pois por padrão uma distorção adiciona um buffer de anti-aliasing de 1 pixel ao redor da imagem resultante. Assim, a imagem final é 100x100 pixels.
Formas e gradientes circulares podem ser deformados para produzir alguns gradientes não-lineares interessantes. Por exemplo, arqueá-lo usando uma Distorção Wave pode gerar um gradiente de formato aproximadamente triangular. |
magick -size 100x100 radial-gradient: \
-background black -wave -28x200 -crop 100x100+0+0 +repage \
gradient_triangle.jpg
Ou um formato de ave de aparência bem estranha, gerado por distorção polar ao longo da borda superior do formato circular. |
magick -size 100x100 radial-gradient: \
+distort Polar '49' +repage \
gradient_bird.jpg
Gradientes por Composição
Também é possível modificar gradientes combinando-os por meio de diversos métodos de composição. Por exemplo, você pode usar o método de composição Modulus_Add para produzir gradientes do tipo persiana veneziana. |
magick -size 100x100 gradient: \( +clone +clone \) \
-background gray50 -compose ModulusAdd -flatten \
gradient_venetian.jpg
E até fazer isso na diagonal. |
magick -size 100x100 gradient: \( gradient: -rotate -90 \) \
\( -clone 0--1 -clone 0--1 \) \
-background gray50 -compose ModulusAdd -flatten \
gradient_vent_diag.jpg
Ou, ao mesclar dois gradientes de cores simples usando os métodos de composição por Cópia de Canal ou por Mesclagem Matemática, você pode gerar coloridos gradientes de mapa de cores bidimensionais. |
magick -size 100x100 gradient:yellow-blue \
\( gradient:black-lime -rotate -90 \) \
-compose CopyGreen -composite gradient_colormap.jpg
Gradientes em outros Espaços de Cor
Embora o gerador "gradient:" atualmente não consiga gerar gradientes diretamente em alguns outros Espaços de Cor (só são criadas imagens de gradiente sRGB não lineares), você pode transferir gradientes para um espaço de cor diferente para gerar efeitos interessantes. Por exemplo...
magick -size 30x600 xc:red -colorspace HSB \
gradient: -compose CopyRed -composite \
-colorspace RGB -rotate 90 gradient_rainbow.jpg
Isso primeiro converte uma cor altamente saturada ('red') para o espaço de cor HSL; qualquer cor saturada pode ser usada. Isso define corretamente os canais de saturação e brilho da imagem com os valores apropriados. Depois disso, um gradiente é gerado e copiado para o canal 'Hue' (equivalente ao 'red') dessa imagem no espaço de cor HSL. E, como num passe de mágica, quando convertemos a imagem HSL de volta para RGB, obtemos um gradiente de arco-íris completo de cores totalmente saturadas. Outro método é gerar um gradiente exatamente com os valores certos para um desses espaços de cor e então mudar o espaço de cor da imagem (usando "[-set](https://imagemagick.org/command-line-options/#set)"). Isso muda o espaço de cor sem alterar os valores de cor que criamos na imagem. Agora, quando convertemos de volta para RGB, obtemos o mesmo arco-íris de valores.
magick -size 30x600 gradient:'#FFF-#0FF' -rotate 90 \
-set colorspace HSB -colorspace RGB \
gradient_rainbow_2.jpg
O resultado é, na verdade, exatamente igual ao método anterior, apenas um pouco mais direto, no sentido de que geramos os valores certos para o espaço de cor desejado e então definimos o espaço de cor ao qual esses valores pertencem. Aqui tomamos o gradiente angular mascarado (veja acima) e o remapeamos para o espaço de cor HSB para gerar um matiz circular de cores. O vermelho (hue=0) é rotacionado para a direita, onde é tradicionalmente posicionado (ângulo 0 em coordenadas polares). |
magick -size 100x300 gradient:'#FFF-#0FF' -rotate 90 \
-alpha set -virtual-pixel Transparent +distort Polar 49 +repage \
-rotate 90 -set colorspace HSB -colorspace RGB \
gradient_hue_polar.png
Um exemplo semelhante ao acima é a Roda de Cores, que é gerada Combinando Imagens de Canal com um gradiente de Matiz e um de Luminosidade.
Gradiente Redimensionado
Um truque apresentado por Glenn Randers-Pehrson foi criar uma imagem bem pequena, de dois pixels de largura, e então expandi-la até o tamanho de imagem necessário usando "[-resize](https://imagemagick.org/command-line-options/#resize)". O Operador Resize tenta suavizar as imagens ampliadas, para que fiquem com melhor aparência na escala maior. É essa suavização que usamos para gerar um gradiente não linear. Por exemplo, aqui geramos a imagem pequena usando uma imagem em formato 'portable bitmap' (ou PBM) e a alimentamos ao IM para ampliação. |
echo "P1 1 2 0 1 " | \
magick - -resize 100x100\! gradient_resize.jpg
| Alguns shells, como o 'csh' e suas variantes, não lidam muito bem com o caractere '!' na configuração de geometria de redimensionamento acima -- nem mesmo entre aspas. Por isso, o caractere de barra invertida '\' pode ser necessário. Recomenda-se cautela.
---|---
O gradiente produzido não é linear, com início e fim suaves para as cores fornecidas, tornando essas cores muito mais pronunciadas do que você obteria com um gradiente normal. A função que o gradiente segue de fato depende (e é próxima) do exato Filtro de Reamostragem usado pelo redimensionamento. Uma forma simples de gerar essa imagem inicial de dois pixels é, na verdade, com o próprio gradient! Isso permite especificar as cores diretamente. É claro que isso limitará você a um gradiente vertical, a menos que você também rotacione o resultado. |
magick -size 1x2 gradient:khaki-tomato \
-resize 100x100\! gradient_resize2.jpg
Claro que você não está limitado a apenas uma dimensão com essa técnica. Aqui uso um 'portable greymap' de quatro pixels (ou formato de imagem PGM) para gerar um gradiente bidimensional. |
echo "P2 2 2 2 2 1 1 0 " | \
magick - -resize 100x100\! gradient_resize3.jpg
Como você pode ver, esse gradiente diagonal não é muito linear quando comparado ao Gradiente Rotacionado acima. | Os formatos de imagemNetwork Portable Bitmap são muito versáteis para gerar imagens a partir de scripts. É um formato que vale muito a pena conhecer como meio de gerar ou manipular dados de imagem.
---|---
Se olhar com atenção, também verá que o gradiente começa a partir do centro do pixel ampliado e não cobre a imagem inteira de borda a borda. Isso fica mais claro se usarmos um Filtro de Redimensionamento Triangular. |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-filter triangle -resize 100x100\! gradient_resize4.jpg
O Operador Resize suaviza a cor entre esses pixels de acordo com as configurações do "[Filtro de Reamostragem](filter.html#filter)". Ajustando o filtro, você pode fazer o gradiente redimensionado gerar um efeito mais de borda a borda. |
magick -size 1x2 gradient: \
-filter Cubic -resize 100x100\! gradient_resize5.jpg
Aqui está um "Gradiente Arco-íris" aproximado, criado usando a técnica de 'resize'.
magick xc:black xc:red xc:yellow xc:green1 xc:cyan xc:blue xc:black \
+append -filter Cubic -resize 600x30\! gradient_rs_rainbow.jpg
Com esse método, você pode usar qualquer combinação e ordem de cores para a geração dos gradientes. Isso o torna muito adequado para gerar Tabelas de Consulta de Cores.
Gradientes de Consulta Interpolados
Para mais informações sobre a configuração "[-interpolate](https://imagemagick.org/command-line-options/#interpolate)", veja Configuração de Interpolação. Outro método de gerar gradientes é usar a Configuração de Interpolação especial. Essa configuração é usada para determinar a cor do pixel retornada quando a consulta de pixel não é um inteiro e, portanto, não corresponde exatamente a um pixel específico. A interpolação então determina a cor com base nos pixels que cercam o ponto de consulta. A configuração padrão de 'bilinear', por exemplo, determinará linearmente a cor para uma consulta que caia entre dois pixels.
magick -size 600x30 xc: \( +size xc:gold xc:firebrick +append \) \
-fx 'v.p{i/(w-1),0}' gradient_interpolated.jpg
Aqui a posição X de consulta 'i/(w-1)' vai de '0.0' a '1.0' ao longo da segunda imagem de dois pixels. O número de ponto flutuante produz um gradiente linear perfeito, muito parecido com o que "[gradient:](#gradient)" faz. O exemplo acima é, na verdade, quase equivalente (veja Gradientes Perfeitos para a diferença) a usar Imagens Recoloridas por Clut" para recolorir uma imagem de gradiente, usando a consulta interpolada da imagem de duas cores.
magick -size 30x600 gradient: -rotate 90 \
\( +size xc:gold xc:firebrick +append \) -clut \
gradient_clut_recolored.jpg
Usar esse método também permite gerar gradientes multicoloridos.
magick -size 30x600 gradient: -rotate 90 -interpolate Bicubic \
\( +size xc:black xc:tomato xc:wheat +append \) -clut \
gradient_clut.jpg
A limitação, porém, é que as cores só podem ser definidas com espaçamento igual. Você não pode simplesmente deslocar a posição da cor central, exceto modificando grosseiramente o gradiente de entrada para alguma forma não linear, de modo a deslocar esse centro. Para mais de três cores, a situação piora. O exemplo acima também é uma boa técnica para colorir imagens em tons de cinza usando Duotons, com garantia de definir exatamente a cor de meio-tom (diferente de usar o Operador Tint). Gradientes de consulta interpolados também podem ser expandidos para 2 dimensões e gerar gradientes lineares quadrados (Interpolação Bilinear), com a mesma facilidade dos gradientes puramente unidimensionais. |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-size 100x100 xc: +swap -fx 'v.p{i/(w-1),j/(h-1)}' \
gradient_bilinear.jpg
Aqui está o mesmo exemplo, mas usando Interpolação Catrom e gerando com o Operador Distort em vez do operador FX, que é muito lento. |
magick \( xc:red xc:blue +append \) \
\( xc:yellow xc:cyan +append \) -append \
-filter point -interpolate catrom \
-define distort:viewport=100x100 \
-distort Affine '.5,.5 .5,.5 1.5,1.5 99.5,99.5' \
gradient_catrom.jpg
O ponto-chave para entender o exemplo acima é que estamos ampliando a imagem pequena com base nos centros de seus pixels. Veja Coordenadas de Imagem vs Coordenadas de Pixel para detalhes. Observe que a maioria dos métodos de interpolação tem Filtros de Redimensionamento Interpolados equivalentes. Mas o uso da viewport e das coordenadas de pixel remove os efeitos de borda mostrados nos Gradientes por Redimensionamento anteriores, causados pela ampliação extrema da imagem muito pequena.
A configuração de Interpolação Mesh, porém, não está disponível como um Filtro de Redimensionamento. É uma interpolação 2D especial que divide a área intrapixel em dois triângulos lineares planos, articulados ao longo da diagonal que conecta os cantos com a menor diferença de cor. Assim, ao tornar duas cores iguais e usar "-interpolate mesh", você pode gerar um gradiente 2D bem diferente. |
magick \( xc:red xc:gold +append \) \
\( xc:gold xc:green +append \) -append \
-filter point -interpolate mesh \
-define distort:viewport=100x100 \
-distort Affine '.5,.5 .5,.5 1.5,1.5 99.5,99.5' \
gradient_mesh.jpg
Como os dois cantos amarelos diagonalmente opostos são iguais, uma diagonal de amarelo foi usada para uni-los. Com as outras cores mapeadas linearmente para esses triângulos. Se as duas cores diagonais não forem iguais, você pode obter uma divisão diagonal diferente.
Crie seu próprio gradiente
O Operador FX Faça-Você-Mesmo permite definir seus próprios gradientes ou outra geração de imagem, com base na posição atual do pixel. Como esse operador requer uma imagem para trabalhar, você pode gerar seus gradientes ou outras imagens de modo a corresponder a essa imagem. Ou seja, você não precisa saber o tamanho da imagem para gerar um gradiente para ela! Por exemplo, você pode gerar facilmente um gradiente linear, dimensionado corretamente para a imagem em que estiver trabalhando. |
magick rose: -channel G -fx 'i/w' -separate gradient_fx_linear.gif
| Ao gerar gradientes em tons de cinza, você pode tornar o operador -fx 3 vezes mais rápido simplesmente pedindo que ele gere apenas um canal de cor, como o canal 'G' (green) no exemplo acima. Esse canal pode então ser Separado para formar a imagem em tons de cinza necessária. Isso pode representar um ganho de velocidade muito grande, especialmente ao usar uma fórmula "[-fx](https://imagemagick.org/command-line-options/#fx)" muito complexa.
---|---
Você pode até gerar alguns gradientes não lineares interessantes. |
magick rose: -channel G -fx '(i/w)^4' -separate gradient_fx_x4.gif
magick rose: -channel G -fx 'cos(pi*(i/w-.5))' \
-separate gradient_fx_cos.gif
Que tal um gradiente radial linear circular bidimensional (um cone). |
magick -size 100x100 xc: -channel G \
-fx 'rr=hypot(i/w-.5, j/h-.5); 1-rr*1.42' \
-separate gradient_fx_radial.gif
| A função 'rr=hypot(xx,yy)' do "[-fx](https://imagemagick.org/command-line-options/#fx)" foi adicionada ao IM v6.3.6 para acelerar a expressão muito comum 'rr=sqrt(xx*xx+yy*yy)'. Isso também significou que não precisamos mais fazer atribuições extras como 'xx=i/w-.5' ao criar um gradiente radial.
---|---
O valor '1.42' (ou sqrt(2)) acima controla o tamanho geral do gradiente em relação às dimensões da imagem. Dessa forma, o raio do gradiente (quão longe o preto está do centro) é a distância diagonal até o canto. Você pode até remover o 'sqrt()' (embutido na função 'hypot()') da expressão para criar um gradiente esférico mais interessante, que pode ser útil para Efeitos de Sombreamento 3D. |
magick -size 100x100 xc: -channel G \
-fx 'xx=i/w-.5; yy=j/h-.5; rr=xx*xx+yy*yy; 1-rr*4' \
-separate gradient_fx_spherical.gif
Observe como uso algumas expressões de atribuição para simplificar o cálculo da distância a partir do centro da imagem e então convertê-lo em um gradiente. Esse recurso foi adicionado no IM v6.3.0. Usando uma função de potência elevada, você pode dar às fotos um efeito de desvanecimento ao redor das bordas retangulares da imagem. Ajuste o valor da potência '4' para controlar a quantidade de desvanecimento. |
magick -size 100x100 xc: -channel G \
-fx '(1-(2*i/w-1)^4)*(1-(2*j/h-1)^4)' \
-separate gradient_fx_quad2.gif
Aqui está um gradiente angular, gerado usando matemática direta. |
magick -size 100x100 xc: -channel G \
-fx '.5 - atan2(j-h/2,w/2-i)/pi/2' \
-separate gradient_fx_angular.gif
Observe que a função 'atan2(y,x)' retorna um ângulo em radianos de -PI a +PI (veja sua manpage), então sua saída precisa ser escalonada e transladada para se ajustar corretamente a uma faixa de cores de 0.0 a 1.0. É por isso que o exemplo acima parece muito mais complexo do que realmente é.Este último exemplo pode ser gerado mais rapidamente Distorcendo um Gradiente.
Gradientes Faça-Você-Mesmo Mais Complexos
NOTA: Esta seção foi criada antes da adição dePontos Esparsos de Cor, e ela teve influência direta em sua criação. É claro que uma função FX pode gerar gradientes de cor. Por exemplo, aqui está um gradiente baseado em razões de distância, usando uma expressão FX extremamente complexa. |
magick -size 100x100 xc: +size xc:red xc:yellow -colorspace RGB \
-fx 'ar=hypot( i/w-.8, j/h-.3 )*4;
br=hypot( i/w-.3, j/h-.7 )*4;
u[1]*br/(ar+br) + u[2]*ar/(ar+br)' \
-colorspace RGB gradient_dist_ratio.gif
| O processamento de imagem foi realizado em um espaço de cor linear (RGB) para evitar o 'escurecimento sRGB' durante a mesclagem de cores primárias tão fortes. VejaProcessando Imagens Reais para mais detalhes.
---|---
Ao passar de dois pontos para três pontos, a razão de quanta cor cada 'ponto de controle' fornece torna-se um pouco mais complexa e usa uma técnica chamada Interpolação por Distância Inversa Ponderada (IDW). Você pode ver mais detalhes matemáticos sobre isso na Wikipedia, IDW Aqui está um exemplo de distância inversa para três pontos. |
magick -size 100x100 xc: +size xc:red xc:yellow xc:lime -colorspace RGB \
-fx 'ar=1/max(1, hypot(i-50,j-10) );
br=1/max(1, hypot(i-10,j-70) );
cr=1/max(1, hypot(i-90,j-90) );
( u[1]*ar + u[2]*br + u[3]*cr )/( ar+br+cr )' \
-colorspace sRGB gradient_inverse.gif
E aqui uso uma distância inversa ao quadrado, que é o método mais comum usado para uma interpolação IDW. Isso também é conhecido como método de Interpolação de Shepard. |
magick -size 100x100 xc: +size xc:red xc:yellow xc:lime -colorspace RGB \
-fx 'ar=1/max(1, (i-50)*(i-50)+(j-10)*(j-10) );
br=1/max(1, (i-10)*(i-10)+(j-70)*(j-70) );
cr=1/max(1, (i-90)*(i-90)+(j-90)*(j-90) );
( u[1]*ar + u[2]*br + u[3]*cr )/( ar+br+cr )' \
-colorspace sRGB gradient_shepards.gif
Observe que a função 'hypot()' não foi usada acima, pois não há necessidade de gerar a raiz quadrada da distância. O exemplo acima agora foi implementado usando os métodos de Cor Esparsa '[Inverse](#inverse)' e '[Shepard's](#shepards)'. Assim, o que foi feito acima agora pode ser feito de forma muito mais simples usando...
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '50,10 red 10,70 yellow 90,90 lime' \
-colorspace sRGB gradient_inverse_alt.gif
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Shepards '50,10 red 10,70 yellow 90,90 lime' \
-colorspace sRGB gradient_shepards_alt.gif
O problema de usar 'Inverse Distance' ou o 'Shepard's Method' (inverso da distância ao quadrado) é que todos os 'pontos de controle' têm um efeito global sobre a imagem inteira. Como resultado, você obtém uma espécie de 'cor média' subjacente entre os pontos, e especialmente a uma grande distância de todos os pontos de controle. Isso, por sua vez, produz 'manchas' de cor em vez de um gradiente de cor suave.
Gradientes e Matizes Faça-Você-Mesmo
-- (Matizes são difíceis de lidar)
À PARTE: Esta foi uma espécie de tentativa fracassada de gerar um efeito de arco-íris interessante. Foi um fracasso, mas aprendi muito com esse fracasso, que apresento a você aqui. O exemplo acima funciona bem, mas eu queria tentar fazer melhor. Pensei que talvez pudesse gerar um gradiente de arco-íris brilhante de cores entre os pontos, em vez de gerar manchas que se fundem em uma cor média. Então, para gerar um gradiente de matiz, tentei fazer a Interpolação Ponderada pelo Inverso da Distância no espaço de cor HSB, embora eu tenha trocado o amarelo por azul, para tornar as cores mais igualmente espaçadas em torno do matiz, e assim, com sorte, fornecer outra forma de gerar uma roda de cores (veja Gradientes em Outros Espaços de Cor acima). |
magick -size 100x100 xc: +size xc:red xc:blue xc:lime -colorspace HSB \
-fx 'ar=1/max(1, (i-50)*(i-50)+(j-10)*(j-10) );
br=1/max(1, (i-10)*(i-10)+(j-70)*(j-70) );
cr=1/max(1, (i-90)*(i-90)+(j-90)*(j-90) );
( u[1]*ar + u[2]*br + u[3]*cr )/( ar+br+cr )' \
-colorspace sRGB gradient_shepards_HSB.gif
Como você pode ver, todas as cores ficaram bonitas e brilhantes, pois estamos gerando apenas um gradiente de matiz. No entanto, o resultado também parece muito estranho, o que é causado pela natureza 'cíclica' do canal de cor 'Hue' (matiz). Como consequência, a área entre o azul e o vermelho percorre o caminho longo passando por um matiz verde, em vez do caminho 'de módulo' mais curto por um matiz roxo. Depois de muita pesquisa, finalmente descobri como fazer a matemática de módulo necessária para realizar o exemplo acima corretamente, usando uma Média Circular para a média ponderada das distâncias. Isso envolve converter o matiz, como um ângulo polar, em coordenadas retangulares X e Y. Isso permite realizar matemática linear, deixando-nos aplicar uma ponderação linear dos valores, de forma apropriada. O resultado é então convertido de volta em um matiz angular. |
magick -size 100x100 xc: +size xc:red xc:blue xc:lime \
-colorspace HSB -channel R \
-fx 'aa=u[1]*2*pi; ba=u[2]*2*pi; ca=u[3]*2*pi;
ar=1/max(1, hypot(i-50,j-10) );
br=1/max(1, hypot(i-10,j-70) );
cr=1/max(1, hypot(i-90,j-90) );
nr=ar+br+cr;
mod(atan2( ( sin(aa)*ar + sin(ba)*br + sin(ca)*cr )/nr,
( cos(aa)*ar + cos(ba)*br + cos(ca)*cr )/nr
)/(2*pi)+1, 1)' \
-separate -background white -combine +channel \
-set colorspace HSB -colorspace sRGB gradient_circular_mean_hue.gif
NOTA: O exemplo acima realizou suas operações apenas no canal de matiz. Para uma imagem real, ainda precisaríamos operar (normalmente) nos canais de saturação e brilho. Como você pode ver, agora obtemos um gradiente correto entre o vermelho e o azul, embora o método, quando aplicado apenas a cores primárias que têm uma alta separação angular, tenda a gerar mudanças de gradiente muito repentinas no meio. Ou seja, embora o resultado esteja correto, a variação angular de matiz não é linear para mudanças muito grandes de efeitos de matiz. Funcionaria bem para calcular a média de muitos matizes próximos, mas não para essas primárias amplamente espaçadas. Eu até mudei para usar uma 'Ponderação Inversa' mais forte, em vez do método mais usual 'Inverso ao Quadrado' ou 'Shepard's' (veja acima) e, embora tenha melhorado as coisas, as mudanças de matiz ainda estavam se comprimindo no centro devido aos efeitos não lineares. Como as cores de entrada são constantes, pré-convertê-las em coordenadas matiz-x e matiz-y, fazer a ponderação de Shepard nesses canais e depois converter de volta tornaria o processo ainda mais rápido. Ou seja, converter as cores de um espaço de cor HSB para um espaço de cor Hx,Hy,S,B, para aplicar a técnica. Se isso for feito, então o ponto central e mesmo o gradiente uniforme entre os pontos tenderia ao branco (o ponto central de um espaço de cor HSB). Se isso fosse realizado no espaço de cor HSL, essa área tenderia a um cinza de tom médio.
Essa conversão de um matiz polar para coordenadas X-Y seria, de certa forma, semelhante a simplesmente fazer os cálculos em um espaço RGB não polar, que mostra esse mesmo efeito de tender ao cinza (veja os exemplos anteriores). Então, se ao usar uma Média Circular estamos, na verdade, simplesmente convertendo um espaço de cor HSB em uma variante RGB altamente distorcida, por que não fazer a tarefa em um espaço de cor RGB linear e saturar as cores, para gerar o matiz!
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '50,10 red 10,70 blue 90,90 lime' \
-colorspace sRGB gradient_inverse_RGB.png
magick gradient_inverse_RGB.png -colorspace HSB \
-channel GB -evaluate set 100% +channel \
-colorspace sRGB gradient_inverse_RGB_Hue.gif
| O processamento da imagem foi realizado em um espaço de cor linear (RGB) para evitar o 'escurecimento sRGB' durante a mistura de cores primárias tão fortes. VejaProcessando Imagens Reais para mais detalhes. ---|--- Como você pode ver, obtemos praticamente exatamente o mesmo resultado de antes, mas com toda a complexa 'matemática de módulo' removida. No entanto, ainda não estou nem um pouco mais perto de obter uma distribuição mais linear de matizes entre os pontos iniciais de cor. A moral de tudo isso é que trabalhar com matizes é difícil, não apenas por causa da 'descontinuidade do vermelho', mas também por causa dos efeitos não lineares que ocorrem quando as cores são muito amplamente espaçadas. E, no fim, o resultado foi o mesmo que se eu tivesse feito a tarefa diretamente no espaço RGB linear e saturado as cores. Essencialmente, embora os espaços de cor HSB e HSL sejam divertidos, eles não são espaços de cor lineares, realistas ou práticos para se trabalhar. Esta é provavelmente também a razão pela qual pouquíssimas operações realmente trabalham com o matiz diretamente.
Gerando o Gradiente Perfeito (matematicamente)
Gerar um gradiente matemático perfeito, como para Transformadas de Fourier (que é cíclico), Mapeamento de Imagem, ou mesmo Matemática de Gradiente; requer gradientes especiais que são diferentes dos gradientes que examinamos até agora. O que quero dizer com isso? Bem, aqui está uma pequena imagem "gradient:" de 1x5 pixels, que eu Escalei para que você possa ver as cores individuais dos pixels. |
magick -size 1x5 gradient: -scale 2000% gradient.png
Esta imagem cria um gradiente que vai de uma cor 'branco' exata ao longo da linha superior, até uma cor 'preto' exata ao longo da linha mais inferior. É um gradiente 'idealizado' e, tipicamente, exatamente o que um usuário deseja, pois contém de fato as cores que o usuário especificou. No entanto, embora seja isso que um usuário espera, não é um gradiente matematicamente correto. Como discutido em Coordenadas de Imagem vs Coordenadas de Pixel, os pixels na verdade têm uma área e, como tal, o pixel branco no topo da imagem representa o centro desse pixel, enquanto o preto representa o centro do pixel mais inferior. Ou seja, não a borda da imagem, mas a 1/2 pixel de distância da borda. Matematicamente, as imagens começam na borda. Assim, para gerar um gradiente matemático perfeito, você precisa especificar as localizações das cores na borda da imagem, em coordenadas de pixel. Como tal, em coordenadas de imagem, as posições são deslocadas em 1/2 pixel, e o tamanho da imagem é exatamente o número de pixels na imagem (uma distância), em vez de uma localização que é 1 pixel menor que o tamanho da imagem. Uma forma de gerar um gradiente matematicamente perfeito é usar a Cor Esparsa Baricêntrica (examinada em detalhe na próxima seção) para gerar um gradiente perfeito de borda a borda... |
magick -size 1x5 xc: \
-sparse-color Barycentric '0,-0.5 white 0,%[fx:h-.5] black' \
-scale 2000% gradient_math.png
Observe que as coordenadas usadas vão de -0.5 até a altura da imagem menos 0.5, que são as coordenadas de pixel das bordas reais da imagem. E se você olhar de perto os resultados, descobrirá que os pixels superior e inferior não são de cor branca ou preta. O pixel tem a cor do gradiente no centro do pixel. Como este gradiente é matematicamente correto, ele fará 'ladrilhamento' corretamente quando usado em situações especiais de 'ladrilhamento' ou 'cíclicas'. A imagem de gradiente anterior não fará 'ladrilhamento' corretamente. Você obtém um pixel branco puro, ao lado do pixel preto puro, gerando assim uma lacuna de um pixel ou 'disjunção' no ciclo matemático, em situações em que o branco puro e o preto puro são tipicamente considerados valores equivalentes. Uma forma mais simples é gerar uma imagem "[gradient:](#gradient)" que seja um pixel mais longa, e cortar um pixel de qualquer uma das extremidades (de acordo com a configuração atual de "[-gravity](https://imagemagick.org/command-line-options/#gravity)"). Por exemplo, aqui cortei o pixel branco mais superior, já que ter um pixel preto (ou valor zero) muitas vezes é mais desejável no resultado final. |
magick -size 1x6 gradient: -chop 0x1 -scale 2000% gradient_chopped.png
A imagem de gradiente resultante pode então ser Rotacionada conforme necessário, para gerar a imagem requerida para processamento posterior. No entanto, embora este gradiente 'cicle' corretamente, a posição real da cor não é exatamente correta. Mas, em muitos casos, isso é bom o suficiente. Se você precisa de um 'gradiente perfeito', recomendo que use um gradiente de cor esparsa. Em Resumo... Um pouco de reflexão sobre exatamente o que você quer do seu gradiente pode fazer uma grande diferença na precisão dos seus resultados finais. Mas, se não importa, então não se preocupe com isso, use o que for mais simples para a tarefa em questão.
Pontos Esparsos de Cor
O operador "[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color) ", adicionado no IM v6.4.3-0, pega uma imagem e define a cor fornecida em cada uma das coordenadas de ponto flutuante 'x,y' dadas. Ou seja, da forma...
-sparse-color {method} 'x,y color x,y color x,y color ...'
O restante dos pixels (limitado de acordo com a configuração "[-channel](https://imagemagick.org/command-line-options/#channel)") será então mapeado de acordo com sua relação com esses pontos isolados de cor, de modo a suavizar as cores entre esses pontos. O method define qual será essa relação. Naturalmente, há muitas maneiras de definir qual deve ser a cor intermediária, e qual método você escolhe realmente depende do que você está tentando alcançar. Isso também pode, de fato, ser classificado como uma versão completamente livre de interpolação bidimensional (Veja Interpolação, Wikipedia). A ampliação de imagem, ou Redimensionar, é na verdade um subconjunto especializado disso, mas em que você começa com uma grade fixa completa de pixels a serem ampliados. Infelizmente, poucos dos Filtros de Redimensionamento ou Métodos de Interpolação que são especificamente projetados para lidar com uma grade de pontos se traduzem diretamente em um conjunto de forma livre de pontos de cor esparsamente separados. Ou seja, o redimensionamento envolvendo uma grade incompleta simplesmente não funciona. Isso também está relacionado aos métodos de "Sistema de Informação Geográfica (GIS)", onde as paisagens são medidas usando pontos de altura esparsamente separados (que raramente estão em uma grade estrita), com o restante da paisagem sendo determinado a partir desses pontos isolados. Em uma situação semelhante, a meteorologia frequentemente tem pontos isolados de pressão atmosférica e temperatura, que então precisam ser interpolados. Tipicamente, após a interpolação, os mapas são processados posteriormente para gerar 'isolinhas' mostrando pontos de igual valor (altura, pressão, temperatura), produzindo os vários mapas meteorológicos com os quais quase todo mundo está familiarizado. Neste caso, você pensaria na imagem gerada como um simples 'mapa de altura' em escala de cinza dos dados de entrada, ou talvez até de todas as três variáveis simultaneamente, cada uma em um 'canal' de imagem separado.
Baricêntrico (gradiente triangular)
O método "Barycentric" mapeia três e apenas três pontos em um triângulo linear de cor. As cores fora deste triângulo continuam como antes. Marquei os pontos de entrada com um pequeno círculo, para que as cores que você vê sejam todas os valores interpolados que foram gerados pelo Operador de Cor Esparsa. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '30,10 red 10,80 blue 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82 circle 90,90 90,92' \
sparse_barycentric.png
| O processamento da imagem foi realizado em um espaço de cor linear (RGB) para evitar o 'escurecimento sRGB' durante a mistura de cores primárias tão fortes. VejaProcessando Imagens Reais para mais detalhes.
---|---
Se quatro ou mais pontos forem dados, será realizado um 'melhor ajuste' sobre todos os pontos fornecidos e, como resultado, os pontos reais podem não obter a cor exata especificada para eles. No entanto, esteja avisado de que o gradiente não simplesmente 'para', mas continua mudando além desses pontos. Tradicionalmente, um gradiente baricêntrico será limitado ao interior do triângulo envolvente dos pontos usados para gerá-lo. Por exemplo.. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '30,10 red 10,80 blue 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
\( -size 100x100 xc:black -draw 'polygon 30,10 10,80 90,90' \) \
-alpha off -compose CopyOpacity -composite \
-draw 'circle 30,10 30,12 circle 10,80 10,82 circle 90,90 90,92' \
sparse_bary_triangle.png
magick -size 100x100 xc:none -draw "polygon 30,10 10,80 90,90" \
-colorspace RGB -channel rgb \
-sparse-color Barycentric '30,10 red 10,80 blue 90,90 lime' \
-colorspace sRGB sparse_bary_triangle_2.png
| As máscaras triangulares usadas acima são 1/2 pixel grandes demais devido à forma como o draw desenha uma linha extra ao redor de suas formas. VejaLimites de Preenchimento do Draw para detalhes. Isso pode ser um problema ao gerar uma malha triangular de gradientes.
---|---
O método 'barycentric' é, na realidade, um mapeamento de uma equação afim linear para cada um dos três canais de cor separadamente. Como tal, se eu separar cada um dos canais de cor do exemplo de três pontos acima, você obtém três gradientes lineares simples em cada canal de cor.
magick sparse_barycentric.png -separate sparse_bary_%d.gif
É apenas por causa do uso de cores primárias que os gradientes acima foram todos mapeados paralelamente a uma das arestas do triângulo. Ou seja, isso não é tipicamente o caso. Mas você sempre obterá um gradiente linear simples em cada canal separado da imagem, e um plano plano de valores no espaço de cor 3D.
Baricêntrico e Gradientes de Duas Cores
Este efeito paralelo do gradiente baricêntrico triangular é, na verdade, muito útil. Se dois dos pontos forem definidos com a mesma cor, então esses dois pontos definirão o 'ângulo' do gradiente entre eles e o outro ponto colorido. Por exemplo, ao tornar dois dos pontos 'red', o gradiente ficará paralelo aos dois pontos 'red'... |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '30,10 red 10,80 red 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82 circle 90,90 90,92' \
sparse_bary_gradient.png
Aqui está o mesmo exemplo, mas com um dos pontos de controle de ângulo movido para mostrar como ele define o ângulo do gradiente. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '50,70 red 10,80 red 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 50,70 50,72 circle 10,80 10,82 circle 90,90 90,92' \
sparse_bary_gradient_2.png
Gradientes Diagonais
Isso fornece uma forma simples de gerar qualquer gradiente diagonal linear usando apenas duas cores. Por exemplo, aqui está uma maneira particularmente boa de criar um gradiente diagonal, indo de um canto a outro canto, para uma imagem de entrada de QUALQUER tamanho.
magick -size 600x60 xc: -colorspace RGB \
-sparse-color barycentric '0,0 skyblue -%w,%h skyblue %w,%h black' \
-colorspace sRGB diagonal_gradient.jpg
E para alinhar com os outros dois cantos...
magick -size 600x60 xc: -colorspace RGB \
-sparse-color barycentric '0,%h black -%w,0 black %w,0 skyblue' \
-colorspace sRGB diagonal_gradient_2.jpg
Esses 'gradientes diagonais' produzem um gradiente de aparência natural mesmo com imagens longas como a acima. Estude as localizações dos três pontos de cor, especialmente os dois pontos de cor igual que definem o ângulo do gradiente entre os dois cantos. Observe que, em ambos os casos, um desses pontos nem está localizado dentro da própria imagem! Note também o uso de Escapes de Porcentagem para fazer as posições se ajustarem automaticamente ao tamanho das imagens sobre as quais o gradiente está sendo desenhado.
Gradientes de Dois Pontos
Se apenas dois pontos de cor forem dados, o IM gerará o terceiro ponto para você, de modo que o ângulo seja perpendicular entre os dois pontos originais. O resultado é um gradiente linear simples sobre o qual você tem muito controle. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Barycentric '30,10 red 90,90 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 90,90 90,92' \
sparse_bary_two_point.png
Os gradientes de dois pontos, no entanto, não funcionam muito bem quando aplicados aos cantos de imagens muito 'largas' ou 'altas' (alta proporção de aspecto). Basicamente, o gradiente não está alinhado diagonalmente, ao contrário dos gradientes de três pontos acima. Ele é angulado, mas não angulado o suficiente para torná-lo 'interessante'.
magick -size 600x60 xc: -colorspace RGB \
-sparse-color barycentric '0,0 skyblue %w,%h black' \
-colorspace sRGB sparse_bary_two_point_wide.jpg
Bilinear (gradiente de 4 pontos)
Este método ajusta uma equação a 4 pontos, sobre todos os três canais de cor, para produzir um gradiente de cor uniforme entre os pontos, e além. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Bilinear '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_bilinear.png
Você pode ver esse 'ajuste de 4 pontos' pegando a imagem acima e separando os gradientes de cada canal de cor individual.
magick sparse_bilinear.png -separate sparse_bilin_%d.gif
Observe como a equação produz curvas (curvas quadráticas, na verdade). No entanto, se os 4 pontos formarem linhas paralelas, o gradiente gerado se tornará linear. Este método é, na verdade, equivalente ao método de Interpolação Bilinear (veja Gradientes de Consulta Interpolados abaixo), quando os 4 pontos estão alinhados a uma grade ortogonal (retangular). Se menos de 4 pontos forem dados, a função acima será substituída por um método de 3 pontos '[Barycentric](#barycentric)' (veja acima). Se mais de quatro pontos forem dados, ele fará um melhor ajuste de todos os pontos e, portanto, pode não corresponder à cor especificada no ponto dado. Isso não é recomendado.
Voronoi (cor mais próxima)
O método "Voronoi" simplesmente mapeia cada pixel para o ponto de cor mais próximo que você forneceu. Isso basicamente divide a imagem em um conjunto de 'células' poligonais ao redor de cada ponto. Por exemplo.. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Voronoi '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi.gif
Como você pode ver, nenhuma tentativa é feita para fornecer anti-aliasing das 'células' coloridas ao redor de cada ponto. A borda de cada célula cai exatamente no ponto médio entre os vizinhos mais próximos de cada ponto. Isso pode ser usado, por exemplo, para gerar máscaras para recortar a imagem de várias maneiras. Basta atribuir a um ponto o valor branco e a todos os demais o valor preto para extrair uma única 'célula' da imagem. Se você quiser suavizar (anti-aliasing) o resultado, pode usar alguma forma de Superamostragem para suavizar a imagem. Por exemplo, gere uma 4 vezes maior e use "[-scale](https://imagemagick.org/command-line-options/#scale)" para reduzi-la de volta ao tamanho desejado. |
magick -size 400x400 xc: -colorspace RGB \
-sparse-color Voronoi '120,40 red 40,320 blue 270,240 lime 320,80 yellow'
\
-scale 25% -colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi_ssampled.png
| Todo o processamento da imagem foi realizado em um espaço de cor linear (RGB) para evitar o 'escurecimento sRGB' durante a mistura de cores primárias tão fortes. VejaProcessando Imagens Reais para mais detalhes.
---|---
A forma mais simples (embora não muito boa) é apenas borrar a imagem muito ligeiramente... |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Voronoi '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-blur 1x0.7 -colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi_smoothed.png
Ao borrar a imagem gerada por uma grande quantidade, você pode configurar alguns gradientes não lineares entre as 'células' que foram geradas. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Voronoi '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-blur 0x15 -colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi_blur.png
Quanto maior o "[-blur](https://imagemagick.org/command-line-options/#blur)", maior o gradiente entre as várias 'células'. No entanto, esteja avisado de que isso pode não preservar pequenas células coloridas, ou garantir que o ponto original permaneça com a cor que foi dada, se ele estiver próximo da borda (e de outro ponto) de uma cor diferente. Ao usar uma técnica especial de 'desfoque linear', desenvolvida por Fred Weinhaus, você pode produzir um gradiente linear de largura fixa entre as células. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Voronoi '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-blur 10x65535 -colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_voronoi_gradient.png
A saída não borrada também poderia ser passada para várias técnicas de Detecção de Bordas para gerar várias bordas delimitadas. Você pode remapear a imagem por meio de um Conversor de Rasterizado para Vetor para gerar linhas vetoriais. No entanto, descobri que as configurações padrão do 'autotrace' podem precisar ser ajustadas com "-corner-threshold 120" para que detecte melhor os cantos.
Shepards (manchas de cor)
O método "Shepards" usa uma razão dos inversos dos quadrados das distâncias a cada um dos pontos dados para determinar a cor da tela em cada ponto. Veja Gradientes DIY Mais Complexos acima para exemplos de como a matemática é realizada. É um pouco como ter holofotes de cor em cada ponto que interagem entre si, à medida que a luz se espalha para uma média uniforme de todas as cores dadas no infinito. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards.png
| O processamento da imagem foi realizado em um espaço de cor linear (RGB) para evitar o 'escurecimento sRGB' durante a mistura de cores primárias tão intensas. VejaProcessando Imagens Reais para mais detalhes.
---|---
Ao cercar uma área específica com uma cor similar, você pode gerar um platô dessa cor específica, embora os limites entre os pontos de borda possam 'vazar', e o centro do 'platô' possa afundar formando uma tigela rasa (dependendo da distância aos outros pontos de cor). Este método também é o que se usa para gerar um campo de deslocamento, como o usado em Distorções de Imagem Shepards. Nesse caso, são os vetores de deslocamento X e Y que estão sendo mapeados, em vez dos valores de cor R,G,B.
Inverse (pontos nítidos de cor)
O método "Inverse" é praticamente idêntico ao "Shepards", exceto que usa uma ponderação por distância inversa mais direta dos pontos dados. Veja Gradientes DIY Mais Complexos acima para exemplos de como a matemática é realizada. Este foi um acréscimo bem posterior ao ImageMagick versão 6.6.9-7. Por exemplo... |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '30,10 red 10,80 blue 70,60 lime 80,20 yellow' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_inverse.png
Como você pode ver, ele gera pontos nítidos de cor, que rapidamente se fundem com a 'cor média' do fundo. Em comparação com o Método Shepards, que gera manchas arredondadas, com uma cor 'plana' ao redor dos pontos de cor. Ele, no entanto, funciona melhor ao gerar gradientes lineares onde todos os pontos de controle formam uma linha. Ou seja, para gerar gradientes unidimensionais ao longo de uma linha específica na imagem. Contudo, há mais um ponto a ser destacado. A velocidade com que esses pontos de cor caem para um nível próximo à 'média' é controlada por quão próximos eles estão. Ao colocar duas fontes pontuais próximas, elas caem rapidamente; quanto mais afastadas, maior a influência de cada cor individual no resultado.
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '45,45 red 55,55 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 45,45 45,47 circle 55,55 55,57' \
sparse_inverse_near.png
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '30,30 red 70,70 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,30 30,32 circle 70,70 70,72' \
sparse_inverse_far.png
Além disso, se você 'duplicar' um ponto específico (exatamente sobre, ou apenas próximo um do outro) com a mesma cor ou uma cor similar, você tornará esse ponto de cor duas vezes mais forte. |
magick -size 100x100 xc: -colorspace RGB \
-sparse-color Inverse '30,30 red 75,65 lime 65,75 lime' \
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,30 30,32 circle 75,65 75,67 circle 65,75 65,77 '
\
sparse_inverse_stronger.png
Esses efeitos também se aplicam ao método '[Shepards](#shepards)'!
Fator de Potência Shepards
Ambos os métodos de cor esparsa Shepards e Inverse são na verdade o mesmo, mas com diferentes 'níveis de potência' aplicados aos pesos de distância inversa. (2.0 e 1.0 respectivamente). A partir do IM v6.8.0-10, você pode definir esse nível de potência usando um define operacional, 'shepards:power', que será usado pelo método '[Shepards](#shepards)'. Por exemplo
magick -size 100x100 xc: -colorspace RGB -define shepards:power=0.5 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow0.5.png
magick -size 100x100 xc: -colorspace RGB -define shepards:power=1 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow1.png
magick -size 100x100 xc: -colorspace RGB -define shepards:power=2 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow2.png
magick -size 100x100 xc: -colorspace RGB -define shepards:power=3 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow3.png
magick -size 100x100 xc: -colorspace RGB -define shepards:power=8 \
-sparse-color Shepards '30,10 red 10,80 blue 70,60 lime 80,20 yellow'
\
-colorspace sRGB -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_pow8.png
potência 0.5 |
potência 1.0
(inverse) |
potência 2.0
(shepards) |
potência 3.0 |
potência 8.0
---|---|---|---|---
Como você pode ver, as 'manchas de cor' expandem-se de pontos muito nítidos para manchas arredondadas, e daí para grandes áreas de cor. Em níveis de potência muito altos, ele acabará reproduzindo o mesmo padrão de um Método de Cor Esparsa Voronoi. Este -define não afeta apenas a Cor Esparsa Shepards, mas também terá efeitos semelhantes sobre o Método de Distorção Shepards, que é baseado em mapas de deslocamento calculados gerados pelo método de cor esparsa. Contudo, ele não afeta o método de cor esparsa Inverse, que sempre usa um nível de potência de 1.0.
Resumo dos Métodos de Cor Esparsa
Aqui está uma repetição das várias imagens de "[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)" de 4 pontos, para comparação.
Voronoi |
Voronoi (desfocado) |
Shepards |
Inverse |
Bilinear
---|---|---|---|---
E aqui está um resumo dos vários métodos de 3 pontos.
Voronoi |
Voronoi (desfocado) |
Shepards |
Inverse |
Barycentric
---|---|---|---|---
No momento, apenas os métodos '[Voronoi](#voronoi)', '[Shepards](#shepards)' e '[Inverse](#inverse)' são adequados para mais de quatro pontos. Mais métodos de "[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)" estão planejados. Se você tiver alguma ideia, envie-a por e-mail para mim.
Canal e Cor Esparsa
O operador "[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)" é afetado pela configuração "[-channel](https://imagemagick.org/command-line-options/#channel)", o que significa que você pode usar essa configuração para limitar seus efeitos a apenas um único canal, ou expandi-los ao canal de transparência. Você também pode usar a configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" para acelerar o processamento de imagens em escala de cinza operando apenas em um canal, e então "[-separate](https://imagemagick.org/command-line-options/#separate)" esse canal (veja Manipulação de Canais para mais detalhes). Por exemplo.. |
magick -size 100x100 xc: -channel G -sparse-color Shepards \
'30,10 gray70 10,80 black 70,60 white 80,20 gray(33.3333%)' \
-separate +channel -fill white -stroke black \
-draw 'circle 30,10 30,12 circle 10,80 10,82' \
-draw 'circle 70,60 70,62 circle 80,20 80,22' \
sparse_shepards_gray.gif
A partir do IM v6.6.8-5, os canais não modificados são preservados; assim, você agora pode usar a Cor Esparsa com a configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" para adicionar um gradiente transparente a qualquer imagem, de forma rápida e fácil. Por exemplo, aqui adiciono um Gradiente Diagonal transparente, alinhado de modo que 50% de transparência fique ao longo da diagonal da imagem interna "rose: ". |
magick rose: -alpha set -channel A \
-sparse-color Barycentric \
'0,0 opaque %w,-%h opaque %w,%h transparent' \
rose_alpha_gradient.png
| A cor 'Opaque' é apenas outro nome para 'Black'. Basicamente, ela é usada quando você está realmente interessado apenas em especificar uma cor totalmente opaca, mas a cor em si não importa. O mesmo vale para a cor 'Transparent'. Eu poderia ter usado com a mesma facilidade 'White' e 'None', respectivamente.
---|---
| Antes do IM v6.6.8-5, quaisquer canais não selecionados pela configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" eram redefinidos para valores zero (preto). Isso limitava severamente sua utilidade efetiva
---|---
A Cor Esparsa também aceita valores de ponto flutuante normalizados em vez de um nome de cor. Exatamente quantos valores precisam ser fornecidos para substituir o nome da cor depende da configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" atual, e se esse canal está 'ativo' na imagem sendo processada. A maneira mais fácil é limitar o processamento a um único canal. Note também que, ao usar números brutos, em vez de nomes de cor, os valores de transparência são valores 'matte' (0=opaco) e não valores 'alpha' (1=opaco) (para o IMv7). Assim, no exemplo acima eu poderia ter usado números em vez de nomes de cor...
-channel A -sparse-color Bilinear '0,0 1.0 -%w,%h 1.0 %w,%h 0.0'
Isso pode ser mais fácil de manipular em scripts programados, e em APIs, que podem não ter acesso ao tradutor de 'colorname'.
Cor Esparsa como um Operador de Preenchimento
Uma das razões originais para criar o Operador de Cor Esparsa era permitir que você fornecesse uma imagem contendo apenas um pequeno número de pontos fixos de cor, e a partir disso 'preenchesse' o restante das cores indefinidas. Por exemplo, aqui desenhei um pequeno número de pixels. A configuração "[+antialias](https://imagemagick.org/command-line-options/#antialias)" foi especificamente desativada para que nenhuma cor semitransparente ou mista fosse desenhada; assim, a imagem contém apenas as quatro cores exatas especificadas e nenhuma outra. |
magick -size 100x100 xc:none +antialias -fill none -strokewidth 0.5 \
-stroke Gold -draw "path 'M 20,70 A 1,1 0 0,1 80,50'" \
-stroke DodgerBlue -draw "line 30,10 50,80" \
-stroke Red -draw "circle 80,60 82,60" \
sparse_source.gif
Agora podemos extrair os poucos pixels não transparentes presentes nesta imagem, e então preencher todas as outras cores usando o método de cor esparsa multiponto, '[Shepards](#shepards)'. |
magick sparse_source.gif sparse-color:- |\
magick sparse_source.gif -alpha off \
-sparse-color shepards '@-' sparse_fill.png
O comando "sed" acima toma o Formato de Arquivo de Texto Enumerado, exclui a primeira linha de cabeçalho e qualquer linha que contenha transparência, antes de reformatá-lo em uma lista de coordenadas de pixel e cores. Essa lista é então 'canalizada' para o Operador de Cor Esparsa usando o argumento especial "@-". Sim, o exemplo acima é bem complicado, mas funciona. Pelo menos para um número muito pequeno de pontos. Contudo, quanto mais pontos forem fornecidos, mais lenta a operação se torna. Isso porque a Cor Esparsa é orientada a 'pontos' em seu processamento, em vez de orientada a imagem ou Morfologia. Eventualmente, espero poder fornecer um conjunto de métodos de 'preenchimento de buracos' orientados à morfologia, onde você pode simplesmente fornecer a imagem acima como está e fazer com que ela preencha as áreas transparentes automaticamente. Esta técnica de extração de pontos pode ser combinada com o Método de Morfologia EdgeIn para extrair os pixels ao redor das bordas de objetos ou buracos, de modo que você possa então 'preencher' o fundo faltante ou os buracos (como mostrado em Morfologia e Canais). Por exemplo...
magick figure.gif -channel A -morphology EdgeIn Diamond
shape_edge_pixels.gif
magick shape_edge_pixels.gif txt:- |\
sed '1d; / 0) /d; s/:.* /,/;' | \
magick shape_edge_pixels.gif -alpha off \
-sparse-color shepards '@-' shape_edge_in_lights.png
magick shape_edge_in_lights.png figure.gif -composite shape_in_lights.png
Note que a imagem resultante é exatamente igual à entrada, mas com o fundo transparente substituído por 'cores de borda' desfocadas por distância. É por isso que as bordas da imagem se tornaram indistintas. Esta imagem foi desenvolvida especificamente para tentar gerar melhores técnicas de 'suavização de bordas'. Veja Suavização por Desfoque e Suavização por Distância para outras técnicas de suavização.
Cor Esparsa Shepards, uma Alternativa ao Desfoque
Uma alternativa ao uso de "[-sparse-color](https://imagemagick.org/command-line-options/#sparse-color)" é pegar a imagem de pixels sobre um fundo transparente e Desfocá-la. Depois, a transparência é descartada.
magick sparse_source.gif -channel RGBA -blur 0x15 \
-alpha off sparse_blur_simple.png
O problema com isso é que as cores originais não são preservadas, e você também tem o problema de qual valor exato de 'sigma ' deve ser usado. Além disso, ele não leva em conta quão 'próxima' cada cor está; assim, dois pixels coloridos próximos um do outro (a menos do valor de 'sigma ') vão inundar um ao outro e se fundir por desfoque. Um método melhor é gerar várias camadas de imagens desfocadas com valores de 'sigma ' progressivamente menores, e a imagem original não desfocada no topo.
for sigma in 64 32 16 8 4 2 1 0; do
magick sparse_source.gif -depth 16 \
-channel RGBA -blur 0x$sigma miff:-
done |
magick - -background none -flatten -alpha off sparse_blur_layered.png
Esta técnica de desfoque em camadas é equivalente ao resultado de um método '[Shepards](#shepards)' sobre a mesma imagem; embora não seja tão exata, ela é muito próxima. Contudo, é provável que seja muito mais rápida quando muitos pixels de entrada estão envolvidos, pois é orientada a imagem (morfologia), em vez de calcular usando pontos individuais. Outro método de desfoque em camadas é usar Redimensionamento para gerar uma 'pirâmide' de imagens desfocadas. Esta técnica é detalhada em Grandes Desfoques Usando Redimensionamento. |
magick sparse_source.gif \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
\( +clone -resize 50% \) \
-layers RemoveDups -filter Gaussian -resize 100x100\! -reverse \
-background None -flatten -alpha off sparse_blur_pyramid.png
Isso funcionará muito rápido com imagens muito grandes sem precisar de valores grandes de 'sigma ' (e, portanto, muito lentos) para cada uma das etapas de desfoque. Essencialmente, está usando uma técnica de redimensionamento de imagem mais rápida para gerar as camadas desfocadas do exemplo anterior. Não é tão exato, mas gerará uma boa aproximação do resultado correto. Contudo, funciona melhor para imagens quadradas e com tamanho igual a uma potência de dois, ou será menos preciso. O operador especial "[-layers](https://imagemagick.org/command-line-options/#layers) RemoveDups" acima removerá quaisquer imagens extras de 'pixel médio único' que tenham sido geradas pelas múltiplas operações de 'clone-resize'. As imagens são então redimensionadas de volta ao tamanho original usando um Filtro de Redimensionamento Gaussiano (o equivalente a um desfoque). A ordem das imagens é então invertida para colocar a original no topo, e as camadas mais desfocadas embaixo, antes de achatá-las como antes. Tem a vantagem de precisar ler a imagem apenas uma vez, fazendo todo o trabalho em um único comando. Também funciona muito rapidamente mesmo para imagens grandes, especialmente porque o redimensionamento apenas reduz a imagem à metade a cada etapa, evitando assim o desfoque lento com um sigma muito grande. A única desvantagem deste método é que você precisará ter uma ideia aproximada do tamanho original da imagem para restaurar as imagens 'desfocadas', e para obter pelo menos uma ideia aproximada de quantos clones redimensionados gerar (Log2 da maior dimensão, mais 1). Contudo, exagerar nos clones de redimensionamento não representa um grande impacto no desempenho, pois o redimensionamento simplesmente se torna um 'no-op' quando a imagem de entrada já foi reduzida à imagem mínima de 1 pixel. As camadas de 'imagem redimensionada' extras e inúteis são então tratadas automaticamente usando "[-layers](https://imagemagick.org/command-line-options/#layers) RemoveDups". O único problema real é a possibilidade de as imagens redimensionadas ficarem 'fora de sincronia' ao lidar com uma imagem que não é uma potência de dois em tamanho. Quão severo é esse problema não se sabe, mas não deve ser muito grande, já que essas imagens são também as mais desfocadas. É claro que ele ainda tem o problema de 'vazamento' do método '[Shepards](#shepards)', então vejamos esse problema com mais detalhes.
O Método Shepards 'Vaza'
O método '[Shepards](#shepards)' não tem qualquer compreensão de 'limites'; assim, cores no lado oposto de alguma 'linha de cor' vazarão, ou 'sangrarão através', para além dessa linha. Eventualmente, a uma grande distância, você obterá uma cor média pura de todos os pixels. Isso nem sempre é um resultado desejável (embora seja desejável em alguns casos). Neste exemplo, quanto mais a curva 'Red' se aproxima da linha 'White', mais a cor 'vazará' através das duas linhas para o lado oposto, produzindo uma cor rosa. |
magick -size 100x100 xc:none +antialias -fill none -strokewidth 0.5 \
-stroke Red -draw "path 'M 26,0 A 55,61 0 0,1 26,100'" \
-stroke White -draw "line 50,0 50,100" \
sparse_lines_near_source.gif
magick sparse_lines_near_source.gif txt:- |\
sed '1d; / 0) /d; s/:.* /,/;' |\
magick -size 100x100 xc: -sparse-color shepards '@-' \
sparse_lines_near.png
Esse vazamento de cores é o principal problema ao usar o Método Shepards para 'preenchimento de buracos', especialmente quando múltiplos buracos estão envolvidos, pois as cores associadas a um buraco podem e vão vazar para outro buraco completamente diferente e afetar suas cores. E vice-versa. É uma compreensão de limites que constitui a diferença entre o Método Shepards e outra forma de 'preenchimento de buracos' de cor conhecida como 'Difusão de Cor '. Basicamente, com a 'Difusão de Cor ', as cores não podem passar através de uma linha de alguma outra cor definida. Isso é alcançado limitando o efeito apenas às cores em 'linha de visão', ou àquelas que vazam ao redor do lado externo de uma borda. Isso requer usar a distância às cores mais próximas para limitar quais cores influenciam um pixel. Um uso importante da 'Difusão de Cor ' é apresentado no site Diffusion Curves. Este não só faz uso intenso de difusão de cor, como também inclui informações sobre técnicas para gerar difusões muito rapidamente. Espero implementar isso no ImageMagick em algum momento no futuro.
Imagens Plasma
Gradientes Plasma
Enquanto os gradientes fornecem uma faixa suave de cores, outro operador de criação de imagens, "plasma:", fornece um tipo diferente de gradiente. Um que é idealmente adequado para gerar um pano de fundo aleatório de cor para suas imagens. Antes de tudo, devo destacar que "plasma:" é uma imagem randomizada. Assim, ela pode e vai produzir uma imagem diferente toda vez que é executada. Por exemplo, aqui geramos três imagens plasma 'padrão' separadas, e cada imagem é diferente das outras, embora o mesmo comando tenha sido usado para gerá-las.
magick -size 100x100 plasma: plasma1.jpg
magick -size 100x100 plasma: plasma2.jpg
magick -size 100x100 plasma: plasma3.jpg
Você também pode ver que as imagens plasma são igualmente um tipo de gradiente randomizado de cores e, como "gradient:", começam com branco no topo e preto na base. O que não está bem documentado é que você pode especificar a cor para o gradiente plasma exatamente da mesma forma que pode para os gradientes lineares acima.
magick -size 100x100 plasma:blue plasma_range1.jpg
magick -size 100x100 plasma:yellow plasma_range2.jpg
magick -size 100x100 plasma:green-yellow plasma_range3.jpg
magick -size 100x100 plasma:red-blue plasma_range4.jpg
magick -size 100x100 plasma:tomato-steelblue plasma_range5.jpg
Você também pode ver que cores de meio-tom como 'tomato' e 'steelblue' tendem a funcionar melhor do que cores puras como 'red' e 'blue'. Ao usar a mesma cor duas vezes com plasma, você pode produzir um fundo predominantemente daquela cor, mas com manchas aleatórias de cores próximas às cores originais.
magick -size 100x100 plasma:black-black plasma_black.jpg
magick -size 100x100 plasma:grey-grey plasma_grey.jpg
magick -size 100x100 plasma:white-white plasma_white.jpg
magick -size 100x100 plasma:yellow-yellow plasma_yellow.jpg
magick -size 100x100 plasma:tomato-tomato plasma_tomato.jpg
magick -size 100x100 plasma:steelblue-steelblue plasma_steelblue.jpg
Novamente, como você pode ver, cores de meio-tom gerarão mais variedades de cor na imagem resultante do que uma cor extrema, como preto, branco ou amarelo. O plasma 'grey' acima é particularmente bonito, dando um efeito iridescente semelhante a 'madrepérola', basicamente porque o cinza tem total liberdade nas cores que o "plasma:" gerará. Normalizar um plasma cinza perfeito de 50% produzirá uma imagem plasma multicolorida particularmente uniforme, sobre toda a faixa de cores, incluindo branco e preto. |
magick -size 100x100 plasma:grey50-grey50 -auto-level plasma_grey_norm.jpg
Como alternativa, você pode apenas ampliar o contraste das cores para deixá-las mais fortes, mas sem chegar a extremos. |
magick -size 100x100 plasma:grey50-grey50 \
-sigmoidal-contrast 8x50% plasma_grey_contrast.jpg
Compare esta imagem com as imagens de 'plasma fractal' abaixo.
Plasma Fractal
O gerador de plasma também tem um modo fractal especial, que produz efeitos altamente coloridos. As cores geradas são realçadas para produzir mudanças de cor mais exageradas.
magick -size 100x100 plasma:fractal plasma_fractal1.jpg
magick -size 100x100 plasma:fractal plasma_fractal2.jpg
magick -size 100x100 plasma:fractal plasma_fractal3.jpg
Na verdade, isso é muito semelhante às imagens de plasma de cor constante que já vimos e, de fato, elas são geradas da mesma forma, mas com mudanças de cor mais pronunciadas.
Costumo achar que as imagens de plasma são um pouco 'ruidosas'. Por isso, elas geralmente se beneficiam de uma leve suavização usando "[-blur](https://imagemagick.org/command-line-options/#blur)". Aqui eu suavizei o ruído da imagem de plasma central acima. |
magick plasma_fractal2.jpg -blur 0x2 plasma_smooth.jpg
Você pode usar "[-paint](https://imagemagick.org/command-line-options/#paint)" para criar manchas aleatórias de cor. |
magick plasma_fractal2.jpg -blur 0x1 -paint 8 plasma_paint.jpg
Ou torne as cores mais pronunciadas e circulares usando o operador de imagem "[-emboss](https://imagemagick.org/command-line-options/#emboss)", depois de usar "[-blur](https://imagemagick.org/command-line-options/#blur)" para remover o ruído de baixo nível. |
magick plasma_fractal2.jpg -blur 0x5 -emboss 2 plasma_emboss.jpg
Usando um "[-blur](https://imagemagick.org/command-line-options/#blur)" seguido de um "[-sharpen](https://imagemagick.org/command-line-options/#sharpen)", você pode produzir um padrão de cores mais pastel do que produzimos com "[-emboss](https://imagemagick.org/command-line-options/#emboss)". |
magick plasma_fractal2.jpg -blur 0x5 -sharpen 0x15 plasma_sharp.jpg
Na verdade, acho que gerar um gradiente de plasma redemoinhado fica particularmente agradável como padrão de fundo. |
magick -size 160x140 plasma:fractal \
-blur 0x2 -swirl 180 -shave 20x20 plasma_swirl.jpg
Plasma em Tons de Cinza
Agora, o gerador de plasma sempre gera cor, mesmo sobre uma cor sólida preto puro. No entanto, muitas vezes é útil gerar um plasma em tons de cinza puros. Bem, há duas maneiras simples de fazer isso. A maneira mais simples é pegar a imagem de plasma e convertê-la para tons de cinza. |
magick -size 100x100 plasma:fractal -blur 0x2 \
-colorspace Gray plasma_greyscale.jpg
Outra maneira é copiar um dos canais de cor sobre os outros dois, para um efeito mais forte, de camada única. |
magick -size 100x100 plasma:fractal -blur 0x2 \
-channel G -separate plasma_grey_copy.jpg
Uma técnica final é usar "[-shade](https://imagemagick.org/command-line-options/#shade)" sobre o plasma. |
magick -size 100x100 plasma:fractal -blur 0x5 \
-shade 120x45 -auto-level plasma_grey_shade.jpg
Você provavelmente pensaria que obteria muitos efeitos de luz e sombra, mas o plasma bruto é tão aleatório que "[-shade](https://imagemagick.org/command-line-options/#shade)" só parece produzir um efeito de 'plasma mais manchado'. Em vez de usar um plasma fractal, com suas mudanças de cor altamente exageradas, você pode criar um plasma em tons de cinza usando o método de plasma de cor constante. Como efeito colateral, esse método também permite controlar o brilho geral da imagem de plasma em tons de cinza gerada.
magick -size 100x100 plasma:black-black \
-blur 0x2 -colorspace Gray plasma_grey0.jpg
magick -size 100x100 plasma:grey25-grey25 \
-blur 0x2 -colorspace Gray plasma_grey1.jpg
magick -size 100x100 plasma:grey50-grey50 \
-blur 0x2 -colorspace Gray plasma_grey2.jpg
magick -size 100x100 plasma:grey75-grey75 \
-blur 0x2 -colorspace Gray plasma_grey3.jpg
magick -size 100x100 plasma:white-white \
-blur 0x2 -colorspace Gray plasma_grey4.jpg
Se isso não for forte o suficiente, use o método de cópia de canal para converter a imagem de plasma em tons de cinza.
magick -size 100x100 plasma:black-black \
-blur 0x2 -channel G -separate plasma_grey5.jpg
magick -size 100x100 plasma:grey25-grey25 \
-blur 0x2 -channel G -separate plasma_grey6.jpg
magick -size 100x100 plasma:grey50-grey50 \
-blur 0x2 -channel G -separate plasma_grey7.jpg
magick -size 100x100 plasma:grey75-grey75 \
-blur 0x2 -channel G -separate plasma_grey8.jpg
magick -size 100x100 plasma:white-white \
-blur 0x2 -channel G -separate plasma_grey9.jpg
Essas imagens de plasma em tons de cinza são muito úteis para processamento posterior, permitindo gerar outros efeitos de imagem. Por exemplo, veja a página sobre Imagens de Fundo para uma enorme quantidade de exemplos em que o plasma fractal foi usado para produzir muitos efeitos interessantes.
Semeando ou Repetindo uma Imagem de Plasma
Lembre-se de que "plasma:" pode produzir áreas de preto quase puro ou branco puro, ou qualquer outra cor (embora não seja provável que seja pura). E embora seja improvável que você obtenha uma imagem toda de uma só cor, isso também é um resultado possível. Então, quando você obtém um bom resultado, pode querer salvá-lo para reutilizar depois. Por causa disso, scripts que usam imagens de plasma podem querer incluir opções para gerar e reutilizar tais imagens aleatorizadas. Ou seja, você pode querer separar a geração da imagem de plasma das outras partes que usam essa imagem, para permitir a reutilização. Uma técnica mais simples, no entanto, é 'semear' ou inicializar o gerador de números aleatórios do IM para que 'plasma:' gere a mesma imagem 'aleatorizada'. Dessa forma, você pode ajustar um script ou programa para produzir uma coloração ou efeito bom ou interessante, repetidamente. |
magick -size 100x100 -seed 4321 plasma: plasma_seeded.jpg
A imagem acima nunca mudará, então, a menos que eu mude o número de "[-seed](https://imagemagick.org/command-line-options/#seed)", sempre terei uma área 'vermelha' no canto inferior direito. Curiosamente, usar a mesma semente com diferentes gradientes de cor de inicialização pode produzir um conjunto de imagens que, embora aleatórias, são semelhantes em seu padrão interno.
magick -size 100x100 -seed 4321 plasma:grey-grey plasma_rnd1.jpg
magick -size 100x100 -seed 4321 plasma:white-blue plasma_rnd2.jpg
magick -size 100x100 -seed 4321 plasma:green-yellow plasma_rnd3.jpg
magick -size 100x100 -seed 4321 plasma:red-blue plasma_rnd4.jpg
magick -size 100x100 -seed 4321 plasma:tomato-steelblue plasma_rnd5.jpg
Como você pode ver, o mesmo padrão de cores está presente em todas as imagens acima, embora a base de cor subjacente possa realçar ou ocultar partes do padrão compartilhado. Apenas uma última palavra de aviso. Outros operadores do IM também podem usar o gerador de números aleatórios, como a função 'rand()' de "[-fx](https://imagemagick.org/command-line-options/#fx)", a configuração 'random' de "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)", o operador de pontilhamento "[-random-threshold](https://imagemagick.org/command-line-options/#random-threshold)" e o operador "[-noise](https://imagemagick.org/command-line-options/#noise)". Por isso, é uma boa ideia semear o gerador imediatamente antes do seu uso específico do gerador de números aleatórios. A partir do IM v6.3.4-3, você também pode re-aleatorizar o gerador usando "[+seed](https://imagemagick.org/command-line-options/#seed)". Assim, colocar essa configuração após seu 'plasma semeado' garantirá que quaisquer operadores posteriores gerem corretamente um resultado aleatorizado, se desejado. Por padrão, a semente é aleatorizada quando o IM inicia, então normalmente você não precisa aleatorizá-la você mesmo usando "[+seed](https://imagemagick.org/command-line-options/#seed)" para obter um resultado aleatório.
Problemas ao usar Plasma
Um problema que você deve evitar com imagens "plasma:" é gerá-las com uma proporção de aspecto alta. Isso tende a distorcer os efeitos normais de cor do plasma, esticando as cores em riscos semelhantes a agulhas.
magick -size 200x50 plasma: plasma_high_aspect.jpg
Não há solução simples para isso, então, a menos que seja isso o que você deseja, recomenda-se cautela. Há também uma distorção diagonal definida do canto superior esquerdo para o inferior direito na imagem de plasma que não deveria existir. Ou seja, há algum tipo de falha de 'viés espacial' no algoritmo. Por exemplo, como Thomas Maus
magick -size 60x60 plasma: \( +clone -flop \) +append plasma_flaw.jpg
Isso não deveria acontecer. Mas o problema parece ser profundo demais para ser corrigido sem basicamente reescrever completamente toda a função geradora de plasma.
Imagens Aleatórias
Ruído Aleatório Bruto
A partir do IM v6.3.5, você pode gerar uma imagem puramente aleatória a partir de uma imagem existente usando o Gerador de Ruído, "[+noise](https://imagemagick.org/command-line-options/#noise)" método 'Random'. |
magick -size 100x100 xc: +noise Random random.png
Se o seu IM for mais antigo que isso, você ainda pode gerar uma imagem de ruído puramente aleatória usando o mais lento Operador FX faça-você-mesmo, "[-fx](https://imagemagick.org/command-line-options/#fx)". |
magick -size 100x100 xc: -fx 'rand()' random_fx.png
Ou, por velocidade, você pode usar o operador "[-spread](https://imagemagick.org/command-line-options/#spread)" para aleatorizar um gradiente (separadamente para os três canais de cor) ou usando alguma outra imagem. |
magick -size 100x100 gradient: -separate \
-virtual-pixel tile -spread 200 -combine random_spread.png
O resultado pode parecer muito aleatório, mas produzirá uma faixa de cores mais controlada (ou apenas valores de cor).
Pontos Aleatórios (poeira de pixels)
Gerar imagens de pixels aleatórios espalhados também pode ser muito útil. . apenas lembre-se de que cada um dos três Canais de Cor de uma imagem aleatória pode ser pensado como uma imagem separada em tons de cinza aleatória, e esses canais podem ser mesclados de várias maneiras. Por exemplo, você gera uma máscara de pontos aleatórios primeiro aplicando um Limiar a um canal de cor ('G' ou o canal verde) e separando-o como uma imagem em tons de cinza. |
magick random.png -channel G -threshold 5% -separate \
+channel -negate random_mask.png
Como cada cor é um valor linearmente aleatório, a porcentagem de limiar usada acima define diretamente a densidade de pixels selecionados. Você pode ir além e usar um canal de cor ('G' ou canal verde) para selecionar valores aleatórios de outro canal de cor ('R' ou canal vermelho), usando vários métodos de Composição de Imagem.
magick random.png -channel G -threshold 5% -negate \
-channel RG -separate +channel \
-compose Multiply -composite random_black.png
magick random.png -channel G -threshold 5% \
-channel RG -separate +channel \
-compose Screen -composite random_white.png
magick random.png -channel G -threshold 5% -negate \
-channel RG -separate +channel \
-compose CopyOpacity -composite random_trans.png
Esses tipos de imagens são diretamente utilizáveis para gerar Animações de Brilho. Mas o processamento posterior, particularmente na versão de fundo preto, permitirá ampliar os pontos com base na intensidade em tons de cinza deles ou gerar riscos e/ou brilhos de estrela a partir desses pontos. Para exemplos, veja Geradores de Estrelas. Assim como nas Imagens de Plasma Semeadas, você também pode usar a configuração "[-seed](https://imagemagick.org/command-line-options/#seed)" para pré-inicializar o gerador de números aleatórios. Isso permite gerar a(s) mesma(s) imagem(ns) aleatória(s) de forma repetível para uma máquina específica, assim como você pode fazer para imagens de plasma.
Imagens Aleatórias Desfocadas (bolhas aleatórias)
Agora, embora você possa fazer uso direto de imagens aleatórias para criar efeitos pontilhados, imagens puramente aleatórias geralmente não são muito úteis. Mas ao Desfocar uma imagem puramente aleatória, você introduzirá alguma ordem de 'vizinhança', de modo que pixels próximos se tornam relacionados. Por exemplo, aqui eu desfoco apenas uma imagem aleatória, fazendo com que os valores aleatórios produzam 'bolhas' maiores ou cores manchadas.
magick random.png -virtual-pixel tile -blur 0x1 -auto-level random_1.png
magick random.png -virtual-pixel tile -blur 0x3 -auto-level random_3.png
magick random.png -virtual-pixel tile -blur 0x5 -auto-level random_5.png
magick random.png -virtual-pixel tile -blur 0x10 -auto-level
random_10.png
magick random.png -virtual-pixel tile -blur 0x20 -auto-level
random_20.png
Observe, no entanto, que sem a Configuração de Pixel Virtual o operador "[-blur](https://imagemagick.org/command-line-options/#blur)" terá fortes efeitos de borda, que é melhor evitar. Como bônus, ao mudar a configuração "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" para 'tile', a imagem aleatorizada permanece ladrilhável, com as cores envolvendo as bordas da imagem. Essa capacidade de ladrilhamento é algo que atualmente não é possível com Imagens de Plasma aleatórias e é um resultado inerente do fato de imagens puramente aleatórias serem tão aleatórias desde o início. Matizes Aleatórios Desfocados Uma conversão específica de uma imagem de ruído aleatório desfocado que achei particularmente agradável é mapear os valores em matizes de cor HSB. |
magick random_10.png -set colorspace HSB \
-channel GB -evaluate set 100% +channel \
-colorspace RGB random_hues_cyan.png
O problema com o acima é que o desfoque tenderá a criar manchas de vermelho-amarelo (valores baixos) e vermelho-magenta (valores altos), com faixas de verde, ciano e azuis entre elas. Isso é simplesmente uma consequência da forma como os valores de matiz foram desfocados e nivelados. A solução ideal para isso seria um tipo de desfoque-modular, que levaria em conta a natureza cíclica dos valores de Matiz. No entanto, tal operador não está disponível atualmente, e talvez nunca esteja. A melhor solução que conheço é simplesmente somar os três canais aleatórios na imagem (usando Composição Adição-Modular) para estender a faixa de valores. Isso também tem o efeito colateral de tornar as manchas desfocadas menores, mas pelo menos você agora obtém cores de arco-íris com uma faixa dinâmica maior. Alguém tem uma ideia melhor? |
magick random_10.png -separate -background white \
-compose ModulusAdd -flatten -channel R -combine +channel \
-set colorspace HSB -colorspace RGB random_hues.png
Para mais métodos de processamento de imagens aleatórias, veja Imagens de Plasma acima, bem como Gerando Fundos. Cinzas Aleatórios Desfocados Como você pode ver acima, você obtém uma imagem com várias bolhas de cores primárias. Isso ocorre porque cada canal está sendo processado completamente separado dos outros como imagens em tons de cinza. Vamos extrair um dos canais de cada uma das imagens acima para que você possa ver a estrutura da imagem desfocada...
magick random.png -channel G -separate random_0_gray.png
magick random_1.png -channel G -separate random_1_gray.png
magick random_3.png -channel G -separate random_3_gray.png
magick random_5.png -channel G -separate random_5_gray.png
magick random_10.png -channel G -separate random_10_gray.png
magick random_20.png -channel G -separate random_20_gray.png
A primeira coisa que você deve notar é que a imagem geralmente (mas nem sempre) conterá quantidades aproximadamente iguais de áreas pretas e brancas. Você pode ver isso se aplicarmos um Limiar às imagens aleatórias em 50%
magick random_0_gray.png -threshold 50% random_0_thres.png
magick random_1_gray.png -threshold 50% random_1_thres.png
magick random_3_gray.png -threshold 50% random_3_thres.png
magick random_5_gray.png -threshold 50% random_5_thres.png
magick random_10_gray.png -threshold 50% random_10_thres.png
magick random_20_gray.png -threshold 50% random_20_thres.png
Como você pode ver, você obtém aproximadamente 50% de áreas brancas e 50% de áreas pretas, separadas por uma linha curva. Além disso, a curva dessa linha varia de acordo com o valor 'sigma ' usado para o desfoque da imagem puramente aleatória. Desde pixels individuais gerando uma 'neve' preto e branco até você obter uma separação muito uniforme (embora ainda aleatória) da imagem em duas áreas preta e branca. Para mais exemplos de uso de imagens aleatórias, veja Imagens de Fundo ou, para dar uma olhada na geração de telas aleatorizadas, veja Pontos Aleatórios de Cor Sólida.
Granularidade Aleatória (ordem no caos)
Agora, lembre-se de que todas as imagens aleatórias desfocadas foram geradas a partir da mesma imagem aleatória inicial, portanto todas estão relacionadas. Mas cada nova imagem aleatória gerada terá um padrão completamente diferente, embora os padrões tenham, mais ou menos, uma estrutura semelhante. Mas primeiro vamos dar um exemplo completo de geração de uma 'imagem aleatória desfocada' do zero... |
magick -size 100x100 xc: -channel G +noise Random \
-virtual-pixel Tile -blur 0x5 -auto-level \
-separate +channel random_5_gray.png
O uso intenso da configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" para limitar as operações ao canal 'Verde' da imagem é importante, pois acelera a geração geral da imagem por um fator de 3. A separação de Canal então garantirá que obtenhamos um resultado em tons de cinza puros. Se quiser, você pode omitir ambas as configurações "[-channel](https://imagemagick.org/command-line-options/#channel)", o que resultará na geração de 3 'Imagens Aleatórias Desfocadas' completamente separadas e diferentes. A imagem tem algumas características importantes, que podemos ver mais claramente se dividirmos a imagem em três conjuntos iguais de cores (usando uma técnica chamada Posterização); você pode ver que dentro de cada uma das zonas preta e branca você obtém mais bolhas circulares ou 'grânulos'. Por exemplo... |
magick random_5_gray.png -ordered-dither threshold,3 random_5_blobs.png
Primeiro, gostaria de destacar como obtemos quantidades aproximadamente iguais de áreas claras e escuras dentro da imagem, mas que essas áreas estão interconectadas pelas cores cinza 'intermediárias' do gradiente que se forma entre as áreas claras e escuras. Agora, as bolhas individuais ou 'grânulos' variam de área para área ao longo da imagem, mas todos têm, em média, aproximadamente um diâmetro de cerca de três a quatro vezes o valor usado para desfocar a imagem aleatória inicial. Esse valor de desfoque é conhecido como a 'granularidade ' da imagem e é um valor muito importante, pois basicamente representa o tamanho médio das estruturas circulares que a imagem aleatória produz. Às vezes é chamado de 'curvatura' da imagem. Quanto maior o valor, maiores e mais lentas são essas curvas dentro da imagem. Este é o fator mais importante que descreve uma imagem Aleatória Desfocada, então vamos deixar isso bem claro...
A 'Granularidade ' de uma imagem aleatória (ou fator de desfoque) determina o tamanho das estruturas circulares dentro dela
Naturalmente, quanto menor o 'fator de desfoque' ou 'Granularidade ', menores ou mais estreitas as curvas se tornam, até você atingir um valor de '0', ponto no qual todo o agrupamento ou as 'bolhas' dentro da imagem desaparecem, e você fica apenas com um efeito puramente de 'ruído', 'neve' ou 'poeira de pixels' aleatório.
NOTA: Na verdade, o tamanho dos próprios 'grânulos' pode variar dependendo do fator de limiar usado para gerá-los. O que o fator realmente descreve é a distância média entre os centros das áreas brancas e pretas. Quanto maior o valor, maior a distância, e maiores e mais espalhadas as manchas precisam ser para acomodar essa distância aumentada. Isso fica mais evidente quando começamos a observar as Ondulações Aleatórias abaixo.
Você também pode gostar de tentar usar uma operação de Solarização a 50% com alguns Ajustes de Nível extras para extrair da imagem tanto os grânulos pretos quanto os brancos bem separados. Por exemplo, aqui está um exemplo completo com uma granularidade de '8' e um limiar de bolha de '25%' gerando manchas brancas a partir das partes pretas e brancas da imagem. |
magick -size 100x100 xc: -channel G +noise random \
-virtual-pixel tile -blur 0x8 -auto-level \
-solarize 50% -separate +channel \
-threshold 25% -negate random_granules.png
Fique avisado de que, à medida que o valor aumenta, o tempo para gerar a imagem aleatória desfocada também se torna muito, muito maior. Além disso, quando o valor atinge cerca de metade do tamanho da menor dimensão da imagem, o efeito para de crescer, pois a imagem aleatória se acomoda em uma única mancha branca e preta. Valores grandes não são recomendados.
Para encerrar, à esquerda é mostrada uma Animação de Ciclo de Patrulha resultante da variação da 'granularidade' (desfoque aleatório) de uma única imagem aleatória. A animação foi gerada usando o script de shell "[animate_granularity](../static/img/canvas/animate_granularity)", que você pode baixar, estudar e experimentar. Observe que, como a mesma imagem aleatória é usada como fonte, os 'grânulos' ou manchas não se movem de fato, mas apenas mais ou menos crescem juntos, ou se desvanecem, de modo a produzir 'grânulos' maiores com o aumento da granularidade. Lembre-se também de que, embora eu tenha reduzido o número de cores na animação, a estrutura da imagem aleatória completa é na verdade um gradiente suave entre dois conjuntos de grânulos brancos e pretos. Esse gradiente é o que torna a imagem útil em outras técnicas.
Fluxo Aleatório (ciclos de animação)
Agora, como você viu acima, os grânulos ou manchas não se movem de fato muito. Mas para efeitos de animação você quer um padrão que se mova suavemente no tempo. Além disso, você não quer que esse padrão apenas simplesmente se mova para frente e para trás. E, finalmente, você não quer que esse padrão de movimentos de repente salte ou dê um solavanco quando a animação repete. Então o que precisamos é de alguma forma de gerar um padrão aleatório que se repita suavemente. Uma tarefa e tanto. Além disso, como você precisa que ele seja suave, precisará gerar todos os padrões a partir da mesma imagem aleatória única. Aqui está uma ideia que permite gerar tal padrão aleatório. Em vez de pensar em cada valor de pixel aleatório como uma intensidade aleatória, pensamos nesse valor como um valor de 'tempo' que define quando aquele pixel está em sua intensidade máxima ou mínima. Ou seja, magick esse valor em uma posição em uma 'onda'. Assim, cada pixel representa alguma 'fase' de uma curva senoidal. Isso soa complicado, mas na realidade não é. Apenas usamos a Imagem Aleatória como imagem fonte para uma Função Senoidal. Agora, para cada imagem na sequência temporal, definimos a 'fase ' de tempo para aquele ponto específico no ciclo temporal.
magick random.png -function Sinusoid 1,_{time}_ \
... faz o desfoque granular e outros processamentos ...
Onde '_{time}_' vai de '0' a '360' ao longo do ciclo completo de animação. O resultado é que, em vez de cada pixel ter um valor aleatório 'estático', agora temos um que percorre um ciclo em laço entre preto e branco ao longo de um período de tempo. Cada pixel seguirá esse mesmo ciclo, mas como cada pixel tem uma 'fase' completamente diferente, ciclará independentemente de todos os outros pixels. Ou seja, a imagem continua aleatória, mas mudando suavemente com o valor de 'tempo' fornecido. Para os de mente científica, isso é um pouco como observar o 'fluxo quântico' que existe em nível subatômico, onde o espaço está longe do estado 'estático' que vemos em escalas normais. Daí o nome 'Fluxo Aleatório '. Por exemplo, vamos gerar uma sequência temporal de 12 imagens...
for i in `seq 0 30 359`; do
magick random.png -channel G -function Sinusoid 1,${i} \
-virtual-pixel tile -blur 0x8 -auto-level \
-separate flux_${i}.png
done
E sua única imagem aleatória agora pode gerar uma sequência inteira de imagens formando um ciclo. Observe que a extração do 'tempo' precisa acontecer antes de qualquer outro processamento, como o desfoque, que é provavelmente a parte mais lenta de todo o processo de geração. A outra coisa a notar é que, na fase '180' (canto inferior direito), você na verdade obtém o negativo exato da primeira imagem (canto superior esquerdo). Ou seja, os grânulos 'brancos' se tornaram grânulos 'pretos', e vice-versa. De fato, toda a segunda metade da animação é na verdade o negativo da primeira metade. Isso pode ser usado para reduzir o tempo de geração de uma animação simples de 'Fluxo Aleatório'. Como a imagem é um negativo em uma fase de 180 graus, você descobrirá que cada grânulo 'branco' lentamente se move de modo a trocar de lugar com um grânulo 'preto' vizinho. Mas como toda a segunda metade é um negativo da primeira, ele não pode simplesmente ir e voltar, mas deve continuar avançando para retornar à imagem original, ou circular em um laço, ou simplesmente se desvanecer e aparecer adequadamente. Em outras palavras, os grânulos brancos e pretos se movem em um ciclo muito mais complexo.
À direita está uma animação dos quadros acima... O padrão flutuante é completamente aleatório, mas muda suavemente de quadro para quadro, e quando a animação repete. Você não consegue ver começo nem fim no resultado. Às vezes você obtém um turbilhão de movimento, outras vezes parece que todas as bolhas parecidas com 'gás' estão sendo sugadas para uma zona escura, ou apenas aparecendo e se desvanecendo novamente. Você também obtém períodos de movimentos muito rápidos, bem como movimentos muito lentos. É totalmente aleatório. Em resumo : As mesmas propriedades presentes nas Imagens Aleatórias Desfocadas também estão presentes nesta animação. A imagem permanece uma divisão aproximadamente igual entre segmentos brancos e pretos, e forma bolhas de cerca de três vezes o tamanho do desfoque ou Granularidade da imagem. Mas além disso você tem garantido que todas as partes da imagem formarão algum ciclo entre cores mais claras e mais escuras, já que metade do ciclo é o negativo da outra metade. Uma coisa que você pode não ter notado é que, devido à conversão de um valor linear aleatório em uma forma de onda senoidal, você obterá uma separação de cores branca e preta mais nítida (contraste). Sendo assim, você pode gostar de usar o aspecto de redução de contraste do operador de Contraste Sigmoidal para tornar a imagem resultante menos parecida com 'bolhas' e realçar o gradiente entre os grânulos, em vez dos próprios grânulos. Ora, este é apenas um ponto de partida para o que você pode fazer com uma animação aleatória cíclica. Tudo que você pode fazer com uma Imagem Aleatória, como descrito em Gerando Fundos, também pode ser aplicado à 'Animação de Fluxo Aleatório ' Por exemplo, vamos apenas mostrar o movimento apenas dos grânulos 'brancos'... |
magick flux_anim.gif -threshold 70% flux_thres_anim.gif
Ou gere filamentos elétricos mutáveis que fluem lentamente sobre a imagem. |
magick flux_anim.gif \
-sigmoidal-contrast 30x50% -solarize 50% -auto-level \
-set delay 20 filaments_anim.gif
Observe que, devido ao fato de que metade do ciclo é uma negação da primeira metade e usamos uma Solarização para dobrar as cores branca e preta ao meio, o ciclo na verdade se repete duas vezes ao longo de um ciclo de animação. Realmente seriam necessários muito mais quadros para remover algumas das mudanças muito rápidas que estão ocorrendo.
Para tornar o movimento menos previsível em uma sequência cíclica mais longa, você também pode usar um pouco de Matemática de Gradiente para combinar múltiplos Ciclos Senoidais, de múltiplas imagens aleatórias, ou mesmo usando apenas os outros canais de cor da mesma imagem aleatória.
FUTURE: Create even less predictable, long time 'harmonic' cycles.
Ondulações Aleatórias
Ao adicionar outra variação a uma Imagem Aleatória Desfocada, podemos adicionar outro nível de complexidade que torna essas imagens muito mais úteis e nos dá outra variável de controle além de sua Granularidade. Mas primeiro você precisa lembrar que a imagem aleatória não consiste apenas em áreas claras e escuras, mas também contém uma inclinação entre essas áreas. Usando essa inclinação como entrada para a Função Senoidal, você pode gerar ondulações entre as manchas da imagem. Observe que a diferença fundamental deste uso da Função Senoidal em relação aos exemplos anteriores de Fluxo Aleatório foi que desta vez a função está sendo aplicada à imagem DEPOIS de ela ter sido suavizada usando desfoque, em vez de antes. Além disso, neste caso é o valor de 'Frequência ', e não o segundo valor de 'Fase ', que é mais importante. Por exemplo...
magick random_10_gray.png -function Sinusoid 1,90 ripples_1.png
magick random_10_gray.png -function Sinusoid 2,90 ripples_2.png
magick random_10_gray.png -function Sinusoid 3,90 ripples_3.png
magick random_10_gray.png -function Sinusoid 4,90 ripples_4.png
Como você pode ver, quanto maior a 'Frequência ' da Função Senoidal, mais ondulações são adicionadas ao gradiente entre os 'grânulos'. Uma 'Frequência ' de '1' basicamente magick tanto as 'bolhas' Claras quanto Escuras da imagem fonte para branco, e deixa uma lacuna escura entre elas. Uma 'Frequência ' de '2' comprime uma 'crista' ou 'ondulação' extra nessa lacuna escura. À medida que a frequência aumenta, você obtém mais e mais 'ondulações' entre as áreas mais claras e mais escuras da imagem original, tornando-a cada vez mais complexa. À medida que o número de cristas aumenta, você pode perder de vista as 'bolhas' ou 'grânulos' originais da imagem. Você pode corrigir isso modificando o gradiente antes de adicionar as ondulações, seja 'recortando' o gradiente usando um Ajuste de Nível, ou comprimindo os tons médios usando Contraste Sigmoidal. Isso dará aos 'grânulos' alguma massa ou área, proporcionando regiões de 'calma' entre as ondulações.
magick random_10_gray.png -level 25% random_enhanced.png
magick random_enhanced.png -function Sinusoid 4,90 ripples_4e.png
magick random_10_gray.png -sigmoidal-contrast 10,50% random_sigmoidal.png
magick random_sigmoidal.png -function Sinusoid 4,90 ripples_4s.png
Ambos os métodos têm vantagens e desvantagens, mas em essência eles aumentam os grânulos, embora não a distância entre os conjuntos de grânulos brancos e pretos. O efeito colateral disso é, naturalmente, uma compressão das ondulações entre os dois conjuntos de grânulos.
O segundo valor '90' usado nos exemplos acima é a 'Fase ' da Função Senoidal. Ele determinará a cor em que o grânulo 'preto' da imagem fonte se tornará na imagem 'ondulada'.
magick random_enhanced.png -function Sinusoid 3,0 ripples_3e000.png
magick random_enhanced.png -function Sinusoid 3,90 ripples_3e090.png
magick random_enhanced.png -function Sinusoid 3,180 ripples_3e180.png
magick random_enhanced.png -function Sinusoid 3,270 ripples_3e270.png
A cor do grânulo 'branco' dependerá tanto da 'Fase ' quanto da fração da 'Frequência ' que você aplicou. Um valor de 'Frequência ' inteiro fará com que tanto os grânulos brancos quanto os pretos variem de cor juntos (de acordo com a 'Fase '). Como tal, com uma fase de '90' ambos serão brancos. No entanto, se você aplicar um valor de 'Frequência ' fracionário de, digamos, '0.5', o grânulo de 'fonte branca' será o negativo do grânulo de 'fonte preta' (conforme determinado pela 'Fase '). |
magick random_enhanced.png -function Sinusoid 3.5,90 ripples_3.5e.png
Observe que, para os ângulos de 'Fase 'cinza', um dos grânulos é cercado por um anel branco, enquanto o outro é cercado por um anel preto. Se um valor de 'Frequência ' com uma fração de '0.5' for usado, a primeira ondulação ao redor de cada mancha será toda branca ou toda preta, dependendo da 'Fase ' usada. | _Outras 'Frequências' que não sejam inteiras, ou '0.5', não são recomendadas, pois os dois conjuntos de grânulos não estarão sincronizados de alguma forma.
Da mesma forma, Fases que não sejam múltiplos de 90 graus não são recomendadas, a menos que se esteja gerando uma 'animação de ondulações' (veja abaixo).
Um valor de Fase de '0' é recomendado ao gerar 'Mapas de Dispersão' (veja abaixo), pois isso causará distorções mínimas dentro das áreas de 'grânulo' realçadas.
---|---
Como anteriormente em Fluxo Aleatório, você pode modificar a '_Fase ' com o tempo de modo a gerar uma animação das ondulações se movendo de um conjunto de grânulos para o outro. Isso funciona particularmente bem sem qualquer realce de contraste. |
for i in `seq 0 30 359`; do
magick random_10_gray.png -function Sinusoid 3.5,${i} miff:-
done |
magick miff:- -set delay 15 -loop 0 ripples_anim.gif
NOTA: a técnica usada acima é conhecida como "MIFF: Encadeado" e é possível porque o formato de arquivo "MIFF:" pode simplesmente 'concatenar' imagens para gerar um arquivo de múltiplas imagens. Um ponto é que a animação parece mudar muito, muito mais lentamente que a Animação de Fluxo que criamos acima. Isso porque, ao longo de um ciclo de animação, uma ondulação percorrerá apenas uma curta distância, enquanto em uma animação de 'fluxo' a mudança percorrerá dos grânulos brancos aos pretos de grande escala em apenas metade do ciclo e de volta novamente. Agora você pode combinar a animação de ondulações acima com uma animação de 'fluxo' subjacente da mesma fonte de imagem aleatória para gerar uma forma muito mais dinâmica e fluida, mas fique avisado dessa diferença de velocidade de animação. Por exemplo, aqui eu apenas pego a Animação de Fluxo anterior criada acima e adiciono ondulações a ela. As ondulações, neste caso, se moverão apenas porque o gradiente na animação de fluxo se move. |
magick flux_anim.gif -function Sinusoid 3.5,0 flux_rippled_anim.gif
Você também pode animar as ondulações dentro da animação. Embora você possa precisar usar uma 'taxa de ciclo de fase' muito maior (a expressão 'j = 5 * i') para as próprias ondulações. Além disso, como você está gerando um ciclo dentro de um ciclo, precisará gerar uma animação muito mais longa, 60 quadros neste caso. No entanto, isso tem o benefício de desacelerar também os movimentos maiores de 'fluxo'. |
for i in `seq 0 10 359`; do
j=`expr $i \* 5`
magick random.png -channel G \
-function Sinusoid 1,${i} \
-virtual-pixel tile -blur 0x8 -auto-level \
-function Sinusoid 2.5,${j} \
-separate +channel miff:-
done |
magick miff:- -set delay 15 -loop 0 ripples_flux_anim.gif
Observe na segunda imagem como as ondulações parecem primeiro sair de um ponto, e depois começam a voltar para o mesmo ponto, embora nunca simplesmente invertam de direção. Um gerador de ciclo de fluxo multi-cíclico melhor deveria remover essa leve estranheza ao eliminar o efeito 'negativo' na animação de fluxo subjacente.
FUTURE: Use of Rippled Random Images for Dispersion Mapped Distortions.
Telas com Ladrilhos
Imagens de ladrilho podem ser muito grandes ou muito pequenas, são projetadas para se encaixar lado a lado e verticalmente para cobrir grandes áreas de espaço. Graças à World Wide Web, houve uma explosão de imagens de ladrilho disponíveis para uso (encontrar o que você quer é outra questão). Abaixo está um conjunto de imagens ladrilháveis que copiei da Biblioteca de Ícones do Anthony para uso ao longo destas páginas de exemplo.
bg.gif |
tile_aqua.jpg |
tile_water.jpg |
rings.jpg |
tile_disks.jpg |
tile_weave.gif
---|---|---|---|---|---
Atualmente existem várias maneiras pelas quais você pode ladrilhar uma imagem sobre uma grande área. Você pode "[-tile](https://imagemagick.org/command-line-options/#tile)" qualquer imagem de modo a substituir completamente a imagem de fundo original (usando o operador de composição "Copy"). (Para mais detalhes veja Composição de Ladrilhos). |
magick composite -tile tile_weave.gif -size 60x60 xc:none tile_copy.gif
Outra maneira é ler a imagem de ladrilho usando o codificador "tile:", e ladrilhá-la para um tamanho específico. |
magick -size 60x60 tile:bg.gif tile_size.gif
| _Observe que o codificador "tile:" substituirá qualquer transparência na imagem pela cor de fundo atual. Isso porque, internamente, ele gera uma tela do tamanho solicitado e 'sobrepõe' a imagem de ladrilho sobre essa tela.
Se você quiser preservar a transparência, defina "-background none" ou "-compose SRC" (veja Método de Composição Src para detalhes)._
---|---
Você pode usar isso para gerar uma imagem ladrilhada muito maior do que precisa, e então usar "[-composite](https://imagemagick.org/command-line-options/#composite)" para sobrepô-la sobre a imagem original. Se a imagem de ladrilho for parcialmente transparente, então um método "[-compose](https://imagemagick.org/command-line-options/#compose)" '[Over](compose.html#over)' precisará ser especificado. É um método de ladrilhamento muito lento, particularmente para imagens grandes, e você tem o problema de determinar exatamente quão grande uma imagem precisa criar para a sobreposição. |
magick test.png -size 200x200 tile:tile_disks.jpg \
-composite tile_over.gif
Ao especificar um ladrilho como 'padrão de preenchimento de ladrilho' para o operador "[-draw](https://imagemagick.org/command-line-options/#draw)", você pode desenhar a imagem de ladrilho sobre outra imagem, para criar qualquer forma ou figura que quiser. Isso porque a configuração "[-tile](https://imagemagick.org/command-line-options/#tile)" sobrescreverá qualquer configuração de cor "[-fill](https://imagemagick.org/command-line-options/#fill)" usada por draw. Veja Configurações de Desenho MVG. |
magick -size 60x60 xc: -tile tile_aqua.jpg \
-draw "circle 30,30 2,30" tile_draw.gif
Isso só funciona para "[-draw](https://imagemagick.org/command-line-options/#draw)" e operadores como "[-annotate](https://imagemagick.org/command-line-options/#annotate)" que também fazem uso de "[-draw](https://imagemagick.org/command-line-options/#draw)" para desempenhar sua função. Não funcionará para operadores de imagem que usam a cor "[-fill](https://imagemagick.org/command-line-options/#fill)" diretamente, como "[label:](text.html#label)", "[caption:](text.html#caption)" e "[text:](text.html#text)". No entanto, "[-draw](https://imagemagick.org/command-line-options/#draw)" tem embutidas nele algumas primitivas de cor especiais, como redefinir completamente todos os pixels da imagem para a cor de preenchimento ou o padrão de ladrilho (se definido). |
magick test.png -tile tile_water.jpg -draw "color 0,0 reset" \
tile_reset.gif
Este é na verdade exatamente o mesmo método usado por alguns métodos de Telas de Cor Sólida que usam uma Cor Específica. Só que aqui usamos "[-tile](https://imagemagick.org/command-line-options/#tile)" em vez de uma cor "[-fill](https://imagemagick.org/command-line-options/#fill)".
Um método mais avançado é usar um Operador de Distorção com uma configuração especial de Viewport de Distorção, que foi definida com o tamanho da imagem original (usando um Artefato Global Definido e Escapes de Porcentagem). Isso basicamente mapeia os Pixels Virtuais dos ladrilhos menores, que cercam a pequena imagem de ladrilho, para gerar a tela ladrilhada maior. |
magick rose: -set option:distort:viewport '%g' +delete \
tree.gif -virtual-pixel tile -filter point -distort SRT 0 \
tile_distort_sized.gif
Veja Ladrilhamento via Distorção (abaixo), onde examinaremos essa mesma técnica para ladrilhar uma imagem que já está na memória.
Telas de Ladrilhamento com Deslocamento
Às vezes você precisa de um pouco mais de controle sobre o posicionamento exato de uma textura de fundo, seja para alinhar um padrão de ladrilho com alguma outra imagem, ou para evitar uma correlação ruim com alguma outra parte da imagem final. Para muitos dos métodos padrão de ladrilhamento, isso pode ser obtido usando a configuração "[-tile-offset](https://imagemagick.org/command-line-options/#tile-offset)". Por exemplo, aqui eu rolo a imagem de ladrilho que está sendo usada para criar diretamente uma imagem de tela ladrilhada usando "tile:" ou "pattern:".
magick -size 80x80 -tile-offset +30+30 tile:rose: offset_tile.gif
magick -size 80x80 -tile-offset +20+20 \
pattern:checkerboard offset_pattern.gif
| A configuração Deslocamento de Ladrilho estava quebrada antes da versão IM 6.3.9-9, no sentido de que o deslocamento 'X' estava sendo usado tanto para os valores de deslocamento 'X' quanto 'Y' (o valor 'Y' fornecido era ignorado). Isso significa que, embora os exemplos acima tivessem funcionado (ambos os deslocamentos X e Y são iguais), você pode não obter os resultados esperados quando os dois valores diferem.
---|---
Isso também funciona para a configuração de fundo "[-texture](https://imagemagick.org/command-line-options/#texture)" do "magick montage". |
montage tree.gif -geometry +24+24 \
-tile-offset +30+30 -texture rose: offset_texture.gif
Você também pode usar a configuração definindo-a antes da configuração "[-tile](https://imagemagick.org/command-line-options/#tile)" ou "[-fill](https://imagemagick.org/command-line-options/#fill)". Por exemplo... |
magick -tile-offset +30+30 -tile rose: \
-size 80x80 xc: -draw 'color 30,20 reset' offset_tile_fill.gif
Certifique-se de que a configuração "[-size](https://imagemagick.org/command-line-options/#size)" seja redefinida antes de definir a imagem "[-tile](https://imagemagick.org/command-line-options/#tile)", mas depois que qualquer outra imagem tiver sido lida. |
magick -size 80x80 xc: \
-tile-offset +20+20 +size -tile pattern:checkerboard \
-draw 'color 30,20 reset' offset_pattern_good.gif
Em qualquer caso, provavelmente é melhor definir o deslocamento de ladrilho e a imagem de ladrilho logo antes de seu primeiro uso, o que tem o mesmo resultado que a solução acima.
Ladrilhamento com uma Imagem já na Memória
Ladrilhar uma imagem que você tem na memória (criada ou modificada) não é simples, e apenas alguns métodos indiretos estão disponíveis.
Clonar e Anexar a Imagem de Ladrilho
Se você não se preocupa com o tamanho exato da imagem ladrilhada, pode simplesmente anexar a imagem várias vezes. Por exemplo, aqui ladrilhamos a imagem em um arranjo 3x3. |
magick tree.gif \
\( +clone +clone \) +append \
\( +clone +clone \) -append \
tile_clone.gif
Este método de ladrilhamento tem a vantagem de permitir que você ladrilhe com espelhamento (ladrilho espelhado) a imagem. |
magick tree.gif \
\( +clone -flop +clone \) +append \
\( +clone -flip +clone \) -append \
tile_clone_flip.gif
Em geral, este método só é prático quando você tem alguma ideia de quão grande é a imagem sendo ladrilhada. Além disso, como clones são na verdade muito rápidos e eficientes, é um método de ladrilhamento bastante simples e rápido, especialmente se você usar os resultados para ladrilhar ainda mais a imagem maior.
Ladrilhamento usando MPR: (Registro de Programa em Memória)
Um método melhor é salvar a imagem em um formato de arquivo 'Em Memória' especial "[mpr:](files.html#mpr)", ou 'registro de programa em memória' nomeado. A partir desse registro, você pode então usar uma configuração "[-tile](https://imagemagick.org/command-line-options/#tile)", ou usar o leitor de arquivo de imagem especial "tile:", ambos os quais só podem ser definidos a partir de um formato de arquivo de imagem 'salvo'. Por exemplo, usando "tile:" para criar uma imagem ladrilhada de um tamanho específico... |
magick tree.gif -write mpr:tile +delete \
-size 100x100 tile:mpr:tile tile_mpr.gif
| Lembre-se de que o codificador "tile:" substituirá qualquer transparência na imagem pela cor de fundo atual. (veja acima)
---|---
Ou ladrilhe sobre uma imagem existente, definindo o padrão de preenchimento "[-tile](https://imagemagick.org/command-line-options/#tile)" ou "[-fill](https://imagemagick.org/command-line-options/#fill)", e usando "[-draw](https://imagemagick.org/command-line-options/#draw)" para fazer uma redefinição de cor (veja Primitivas de Preenchimento de Cor)... |
magick tree.gif -write mpr:tile +delete \
granite: -fill mpr:tile -draw 'color 0,0 reset' \
tile_mpr_reset.gif
| Se ladrilhar com uma imagem contendo transparência, garanta que a imagem de destino também tenha transparência usando "-alpha set". Se você não fizer isso, a imagem resultante mostrará a cor de transparência 'oculta' dos ladrilhos.
---|---
Ou desenhe usando alguma outra Primitiva de Desenho, como um círculo, usando o padrão de preenchimento. |
magick tree.gif -write mpr:tile +delete \
granite: -tile mpr:tile -draw 'circle 64,64 10,50' \
tile_mpr_fill.gif
O nome dado após "[mpr:](files.html#mpr)" pode ser qualquer coisa que você queira, é apenas um rótulo no nome do registrador 'mpr' usado para armazenar a imagem (na memória). Pode até ser um rótulo, um número, uma cor ou até mesmo um nome de arquivo.
Ladrilhamento usando pixels virtuais via Distort
Neste método usamos a Configuração de Pixel Virtual para gerar uma tela ladrilhada grande. Essa configuração define como a área ao redor da imagem real (fora dos limites normais da imagem) deve parecer. A maneira mais fácil de extrair pixels virtuais é usar o Operador Distort com uma configuração especial de Viewport de Distort. |
magick tree.gif -set option:distort:viewport 100x100+0+0 \
-virtual-pixel tile -filter point -distort SRT 0 \
tile_distort.gif
Você também tem acesso a outros estilos de configuração de ladrilhamento com pixels virtuais, como '[Mirror](misc.html#mirror)', ou até mesmo '[CheckerTile](misc.html#checker_tile)', e ainda um bom controle de deslocamento do ladrilhamento usando a configuração de viewport. |
magick tree.gif -set option:distort:viewport 100x100-10-10 \
-background firebrick -virtual-pixel CheckerTile \
-distort SRT 0 +repage tile_distort_checks.gif
Ao usar o Operador de Distorção Geral dessa forma, você também ganha o bônus adicional de distorcer a imagem ladrilhada de maneiras muito complexas. Você pode ver exemplos disso em Ladrilhamento Afim por Distort. Como exemplo mais complexo, aqui eu uso uma Distorção em Arco para ladrilhar a árvore ao redor da origem, que está centralizada no viewport. O '45' especifica o ângulo que a largura da árvore cobre, enquanto o '50' define o raio da borda superior do ladrilho da árvore. O resto simplesmente decorre disso. |
magick tree.gif -set option:distort:viewport 100x100-50-50 \
-virtual-pixel tile -distort Arc '45 0 50' +repage \
tile_distort_polar.gif
Modificando padrões/ladrilhos internos do IM
Veja a lista completa de Imagens e Padrões Internos do ImageMagick. Há muitos desses padrões, mas vou examinar apenas um ou dois aqui. Agora, os padrões internos são geralmente imagens muito, muito pequenas, que podem ser ladrilhadas para cobrir áreas grandes. No entanto, por si só têm aparência muito simples e são bastante inúteis. Por exemplo, aqui está um dos padrões maiores e mais interessantes que são fornecidos... |
magick pattern:checkerboard pattern_default.gif
As imagens de padrão são normalmente ladrilhadas sobre áreas maiores, seja como parte da criação da tela, definindo um "[-size](https://imagemagick.org/command-line-options/#size)", ou como um ladrilho de preenchimento (veja Telas Ladrilhadas acima). Sem uma configuração de tamanho, será usado o tamanho de ladrilho padrão do padrão, 30x30 pixels neste caso. Agora você provavelmente notará que todos os padrões atualmente fornecidos pelo IM são todos em preto e branco puro, com a única exceção do padrão 'checkerboard' que usei no último exemplo. Aqui está um padrão que eu particularmente gosto de usar como padrão de ladrilho... |
magick -size 60x60 pattern:hexagons pattern_hexagons.gif
Se você não está satisfeito com essas cores, pode substituí-las usando o operador de imagem "[-opaque](https://imagemagick.org/command-line-options/#opaque)". |
magick -size 60x60 pattern:hexagons \
-fill blue -opaque black -fill skyblue -opaque white \
pattern_colored.gif
Se você quiser colorir o padrão "checkerboard", isso é melhor feito primeiro usando "[-auto-level](https://imagemagick.org/command-line-options/#auto-level)" para mapear os dois cinzas para preto e branco antes de substituir essas duas cores. Aqui, em vez de usar "[-opaque](https://imagemagick.org/command-line-options/#opaque)" para substituir as cores, uso um operador "[+level-colors](https://imagemagick.org/command-line-options/#level-colors)" (adicionado no IM v6.2.4-1), que é um pouco mais simples de usar. |
magick -size 60x60 pattern:checkerboard -auto-level \
+level-colors red,blue pattern_color_checks.gif
Você também pode usar o operador "[-floodfill](https://imagemagick.org/command-line-options/#floodfill)" para colorir o padrão. No entanto, para que isso funcione corretamente, você precisa fazer isso antes de ladrilhar o padrão modificado. Neste caso, também preciso expandir o ladrilho três vezes para colori-lo com o padrão regular de cores que eu queria. |
magick -size 30x54 pattern:hexagons \
-fill tomato -opaque white \
-fill dodgerblue -draw 'color 10,10 floodfill' \
-fill limegreen -draw 'color 10,25 floodfill' \
-roll +15+27 \
-fill dodgerblue -draw 'color 10,10 floodfill' \
-fill limegreen -draw 'color 10,25 floodfill' miff:- |\
magick -size 100x100 tile:- pattern_color_hexagons.gif
Eu usei um pipeline de dois comandos acima para separar a criação do padrão colorido de seu uso real. Se você quiser fazer isso com um único comando, veja Ladrilhando uma Imagem na Memória acima. Você também pode deformar e distorcer um padrão de ladrilhamento simples para produzir variações interessantes. Por exemplo, um efeito de 'enrugamento' (técnica cortesia do efeito wrinkle do IM do Font Image Generator) sobre um padrão hexagonal que achei particularmente interessante |
magick -size 160x100 pattern:hexagons \
-wave 3x100 -background white -rotate 90 -wave 4x66 -rotate -87 \
-gravity center -crop 120x90+0+0 +repage pattern_distorted.gif
Modificando imagens de ladrilho
O maior problema que as pessoas enfrentam ao modificar ladrilhos, seja um ladrilho existente ou um dos padrões internos, é que muitas operações de imagem destroem a 'ladrilhabilidade' da imagem. Por exemplo, aqui peguei o padrão interno 'hexagon' e tentei modificá-lo para produzir um padrão sombreado em tons de cinza com linhas hexagonais largas. |
magick pattern:hexagons -rotate 90 \
-blur 0x1 -edge 1 -negate -shade 120x45 \
miff:- |\
magick -size 100x100 tile:- tile_mod_failure.jpg
O primeiro comando gera a 'imagem de ladrilho', enquanto o segundo de fato ladrilha a imagem, para que possamos ver como todos se encaixam. Como você pode ver, a imagem de ladrilho resultante NÃO se ladrilha corretamente, com distorções artificiais de borda claramente visíveis na imagem ladrilhada. Basicamente perdemos a uniformidade do ladrilho original, ao longo das bordas da imagem. Uma solução é usar uma configuração especial de Pixels Virtuais, usada para fazer os operadores pensarem que a imagem se enrola em torno das bordas, ao buscar cores que estão além dos limites da imagem real. |
magick pattern:hexagons -rotate 90 -virtual-pixel tile \
-blur 0x1 -edge 1 -negate -shade 120x45 \
miff:- |\
magick -size 100x100 tile:- tile_mod_vpixels.jpg
Aqui está outro exemplo em que junto dois padrões de ladrilho relacionados e uso vários efeitos para criar um ladrilho incomum de parede de tijolos. |
magick pattern:leftshingle pattern:rightshingle +append \
-virtual-pixel tile -blur 0x0.75 -resize 150% -shade 100x45 \
-fill Peru -tint 100% miff:- |\
magick -size 100x100 tile:- tile_slanted_bricks.jpg
Alternativa
Há uma alternativa a depender de Pixels Virtuais. Basicamente, nós mesmos fornecemos os 'pixels de borda virtuais' antes de operar sobre a imagem, de modo a evitar quaisquer efeitos de borda que possam estar presentes. E isso é feito ladrilhando primeiro a imagem sobre uma área ligeiramente maior. Após modificar a imagem, podemos reextrair o ladrilho, evitando as distorções de borda que foram introduzidas. Não precisa ser muito maior, dependendo da extensão das operações de imagem realizadas. Descobri que de 15 a 40 pixels deve deter todos os efeitos de borda no resultado final. Para reextrair a imagem, podemos "[-shave](https://imagemagick.org/command-line-options/#shave)" os pixels extras, ou "[-crop](https://imagemagick.org/command-line-options/#crop)" o tamanho original do ladrilho do meio da imagem processada. Por exemplo, aqui crio um efeito 3d de "[-shade](https://imagemagick.org/command-line-options/#shade)" usando o padrão interno 'hexagons'. |
magick -size 60x60 tile:pattern:hexagons -rotate 90 \
-blur 0x1 -edge 1 -negate -shade 120x45 \
-gravity center -crop 18x30+0+0 +repage miff:- |\
magick -size 100x100 tile:- tile_mod_success.jpg
Note que a posição exata do ladrilho extraído não importa. Uma imagem ladrilhável pode ser recortada de qualquer lugar da imagem ladrilhada, desde que esteja longe das bordas distorcidas e você use o mesmo tamanho original do ladrilho. Aqui, em vez de ladrilhar a imagem sobre uma área maior, usamos uma técnica de 'clone duplo' para dobrar a área que o ladrilho cobre. Ao terminar, então apenas recortamos o centro em 50% da imagem para recuperar nosso ladrilho modificado. Isso significa que não precisamos saber o tamanho exato do ladrilho que você está processando. |
magick pattern:circles \( +clone \) +append \( +clone \) -append \
-fill grey -opaque black -blur 0x0.5 -shade 120x45 \
-gravity center -crop 50% +repage miff:- |\
magick -size 100x100 tile:- tile_circles.jpg
Gerando imagens de ladrilho O maior problema que você enfrenta ao gerar imagens que podem ser ladrilhadas juntas é tentar fazer coincidir as bordas e os cantos da imagem para que possam se encaixar perfeitamente. Se isso não for feito, tudo o que você obtém é um conjunto de caixas quadradas, cada uma com uma cópia repetida da imagem. Isso não é uma tarefa fácil e pode ser uma experiência muito frustrante e de arrancar os cabelos. Um objeto que aparece no ladrilho em uma borda deve reaparecer no outro lado da imagem para reformar o todo quando a imagem é ladrilhada. Embora você possa fazer isso com relativa facilidade com imagens geradas por computador, é quase impossível produzir uma boa imagem de ladrilhamento com fotografias do mundo real. O outro grande problema é tentar fazer com que o ladrilho não pareça estar se repetindo. A única solução verdadeira para isso é tornar suas imagens de ladrilho grandes o suficiente para conter bastantes elementos muito semelhantes, mas ainda diferentes, de modo que se torne difícil ver um padrão repetido. Por essa razão, gerar ladrilhos pequenos que não pareçam se repetir é especialmente difícil.
FUTURE: Ideas and suggestions for generating tile patterns? Anyone?
Or roll, add element, roll, add element, etc...
Any and all suggestions and examples accepted.
Suggestions for generating tile from real photos of repeating patterns,
such as water, fallen leaves, clouds, stucco, brickwork, etc...
Generating Escher-like tile patterns.
Ladrilho de ruído aleatório
Como uma tela de ruído aleatório bruto não tem características de borda para começar (a cor de cada pixel é completamente independente de qualquer um de seus vizinhos), você pode ladrilhá-la sem se preocupar com distorções de borda. Basicamente ela é tão extremamente aleatória no nível de pixel que nenhuma borda coincide para começar, então não perdemos nada ao ladrilhar. Infelizmente, pouquíssimas situações usariam uma imagem de ruído aleatório bruto, tal como está, para algum propósito real. Ela é simplesmente tão terrivelmente aleatória que é inútil. No entanto, ao modificar a imagem preservando sua ladrilhabilidade inerente, podemos criar quase qualquer padrão de ladrilho aleatorizado que quisermos. Por exemplo, vamos olhar para um "[-blur](https://imagemagick.org/command-line-options/#blur)" básico do ladrilho original, usando a mesma técnica de 'modificar um ladrilho' que usamos no último exemplo. |
magick -size 64x64 xc: +noise Random \
-virtual-pixel tile -blur 0x6 -auto-level tile_random.jpg
magick -size 128x128 tile:tile_random.jpg tiled_random.jpg
Usando essa técnica, você pode aplicar quase qualquer transformação a uma imagem de ruído aleatório bruto. Por exemplo... |
magick -size 64x64 xc: +noise Random \
-virtual-pixel tile -blur 0x6 -edge 1 -fx G \
-shade 280x45 -auto-level tile_random_pits.jpg
magick -size 128x128 tile:tile_random_pits.jpg tiled_random_pits.jpg
Como você pode ver, é muito mais simples criar ladrilhos aleatorizados usando a imagem de ruído aleatório bruto, e você não terá nenhuma distorção de borda nos resultados. Essa transformação de imagem específica está listada na página Imagens de Fundo e é intitulada "pits". Veja essa página para muitas outras transformações aleatórias de imagem e exemplos de como elas se parecem.
Ladrilhamento hexagonal
Em vez de ladrilhar de forma quadrada, a imagem de 'ruído aleatório' nos permite gerar um tipo muito diferente de ladrilho. Ao dobrar as dimensões da imagem e reposicionar o ladrilho no espaço extra, mas deslocado pela metade, podemos gerar um padrão básico de ladrilho hexagonal de ruído aleatório. Esse é o mesmo tipo de efeito de ladrilhamento que obtemos quando ladrilhamos o interno especial "pattern:hexagons" do ImageMagick. |
magick pattern:hexagons tile_hexagons.gif
magick -size 64x64 pattern:hexagons tiled_hexagons.gif
Note, porém, que para este ladrilho parecer 'hexagonal', o ladrilho não pode ser um quadrado normal, nem mesmo um quadrado duplicado. O tamanho final do ladrilho precisa ser um retângulo. A proporção exata para este retângulo na verdade envolve números irracionais, o que não é muito bom para trabalho de imagem com uma matriz de pixels. No entanto, uma boa proporção prática é 4:3, que é usada pela maioria das imagens de computador e de câmeras digitais. Aqui sobrepomos a mesma imagem de 'ruído aleatório' (um retângulo com proporção 2:3) duas vezes extras para gerar o padrão básico de hexágonos (num retângulo 4:3). O ladrilho de ruído aleatório hex-ladrilhado é então transformado usando a transformação "paint_3s" da página Imagens de Fundo, para gerar um padrão de ladrilho hexagonal de aparência bastante agradável. |
magick -size 48x64 xc: +noise Random -write mpr:rand \
-extent 96x64 -page +48-32 mpr:rand -page +48+32 mpr:rand \
-flatten tile_hex_random.jpg
magick tile_hex_random.jpg -virtual-pixel tile -blur 0x10 -paint 3 \
-shade 280x45 -auto-level tile_hex_layered.jpg
magick -size 160x160 tile:tile_hex_layered.jpg tiled_hex_layered.jpg
Se você olhar o padrão que o ladrilho produz, verá que qualquer característica específica terá 6 cópias dessa mesma característica ao seu redor formando um círculo. Esse é o padrão 'hexagonal' que o ladrilho produz, mesmo que ele ainda seja ladrilhado no mesmo padrão 'quadrado' de todas as outras imagens de ladrilhamento. Uma variante do padrão 'hextile' acima é dobrar a imagem do ladrilho verticalmente, em vez de horizontalmente como fizemos acima. O resultado é que o padrão hexagonal será rotacionado em noventa graus. É, porém, ainda o mesmo tipo de padrão. | _Matematicamente, o exposto acima não está gerando um novoGrupo de Papel de Parede a partir de um ladrilho existente. Tanto a imagem original 'não hexagonal' quanto a versão final pertencem ao mesmo grupo de ladrilhamento 'p1 '.
O que na verdade estamos fazendo acima é converter um padrão de ladrilhamento de 'protoladrilho' em losango em um 'domínio fundamental' retangular maior, alinhado ortogonalmente, do mesmo padrão de ladrilhamento. Dessa forma você pode então ladrilhar a imagem usando um método de ladrilhamento padrão. ---|--- _Futuro: Inverter a imagem extra para gerar um padrão de ladrilhamento maior (grupo de ladrilhamento pmg ). Futuro: como recortar (mascarar) um hexágono de uma imagem para que ele se ladrilhe perfeitamente, sem lacunas ou sobreposições.
Ladrilhamento hexagonal triplo
Assim como fizemos ao colorir o padrão interno "hexagons" (Veja Modificando padrões/ladrilhos internos do IM acima), você pode criar três variantes diferentes do ladrilho inicial (com rotações, por exemplo) antes de remapeá-las para formar o ladrilho maior. Claro, assim como fiz ao colorir o padrão "hexagons", a imagem final do ladrilho precisará ser ampliada três vezes, de modo a gerar um padrão de ladrilho retangular repetido. As variações entre os três ladrilhos gerados não devem ser muito diferentes e devem sobreviver a qualquer pós-processamento, caso contrário você não obterá os benefícios da técnica. Isso significa que o ladrilho inicial também deve ser razoavelmente grande, para que quaisquer características distintas presentes sejam preservadas. Por exemplo, aqui pegamos um desenho de linha muito simples e o rotacionamos para produzir 3 variações semelhantes. Essas imagens rotacionadas são então ladrilhadas sete vezes sobre uma tela maior (6 vezes maior) para produzir o padrão hexagonal de imagem tripla. |
magick -size 24x24 xc: -draw "rectangle 3,11 20,12" tile_line.gif
magick tile_line.gif -gravity center \
\( +clone -rotate 0 -crop 24x18+0+0 -write mpr:r1 +delete \) \
\( +clone -rotate 120 -crop 24x18+0+0 -write mpr:r2 +delete \) \
-rotate -120 -crop 24x18+0+0 -write mpr:r3 +repage \
-extent 72x36 \( -page +0+0 mpr:r3 \) \
\( -page +24+0 mpr:r1 \) \( -page +48+0 mpr:r2 \) \
\( -page -12+18 mpr:r1 \) \( -page +12+18 mpr:r2 \) \
\( -page +36+18 mpr:r3 \) \( -page +60+18 mpr:r1 \) \
-flatten tile_hex_lines.jpg
magick -size 120x120 tile:tile_hex_lines.jpg tiled_hex_lines.jpg
O exposto acima, porém, só funciona para ladrilhar uma pequena forma no meio da imagem original. Não funciona bem para uma imagem geral. Para um ladrilhamento hexagonal de imagem geral também precisamos mascarar triângulos equiláteros. As peças são então rotacionadas para que as bordas do triângulo equilátero sejam espelhadas. Essa não é uma tarefa fácil.
Ladrilhamento com espelho diagonal
Aqui está uma maneira de pegar qualquer imagem quadrada e transformá-la com o magick em 8 imagens espelhadas em torno de um ponto central. Especificamente, estamos gerando um padrão de ladrilhamento complexo 'p4m '. Primeiro gero uma Imagem de Matiz Aleatório e, usando a metade inferior esquerda da imagem de origem, eu a espelho diagonalmente, depois horizontal e verticalmente. |
magick -size 50x50 xc: +noise Random -virtual-pixel Tile -blur 0x5 \
-auto-level -separate -background white \
-compose ModulusAdd -flatten -channel R -combine +channel \
-set colorspace HSB -colorspace RGB tile_diag_source.jpg
magick tile_diag_source.jpg \( +clone -transpose \) \
\( +clone -sparse-color voronoi '%w,0 white 0,%h black' \) \
-composite \
\( +clone -flop -chop 1x0 \) +append \
\( +clone -flip -chop 0x1 \) -append \
tile_diag_mirror.jpg
O espelho diagonal é gerado fazendo um Transpose e então usando uma máscara gerada com uma Cor Esparsa, Voronoi. Note que este espelho diagonal automaticamente compartilha uma linha de pixels ao longo do espelho da mesma forma, devido à geometria de pixel do quadrado. Também removo um conjunto de pixels ao longo da borda antes de criar os Flips e Flops verticais e horizontais. Também recomendo a remoção de outra linha e coluna de pixels ao longo das bordas superior e esquerda, antes de usar esta imagem como um 'ladrilho'. Você não precisa fazer isso, mas acho que fica melhor. Sem remover uma linha e uma coluna de pixels de borda, você obtém 'emendas' feias de pixels duplicados, onde as imagens se juntam. Uma alternativa é ladrilhar primeiro a imagem aleatória bruta e depois fazer a conversão de Padrão de Fundo; você tem menos probabilidade de obter uma 'aparência cortada' ao longo das linhas do espelho, mas sim uma transição mais suave. |
magick -size 51x51 xc: +noise Random \( +clone -transpose \) \
\( +clone -sparse-color voronoi '%w,0 white 0,%h black' \) \
-composite \
\( +clone -flop -chop 1x0 \) +append \
\( +clone -flip -chop 0x1 \) -append \
-chop 1x1 \
\
-virtual-pixel Tile -blur 0x5 -auto-level \
-separate -background white \
-compose ModulusAdd -flatten -channel R -combine +channel \
-set colorspace HSB -colorspace RGB tile_p4m.jpg
A primeira parte é a geração do 'ladrilhamento dos dados aleatórios'; na segunda metade eu transformo com o magick os dados aleatórios em um mapeamento de 'matizes'. Também adicionei o pixel extra à imagem inicial, que será posteriormente cortado conforme apropriado para gerar uma imagem de ladrilhamento.
Para uma introdução mais completa sobre imagens de ladrilhamento e a matemática por trás delas, veja Wikipedia: Grupo de Papel de Parede. O que exploramos acima é apenas alguns dos muitos padrões de ladrilhamento que você pode criar.
O 'p4g ' é quase exatamente o mesmo que o ladrilhamento 'p4m ' acima, mas usa rotações de 180 graus dos quadrados espelhados, em vez de usar flips, para gerar a imagem de ladrilhamento completa. No entanto, como as imagens não são unidas por espelhos, você não pode usar uma imagem existente como fonte do ladrilho, pois as bordas ficarão desconexas e descontínuas. Você pode, porém, ladrilhar os dados aleatórios brutos e depois processar a imagem de ladrilho resultante, para produzir um resultado suave. |
magick -size 50x50 xc: +noise Random \( +clone -transpose \) \
\( +clone -sparse-color voronoi '%w,0 white 0,%h black' \) \
-composite \
\( +clone -rotate -90 \) +append \
\( +clone -rotate 180 \) -append \
\
-virtual-pixel Tile -blur 0x5 -auto-level \
-separate -background white \
-compose ModulusAdd -flatten -channel R -combine +channel \
-set colorspace HSB -colorspace RGB tile_p4g.jpg
Note que, devido à natureza não espelhada do ladrilhamento, você não precisa remover a linha ou coluna duplicada de pixels das bordas antes de fazer o append. Embora não faça mal fazê-lo, se você quiser seguir o mesmo tipo de processo para ambos os casos.
![[IM Output]](../static/img/canvas/canvas_rose_red.gif)
![[IM Output]](../static/img/images/test.png)
![[IM Output]](../static/img/canvas/color_pick_draw.png)
![[IM Output]](../static/img/canvas/color_pick_distort.png)
![[IM Output]](../static/img/canvas/black_threshold.png)
![[IM Output]](../static/img/canvas/black_level.png)
![[IM Output]](../static/img/canvas/black_fx.png)
![[IM Output]](../static/img/canvas/black_evaluate.png)
![[IM Output]](../static/img/canvas/black_gamma.png)
![[IM Output]](../static/img/canvas/black_alpha.png)
![[IM Output]](../static/img/canvas/white_threshold.png)
![[IM Output]](../static/img/canvas/white_level.png)
![[IM Output]](../static/img/canvas/white_fx.png)
![[IM Output]](../static/img/canvas/white_evaluate.png)
![[IM Output]](../static/img/canvas/white_alpha.png)
![[IM Output]](../static/img/canvas/trans_compose.png)
![[IM Output]](../static/img/canvas/color_matte.png)
![[IM Output]](../static/img/canvas/trans_fx.png)
![[IM Output]](../static/img/canvas/trans_evaluate.png)
![[IM Output]](../static/img/canvas/trans_threshold.png)
![[IM Output]](../static/img/canvas/grey_level.png)
![[IM Output]](../static/img/canvas/gradient_range1.jpg)
![[IM Output]](../static/img/canvas/gradient_range2.jpg)
![[IM Output]](../static/img/canvas/gradient_range3.jpg)
![[IM Output]](../static/img/canvas/gradient_range4.jpg)
![[IM Output]](../static/img/canvas/gradient_range5.jpg)
![[IM Output]](../static/img/canvas/rgradient_range1.jpg)
![[IM Output]](../static/img/canvas/rgradient_range2.jpg)
![[IM Output]](../static/img/canvas/rgradient_range3.jpg)
![[IM Output]](../static/img/canvas/rgradient_range4.jpg)
![[IM Output]](../static/img/canvas/rgradient_range5.jpg)
![[IM Output]](../static/img/canvas/gradient_trans_colorize.png)
![[IM Output]](../static/img/canvas/gradient_arc.jpg)
![[IM Output]](../static/img/canvas/gradient_bird.jpg)
![[IM Output]](../static/img/canvas/gradient_colormap.jpg)
![[IM Output]](../static/img/canvas/gradient_rainbow.jpg)
![[IM Output]](../static/img/canvas/gradient_rainbow_2.jpg)
![[IM Output]](../static/img/canvas/gradient_rs_rainbow.jpg)
![[IM Output]](../static/img/canvas/gradient_interpolated.jpg)
![[IM Output]](../static/img/canvas/gradient_clut_recolored.jpg)
![[IM Output]](../static/img/canvas/gradient_clut.jpg)
![[IM Output]](../static/img/canvas/gradient_fx_x4.gif)
![[IM Output]](../static/img/canvas/gradient_inverse_alt.gif)
![[IM Output]](../static/img/canvas/gradient_shepards_alt.gif)
![[IM Output]](../static/img/canvas/gradient_inverse_RGB.png)
![[IM Output]](../static/img/canvas/gradient_inverse_RGB_Hue.gif)
![[IM Output]](../static/img/canvas/sparse_bary_triangle.png)
![[IM Output]](../static/img/canvas/sparse_bary_0.gif)
![[IM Output]](../static/img/canvas/sparse_bary_1.gif)
![[IM Output]](../static/img/canvas/sparse_bary_2.gif)
![[IM Output]](../static/img/canvas/sparse_bary_gradient_2.png)
![[IM Output]](../static/img/canvas/diagonal_gradient.jpg)
![[IM Output]](../static/img/canvas/diagonal_gradient_2.jpg)
![[IM Output]](../static/img/canvas/sparse_bary_two_point_wide.jpg)
![[IM Output]](../static/img/canvas/sparse_bilin_0.gif)
![[IM Output]](../static/img/canvas/sparse_bilin_1.gif)
![[IM Output]](../static/img/canvas/sparse_bilin_2.gif)
![[IM Output]](../static/img/canvas/sparse_inverse_near.png)
![[IM Output]](../static/img/canvas/sparse_inverse_far.png)
![[IM Output]](../static/img/images/figure.gif)
![[IM Output]](../static/img/canvas/shape_edge_in_lights.png)
![[IM Output]](../static/img/canvas/shape_in_lights.png)
![[IM Output]](../static/img/canvas/sparse_blur_simple.png)
![[IM Output]](../static/img/canvas/sparse_blur_layered.png)
![[IM Output]](../static/img/canvas/sparse_lines_near_source.gif)
![[IM Output]](../static/img/canvas/plasma1.jpg)
![[IM Output]](../static/img/canvas/plasma2.jpg)
![[IM Output]](../static/img/canvas/plasma3.jpg)
![[IM Output]](../static/img/canvas/plasma_range1.jpg)
![[IM Output]](../static/img/canvas/plasma_range2.jpg)
![[IM Output]](../static/img/canvas/plasma_range3.jpg)
![[IM Output]](../static/img/canvas/plasma_range4.jpg)
![[IM Output]](../static/img/canvas/plasma_range5.jpg)
![[IM Output]](../static/img/canvas/plasma_black.jpg)
![[IM Output]](../static/img/canvas/plasma_grey.jpg)
![[IM Output]](../static/img/canvas/plasma_white.jpg)
![[IM Output]](../static/img/canvas/plasma_yellow.jpg)
![[IM Output]](../static/img/canvas/plasma_tomato.jpg)
![[IM Output]](../static/img/canvas/plasma_steelblue.jpg)
![[IM Output]](../static/img/canvas/plasma_fractal1.jpg)
![[IM Output]](../static/img/canvas/plasma_fractal2.jpg)
![[IM Output]](../static/img/canvas/plasma_fractal3.jpg)
![[IM Output]](../static/img/canvas/plasma_swirl.jpg)
![[IM Output]](../static/img/canvas/plasma_grey0.jpg)
![[IM Output]](../static/img/canvas/plasma_grey1.jpg)
![[IM Output]](../static/img/canvas/plasma_grey2.jpg)
![[IM Output]](../static/img/canvas/plasma_grey3.jpg)
![[IM Output]](../static/img/canvas/plasma_grey4.jpg)
![[IM Output]](../static/img/canvas/plasma_grey5.jpg)
![[IM Output]](../static/img/canvas/plasma_grey6.jpg)
![[IM Output]](../static/img/canvas/plasma_grey7.jpg)
![[IM Output]](../static/img/canvas/plasma_grey8.jpg)
![[IM Output]](../static/img/canvas/plasma_grey9.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd1.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd2.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd3.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd4.jpg)
![[IM Output]](../static/img/canvas/plasma_rnd5.jpg)
![[IM Output]](../static/img/canvas/plasma_high_aspect.jpg)
![[IM Output]](../static/img/canvas/plasma_flaw.jpg)
![[IM Output]](../static/img/canvas/random_black.png)
![[IM Output]](../static/img/canvas/random_white.png)
![[IM Output]](../static/img/canvas/random_trans.png)
![[IM Output]](../static/img/canvas/random_1.png)
![[IM Output]](../static/img/canvas/random_3.png)
![[IM Output]](../static/img/canvas/random_5.png)
![[IM Output]](../static/img/canvas/random_10.png)
![[IM Output]](../static/img/canvas/random_20.png)
![[IM Output]](../static/img/canvas/random_0_gray.png)
![[IM Output]](../static/img/canvas/random_1_gray.png)
![[IM Output]](../static/img/canvas/random_3_gray.png)
![[IM Output]](../static/img/canvas/random_10_gray.png)
![[IM Output]](../static/img/canvas/random_20_gray.png)
![[IM Output]](../static/img/canvas/random_0_thres.png)
![[IM Output]](../static/img/canvas/random_1_thres.png)
![[IM Output]](../static/img/canvas/random_3_thres.png)
![[IM Output]](../static/img/canvas/random_5_thres.png)
![[IM Output]](../static/img/canvas/random_10_thres.png)
![[IM Output]](../static/img/canvas/random_20_thres.png)
![[IM Output]](../static/img/canvas/flux_0.png)
![[IM Output]](../static/img/canvas/flux_30.png)
![[IM Output]](../static/img/canvas/flux_60.png)
![[IM Output]](../static/img/canvas/flux_90.png)
![[IM Output]](../static/img/canvas/flux_120.png)
![[IM Output]](../static/img/canvas/flux_150.png)
![[IM Output]](../static/img/canvas/flux_330.png)
![[IM Output]](../static/img/canvas/flux_300.png)
![[IM Output]](../static/img/canvas/flux_270.png)
![[IM Output]](../static/img/canvas/flux_240.png)
![[IM Output]](../static/img/canvas/flux_210.png)
![[IM Output]](../static/img/canvas/flux_180.png)
![[IM Output]](../static/img/canvas/ripples_1.png)
![[IM Output]](../static/img/canvas/ripples_2.png)
![[IM Output]](../static/img/canvas/ripples_3.png)
![[IM Output]](../static/img/canvas/ripples_4.png)
![[IM Output]](../static/img/canvas/random_enhanced.png)
![[IM Output]](../static/img/canvas/ripples_4e.png)
![[IM Output]](../static/img/canvas/random_sigmoidal.png)
![[IM Output]](../static/img/canvas/ripples_4s.png)
![[IM Output]](../static/img/canvas/ripples_3e000.png)
![[IM Output]](../static/img/canvas/ripples_3e090.png)
![[IM Output]](../static/img/canvas/ripples_3e180.png)
![[IM Output]](../static/img/canvas/ripples_3e270.png)
![[IM Output]](../static/img/canvas/offset_tile.gif)
![[IM Output]](../static/img/canvas/offset_pattern.gif)
![[IM Output]](../static/img/canvas/tile_distort_polar.gif)
![[IM Output]](../static/img/canvas/pattern_distorted.gif)
![[IM Output]](../static/img/canvas/tile_slanted_bricks.jpg)