Exemplos do ImageMagick -- Transformações de Imagem
- Transformar imagens em botões em relevo ou rebaixados
- Adicionando uma Borda Interna
- Dispersão Aleatória de Pixels
- Transformação de Foto em Vinheta
- Transformação Polaroid Complexa
- Pintura a Óleo, manchas de cor
- Carvão, esboço artístico de uma cena
- Transformação em Esboço a Lápis
- Relevo (Emboss), criando uma impressão metálica
- Stegano, ocultando segredos dentro de uma imagem
- Criptografando os Dados da Imagem
- Pixelizar Imagens
- Grades de Pixels
- Detector de Bordas Canny
- Contornos de Borda a partir de Formas com Anti-Aliasing
- Contornos de Borda a partir de Formas em Bitmap
- Contornos usando um Conversor de Rasterizado para Vetor
- Detector de Linhas de Hough
- Formas Sombreadas com Máscara
- Imagens de Formas Sombreadas
- Arredondando as Bordas do Shade
- Criando Realces de Sobreposição
- Expressões FX como Escapes de Porcentagem
- Métodos Internos Semelhantes ao FX
-
Evaluate, Operações Matemáticas Simples
Set, Add, Subtract, Multiply, Divide * Funções Matemáticas do Evaluate
Pow, Log, Sin, Cos * Function, Evaluate com Múltiplos Argumentos
- Multiplicar Gradientes com Viés
- Somar Gradientes com Viés
- Modulação de Frequência
Essas operações produzem grandes mudanças na aparência geral da imagem, seja para efeitos visuais ou artísticos. Entretanto, embora a aparência geral da imagem tenha mudado, muitas vezes de forma dramática, a imagem original em si ainda permanece geralmente visível no resultado.
Transformações Artísticas
Bordas em Relevo ou Rebaixadas
O operador "[-raise](https://imagemagick.org/command-line-options/#raise)" é uma transformação de imagem tão simples que quase não chega a ser uma. Tudo o que ele faz é adicionar um realce em bisel retangular a uma imagem existente. |
magick rose: -raise 5 rose_raise.gif
![[IM Output]](../static/img/transform/rose_raise.gif)
Um efeito rebaixado invertido pode ser gerado usando a forma 'plus' do operador... |
magick rose: +raise 5 rose_sunken.gif
![[IM Output]](../static/img/transform/rose_sunken.gif)
Esse operador é um pouco parecido com emoldurar uma imagem, mas em vez de adicionar pixels extras como borda, o operador "[-raise](https://imagemagick.org/command-line-options/#raise)" recolore os pixels de borda da imagem. Isso o torna uma transformação de imagem. | Na verdade, o emolduramento de imagem é obtido adicionando uma borda e, em seguida, aplicando o raise sobre ela!
---|---
| O operador só funciona em imagens retangulares e falhará em imagens com fundo transparente, pois as modificações de cor também serão transparentes. Basicamente, é um operador um tanto tolo!
---|---
Adicionando uma Borda Interna
Em vez de colocar uma borda ao redor da parte externa da imagem, o usuário queria sobrepor uma borda diretamente sobre as bordas da própria imagem. Para obter esse efeito, a solução foi desenhar um retângulo que se alinha precisamente com as dimensões da imagem. Como a imagem interna "rose" mede 70×46 pixels, a sobreposição resultante corresponde exatamente a essas dimensões. |
magick rose: -fill none -stroke navy -strokewidth 11 \
-draw 'rectangle 0,0 69,45' inside_border.jpg
![[IM Output]](../static/img/transform/inside_border.jpg)
A largura da borda adicionada é controlada pelo "[-strokewidth](https://imagemagick.org/command-line-options/#strokewidth)" do retângulo. Ou seja,
{stroke width} = {border width} * 2 - 1
Assim, a borda de 6 pixels acima precisou de um "[-strokewidth](https://imagemagick.org/command-line-options/#strokewidth)" de 11. Se você não souber o tamanho da imagem, poderá aparar (shave) a imagem e então adicionar a borda normalmente. Isso é provavelmente mais fácil, embora talvez não tão versátil. |
magick rose: -bordercolor green -shave 6x6 -border 6x6 inside_border2.jpg
Dispersão Aleatória de Pixels
O "[-spread](https://imagemagick.org/command-line-options/#spread)" substitui cada pixel pela cor de uma cor aleatória próxima na imagem de origem. Essa seleção aleatória foi feita conforme o uso de Interpolação de Pixel e Configuração de Pixel Virtual. Por exemplo... |
magick -size 80x40 xc:red xc:blue -append -spread 5 spread_interpolated.png
![[IM Output]](../static/img/transform/spread_interpolated.png)
Se você examinar os pixels da imagem, verá que alguns pixels podem ter uma mistura de vermelho e azul. Ou seja, eles são interpolados, e não simplesmente dispersos ou trocados. Isso é mais pronunciado com valores de distância menores. Note também que o "[-spread](https://imagemagick.org/command-line-options/#spread)" também faz uso da Configuração de Pixel Virtual. |
magick -size 80x80 xc: -virtual-pixel black -spread 10 spread_virtual.png
![[IM Output]](../static/img/transform/spread_virtual.png)
Como você pode ver, obtém-se uma borda aleatória, em sua maior parte composta de pixels virtuais pretos puros, embora haja alguns pixels cinza interpolados a partir da fronteira entre os pixels reais da imagem e os pixels virtuais. Para obter um efeito de pixels dispersos mais tradicional, você pode evitar essa mistura de cores forçando a busca de cor de pixels específicos usando "[-interpolate](https://imagemagick.org/command-line-options/#interpolate) [Nearest](misc.html#nearest)". Para evitar os problemas com pixels virtuais e um possível 'viés de cor de borda', recomendo que você use "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel) [Mirror](misc.html#mirror)". Assim, este é um 'spread' aleatório de pixels mais tradicional... |
magick rose: -interpolate nearest -virtual-pixel mirror \
-spread 5 spread_rose.png
Em Construção
O principal problema com o exemplo acima é que você pode perder alguns dados de pixel da imagem. Ou seja, os pixels não são 'trocados', mas copiados aleatoriamente, o que significa que um pixel específico da imagem pode acabar duplicado ou perdido. A partir do IM v6.9.2-2, você pode usar "[+spread](https://imagemagick.org/command-line-options/#spread)" para realmente trocar os pixels dentro da imagem, o que significa que nenhum pixel da imagem será duplicado ou perdido. Todo pixel da imagem original ainda está presente, apenas deslocado para uma nova localização. Entretanto, devido à forma como os pixels são processados, os pixels podem sofrer uma 'dupla troca'. Ou seja, um pixel específico pode ser trocado, mas depois ser selecionado para ser trocado novamente com um pixel posterior. Isso significa que um pixel específico pode se deslocar mais do que o solicitado pelo argumento do spread. Essa dupla troca também significa que os pixels tendem a se dispersar mais em direção ao canto inferior direito. Esse movimento é, obviamente, equilibrado por um deslocamento menor de um grande número de pixels em direção ao canto superior esquerdo. Por exemplo, aqui eu dispersei os pixels com o original acrescentado à frente como referência. |
magick -size 40x40 xc:red xc:blue -append \
\( +clone +spread 5 \) +append spread_bias.png
![[IM Output]](../static/img/transform/spread_bias.png)
Note como alguns pixels vermelhos se dispersam mais para baixo, embora você também obtenha alguns pixels azuis se dispersando mais para cima do que o esperado (porém em direção ao lado esquerdo da imagem). Esse problema é mais pronunciado quando você usa um argumento de distância menor no spread. Uma solução para esse problema de dupla troca não é fácil, e estamos procurando um algoritmo de 'embaralhamento de área limitada' para resolvê-lo. Mas, por enquanto, você pode ao menos mitigar o viés direcional realizando o spread duas vezes, com a distorção Transverse (espelhamento diagonal do canto superior esquerdo para o inferior direito). |
magick -size 40x40 xc:red xc:blue -append \
\( +clone +spread 5 -transverse -spread 5 -transverse \) \
+append spread_no_bias.png
![[IM Output]](../static/img/transform/spread_no_bias.png)
Naturalmente, isso torna o spread mais pronunciado e menos linear, mas ao menos fica sem viés direcional ou duplicação/perda de pixels. A adição acima foi desenvolvida a partir de uma Discussão no Fórum: t=28043 Discussão no Fórum do IM rearrange vertical pixel row .
Transformação de Foto em Vinheta
Um operador especial para tornar uma imagem circular com um contorno suave e desfocado. |
magick rose: -background black -vignette 0x5 rose_vignette.gif
![[IM Output]](../static/img/transform/rose_vignette.gif)
Usando um sigma zero (ou muito pequeno), você pode remover o desfoque e gerar molduras em elipse ou oval. Entretanto, note que ele não usa de fato a maior elipse possível, então talvez você prefira fazê-lo manualmente. |
magick rose: -background black -vignette 0x0 rose_vignette_0.gif
![[IM Output]](../static/img/transform/rose_vignette_0.gif)
Você pode usá-lo com transparência (e no formato PNG)... |
magick rose: -alpha Set -background none -vignette 0x3 rose_vignette.png
![[IM Output]](../static/img/transform/rose_vignette.png)
Um método alternativo de argumento é usar um número muito grande para o segundo componente sigma e, então, usar o primeiro radius para definir a extensão do desfoque. Isso produz uma distribuição 'linear' em vez da distribuição gaussiana mais comum no desfoque da vinheta. |
magick rose: -background black -vignette 5x65000 rose_vignette_linear.gif
![[IM Output]](../static/img/transform/rose_vignette.gif)
Outra técnica para uma vinheta mais retangular, produzindo bordas suaves na imagem, é demonstrada em Miniaturas com Bordas Suaves.
Transformação Polaroid Complexa
Graças ao trabalho realizado por Timothy Hunter (famoso pelo RMagick), um operador de transformação "[-polaroid](https://imagemagick.org/command-line-options/#polaroid)" foi adicionado ao IM v6.3.2.
Polaroid® é uma marca registrada da Polaroid Corporation.
Por exemplo, aqui eu dou um visual polaroid a uma miniatura de foto. A imagem mostra a vista para cima da escada em espiral (para baixo), no interior do Arco do Triunfo, Paris. É uma escada muito longa!. |
magick spiral_stairs_sm.jpg -thumbnail 120x120 \
-bordercolor white -background black +polaroid poloroid.png
![[IM Output]](../static/img/transform/poloroid.png)
| Note que a imagem resultante tem uma sombra semitransparente, então você terá que usar uma imagem no formato PNG ou aplicar "[-flatten](https://imagemagick.org/command-line-options/#flatten)" no resultado sobre uma cor de fundo fixa para os formatos GIF ou JPG.
---|---
Esse operador é muito complexo, pois adiciona uma borda (conforme a configuração "[-bordercolor](https://imagemagick.org/command-line-options/#bordercolor)"), 'enrola' o papel e adiciona um enrolamento inverso à sombra. A cor da sombra pode ser controlada pela configuração de cor "[-background](https://imagemagick.org/command-line-options/#background)". Como você viu acima, a forma 'plus' do operador irá rotacionar o resultado por uma quantidade aleatória. Esse operador torna um Índice de Fotos muito mais interessante e menos estático do que você obteria de outra forma. A forma 'minus' do operador permite controlar o ângulo de rotação da imagem. |
magick spiral_stairs_sm.jpg -thumbnail 120x120 \
-bordercolor AliceBlue -background SteelBlue4 -polaroid 5 \
poloroid_5.png
![[IM Output]](../static/img/transform/poloroid_5.png)
Se a imagem tiver metadados "[-caption](https://imagemagick.org/command-line-options/#caption)", esse texto também será adicionado na borda inferior da moldura polaroid, por meio do operador de criação de imagem "[caption:](text.html#caption)". Ou seja, ele será quebrado em linhas conforme a largura da foto. |
magick -caption '%c %f\n%wx%h' spiral_stairs_sm.jpg -thumbnail 120x120 \
-bordercolor Lavender -background gray40 +polaroid \
poloroid_captioned.png
![[IM Output]](../static/img/transform/poloroid_captioned.png)
As outras configurações de texto padrão (conforme "[caption:](text.html#caption)") permitem controlar a aparência da legenda adicionada. |
magick spiral_stairs_sm.jpg -thumbnail 120x120 -font Candice -pointsize 18 \
-bordercolor Snow -background black -fill dodgerblue -stroke navy \
-gravity center -set caption "Spiral Stairs\!" -polaroid 10 \
poloroid_controls.png
![[IM Output]](../static/img/transform/poloroid_controls.png)
| _O atributo de metadados de imagem "[-caption](https://imagemagick.org/command-line-options/#caption)" foi usado devido ao uso interno do gerador de texto para imagem "[caption:](text.html#caption)".
Por outro lado, o comando "[montage](montage.html#montage)" do IM usa "[-label](https://imagemagick.org/command-line-options/#label)", pois utiliza o gerador de texto para imagem "[label:](text.html#label)", que não faz quebra de linha._
---|---
O uso das distorções de cisalhamento Rotate e Wave pela transformação, para adicionar um pequeno 'enrolamento' à imagem da foto, tem a tendência de produzir linhas horizontais de imprecisão no texto da imagem gerada. Esse é um problema bem conhecido de Distorção de Imagem (veja Rotacionando uma Linha Fina), e um que pode ser resolvido usando uma técnica de super amostragem. Basicamente, geramos a polaroid com o dobro do tamanho que realmente queremos e, então, simplesmente redimensionamos a imagem para seu tamanho final normal. A redução do tamanho da imagem efetivamente aguça a imagem resultante e, mais importante, o texto da legenda. Entretanto, para que isso funcione, não só precisamos de uma imagem com pelo menos o dobro do tamanho final, mas também podemos precisar de uma borda maior na imagem e desenhar o texto com o dobro de sua "[-density](https://imagemagick.org/command-line-options/#density)" normal. Não aumente o "[-pointsize](https://imagemagick.org/command-line-options/#pointsize)" da fonte, pois isso não amplia o texto exatamente da mesma forma. |
magick -caption 'Spiral Staircase, Arc de Triumph, Paris, April 2006' \
spiral_stairs_sm.jpg -thumbnail 240x240 \
-bordercolor Lavender -border 5x5 -density 144 \
-gravity center -pointsize 8 -background black \
-polaroid -15 -resize 50% poloroid_modified.png
![[IM Output]](../static/img/transform/poloroid_modified.png)
Como você pode ver, mesmo tendo usado uma fonte com pointsize muito menor, o texto da legenda fica muito nítido, claro e legível. O mesmo vale para qualquer outro detalhe fino que possa estar presente na imagem original. A única desvantagem disso é que a sombra da imagem resultante será menor e menos difusa. Para controle total da transformação polaroid, você pode realizar sozinho todos os passos envolvidos. A técnica original está documentada na página de Tim Hunter, RMagick Polaroid Effect. Os passos são: criar e acrescentar a legenda, adicionar bordas, enrolar a foto com wave, adicionar uma sombra com enrolamento invertido e, por fim, rotacionar a imagem. Para mais exemplos e outros métodos manuais, veja Exemplos de Miniaturas Polaroid e Uma Montagem de Fotos Polaroid. Você também pode se interessar por alguns dos exemplos polaroid em RubbleWeb IM Examples, Other.
Pintura a Óleo, manchas de cor
O operador "[-paint](https://imagemagick.org/command-line-options/#paint)" foi projetado para transformar figuras em pinturas feitas aplicando 'manchas' espessas de tinta a uma tela. O resultado é a fusão das cores vizinhas em áreas maiores de uma única cor.
magick rose: -paint 1 rose_paint_1.gif
magick rose: -paint 3 rose_paint_3.gif
magick rose: -paint 5 rose_paint_5.gif
magick rose: -paint 10 rose_paint_10.gif
magick rose: -blur 0x3 -paint 10 rose_blur_paint_10.gif
Note que, com um raio alto para as manchas de tinta, elas começam a ganhar uma aparência quadrada. Esse efeito pode ser suavizado um pouco desfocando levemente a imagem antes, como mostrado na última imagem acima. É um efeito interessante e poderia ser usado para criar imagens de fundo estranhas e maravilhosas. Por exemplo, veja seu uso em Exemplos de Fundo. Um aviso final. Embora o "[-paint](https://imagemagick.org/command-line-options/#paint)" deva produzir áreas de uma única cor sólida, com valores de raio grandes ele tem a tendência de produzir um gradiente vertical em algumas áreas. Isso é muito irritante e pode ser um bug. Alguém sabe? Existem alternativas ao uso do "[-paint](https://imagemagick.org/command-line-options/#paint)". Uma é usar "-statistic Mode", que atribui a cada pixel a 'cor predominante' dentro da vizinhança retangular dada e pode produzir um resultado mais agradável. |
magick rose: -statistic Mode 10 rose_paint_mode.gif
![[IM Output]](../static/img/transform/rose_paint_mode.gif)
Outra é usar alguns dos Métodos de Morfologia e, mais especificamente, a Variante de Intensidade para Imagens Coloridas. Aqui, por exemplo, está uma morfologia 'OpenIntensity' na rosa. |
magick rose: -morphology OpenI Disk rose_paint_open.gif
![[IM Output]](../static/img/transform/rose_paint_open.gif)
E aqui eu uso 'CloseIntensity' com um 'Disk' ligeiramente menor. |
magick rose: -morphology CloseI Disk:2.5 rose_paint_close.gif
![[IM Output]](../static/img/transform/rose_paint_close.gif)
Você não precisa usar 'discos', mas pode projetar seu próprio núcleo em formato de 'pincel' para as manchas que ele cria. Por exemplo, que tal usar um pincel de linha diagonal.
Carvão, esboço artístico de uma cena
O efeito de carvão pretende simular um esboço a carvão feito por um artista a partir da imagem dada. O operador "[-charcoal](https://imagemagick.org/command-line-options/#charcoal)" é, em alguns aspectos, semelhante às transformações de detecção de bordas usadas pela Visão Computacional. Basicamente, ele tenta transformar as principais fronteiras e bordas dos objetos da imagem em tons de lápis e carvão. O único argumento supostamente representa a espessura das linhas de borda.
magick rose: -charcoal 1 rose_charcoal_1.gif
magick rose: -charcoal 3 rose_charcoal_3.gif
magick rose: -charcoal 5 rose_charcoal_5.gif
| Para um exemplo melhor de uso de uma transformação de carvão em uma imagem real, veja Esboço a Carvão de uma Foto. | Tecnicamente, o operador "[-charcoal](https://imagemagick.org/command-line-options/#charcoal)" é um operador "[-edge](https://imagemagick.org/command-line-options/#edge)" com alguma limiarização aplicada a uma conversão em escala de cinza da imagem original. |
|---|---|
Transformação em Esboço a Lápis
O operador "[-sketch](https://imagemagick.org/command-line-options/#sketch)" basicamente aplica um padrão de traços de linha a uma imagem para gerar algo que parece um esboço artístico a lápis. Os argumentos controlam o comprimento e o ângulo dos traços. Entretanto, ele é melhor aplicado a uma imagem maior com sombreamentos distintos. Veja Esboço a Lápis para um exemplo completo desse operador e de como ele funciona internamente.
Relevo (Emboss), criando uma impressão metálica
O operador "[-emboss](https://imagemagick.org/command-line-options/#emboss)" tenta gerar o efeito de uma impressão a ácido de uma imagem em escala de cinza sobre uma folha de metal. Ele é, em muitos aspectos, muito semelhante ao operador "[-shade](https://imagemagick.org/command-line-options/#shade)" que veremos abaixo, mas sem as bordas com aparência 3D. Seu argumento é um radius/sigma, com apenas o sigma sendo importante. Não achei o argumento muito útil e, na verdade, ele pode estar com bug. O argumento também mudou em uma versão recente do IM. Simplesmente não sei o que está acontecendo. Ajude-me a entender, se puder.
magick rose: -emboss 0x.5 rose_emboss_0x05.gif
magick rose: -emboss 0x.9 rose_emboss_0x09.gif
magick rose: -emboss 0x1 rose_emboss_0x10.gif
magick rose: -emboss 0x1.1 rose_emboss_0x11.gif
magick rose: -emboss 0x1.2 rose_emboss_0x12.gif
magick rose: -emboss 0x2 rose_emboss_0x20.gif
O operador é um operador de escala de cinza, o que significa que será aplicado aos três canais de cor separadamente. Por isso, deve ser aplicado apenas a imagens em escala de cinza. Como você viu acima, imagens coloridas podem produzir alguns efeitos estranhos.
magick rose: -colorspace Gray -emboss 0x.5 rose_g_emboss_0x05.gif
magick rose: -colorspace Gray -emboss 0x.9 rose_g_emboss_0x09.gif
magick rose: -colorspace Gray -emboss 0x1 rose_g_emboss_0x10.gif
magick rose: -colorspace Gray -emboss 0x1.1 rose_g_emboss_0x11.gif
magick rose: -colorspace Gray -emboss 0x1.2 rose_g_emboss_0x12.gif
magick rose: -colorspace Gray -emboss 0x2 rose_g_emboss_0x20.gif
Se alguém souber exatamente o que o algoritmo de emboss deveria fazer,
por favor me avise.
Stegano, ocultando uma imagem secreta dentro de uma imagem
O operador "[-stegano](https://imagemagick.org/command-line-options/#stegano)" é, na verdade, mais um operador 'divertido'. Por exemplo, ele poderia ser usado por um espião para esconder informações no 'caos' de uma imagem aleatória. Primeiro, um aviso...
Não use JPEG, GIF ou qualquer outra codificação de imagem 'com perdas' com o Stegano
Por exemplo, vamos gerar uma mensagem criptográfica (imagem) que você deseja enviar ao seu colega espião... | |
magick -gravity center -size 50x40 label:"Watch\nthe\nPidgeon" message.gif
magick identify message.gif
Note que também precisaremos do tamanho da imagem da mensagem (36x43 pixels), daí o identify acima. Em seguida, coloque-a dentro de alguma imagem com um deslocamento. O deslocamento (e o tamanho da mensagem) usado é a 'chave' criptográfica da mensagem oculta. |
magick composite message.gif rose: -stegano +15+2 rose_message.png
![[IM Output]](../static/img/transform/rose_message.png)
Agora você pode enviar essa imagem ao seu companheiro, que presumivelmente já conhece o tamanho e o deslocamento da mensagem. Podemos então recuperar a mensagem oculta na imagem... |
magick -size 50x40+15+2 stegano:rose_message.png message_recovered.gif
![[IM Output]](../static/img/transform/message_recovered.gif)
Quanto maior a imagem que contém a mensagem, melhor será a imagem recuperada, então esconder imagens pequenas em imagens maiores é melhor do que o exemplo mostrado acima. Só para mostrar como a mensagem oculta foi distribuída por toda a imagem contêiner, vamos fazer uma comparação da imagem combinada com a original. | |
magick compare -metric PAE rose: rose_message.png rose_difference.png
O que mostra como a imagem da mensagem foi criptografada e distribuída por toda a imagem contêiner para ocultá-la. Além disso, a métrica 'PAE' retornada acima mostra que a maior diferença foi de apenas um único valor de cor entre os valores de cor de 8 bits usados para esta imagem. Ou seja, minúscula. Tão minúscula que uma pequena alteração ou modificação na imagem destruirá a mensagem oculta dentro dela. É uma diferença tão pequena que você não pode nem usar JPEG com sua compressão com perdas como formato de imagem, nem qualquer outro formato de imagem com perdas (incluindo GIF) para a imagem contêiner. Além disso, se você tivesse a 'chave de deslocamento' errada, não obteria a mensagem... |
magick -size 50x40+14+2 stegano:rose_message.png message_bad.gif
![[IM Output]](../static/img/transform/message_bad.gif)
Você também pode limitar em qual área da imagem a mensagem deve ser ocultada usando uma configuração de Região. A mesma configuração também será necessária ao tentar recuperar a mensagem. Isso provavelmente tornaria a localização e a decodificação da mensagem oculta em uma imagem grande uma ordem de magnitude mais difícil de determinar, especialmente se restrita a uma área 'movimentada'. Entretanto, esteja avisado de que esta não é uma técnica muito segura do ponto de vista criptográfico. Especialmente se a imagem de origem original também estiver disponível. A análise de frequência da imagem geralmente permitirá que um atacante saiba que há uma mensagem oculta. Como método de proteção de direitos autorais de imagem, o Operador Stegano também é inútil, pois a menor alteração na imagem destruirá a mensagem e, portanto, sua eficácia. Como ferramenta de espionagem, também não é muito boa, com um número tão pequeno de 'combinações' para uma imagem de tamanho razoável. Qualquer um que saiba aproximadamente o que você está fazendo provavelmente conseguiria quebrá-la rapidamente. É melhor ater-se a métodos criptográficos bem conhecidos e testados ao longo do tempo. Seu único uso realmente prático é como uma ferramenta divertida ou como uma forma de adicionar quantidades muito pequenas de ruído a uma imagem existente.
Criptografando os Dados da Imagem
Os operadores "[-encipher](https://imagemagick.org/command-line-options/#encipher)" e "[-decipher](https://imagemagick.org/command-line-options/#decipher)" basicamente criptografam os dados da imagem em uma bagunça embaralhada. Ou seja, o próprio conteúdo da imagem deixa de ser reconhecível até que a imagem seja posteriormente descriptografada. Isso pode ser usado, por exemplo, para proteger imagens sensíveis em serviços públicos, de modo que apenas outras pessoas com a frase secreta possam visualizá-la posteriormente. Mas primeiro, um aviso...
Não use JPEG, GIF ou qualquer outra codificação de imagem 'com perdas' com a Criptografia
Por exemplo, vamos criptografar aquela imagem de mensagem secreta que criamos acima, usando uma frase secreta que salvei em um arquivo não tão 'secreto', "pass_phrase.txt".
magick message.gif -encipher pass_phrase.txt \
-depth 8 png24:message_hidden.png
| _A imagem criptografada assume que é salva usando um formato de arquivo de imagem de 8 bits. Por isso, recomenda-se impor essa limitação definindo "[-depth](https://imagemagick.org/command-line-options/#depth) 8" antes de salvar no arquivo de saída final.
O "png24" também foi necessário acima para garantir que a saída não seja uma imagem "png8:" de paleta ou com mapa de cores, o que também não funciona corretamente._
---|---
Como você pode ver, a imagem resultante parece um completo lixo, sem nenhuma indicação do conteúdo real da imagem. Agora você pode publicar essa imagem na web, e apenas alguém que conheça exatamente a frase secreta original poderá restaurar os dados da imagem... |
magick message_hidden.png -decipher pass_phrase.txt message_restored.gif
![[IM Output]](../static/img/transform/message_restored.gif)
Entretanto, esteja avisado de que, se os dados da imagem forem corrompidos de alguma forma, você não conseguirá restaurá-la. Isso inclui se o PNG for salvo usando um tipo de formato de imagem em escala de cinza. Por isso, apenas um formato de imagem sem perdas pode ser usado, como PNG, MIFF, TIFF ou até mesmo Texto de Enumeração de Pixel. Entretanto, usar um formato de imagem com perdas, como JPEG, PNG8 e GIF, corromperá os dados da imagem e, assim, destruirá a criptografia resultante. Note que quaisquer metadados que possam descrever a imagem ainda ficarão em texto claro. Isso significa que você poderia criptografar imagens usando a própria string de 'comentário' da imagem como frase secreta, ou usar esse comentário criptografado com alguma senha menor. É uma ideia simples que poderia tornar a frase secreta mais variável. Criptografar uma imagem pode ser apenas um passo. Levar o resultado só mais um pouco adiante pode produzir uma imagem que não será simplesmente descriptografada sem algum processamento extra. Por exemplo, aqui eu uso algumas Distorções Simples Não Destrutivas para confundir quem tentar descriptografar a imagem da maneira normal.
echo "password" | magick message.gif -encipher - \
-transpose -depth 8 png24:message_obfuscate.png
echo "password" | magick message_obfuscate.png -transpose \
-decipher - message_restored_2.png
Se você não incluísse o "[-transpose](https://imagemagick.org/command-line-options/#transpose)" no comando de descriptografia acima, a imagem não teria sido decifrada corretamente. Note também que, devido à cifra de fluxo usada (veja a nota de especialista abaixo), usar apenas algum tipo de "[-roll](https://imagemagick.org/command-line-options/#roll)" não impedirá que a imagem seja descriptografada, ao menos parcialmente. Note que, no exemplo acima, não usei um arquivo para armazenar a 'frase secreta', mas alimentei a frase no comando "magick" usando a entrada padrão, o que permite usar algum outro programa ou comando para obter a frase do usuário, gerá-la ou algum outro método, em vez de usar um arquivo de texto com a frase secreta em texto claro. A frase secreta também poderia ser gerada a partir de outros arquivos e imagens de download livre. Por exemplo, você poderia descriptografar sua imagem usando a assinatura ou a string de comentário de uma imagem de referência bem conhecida e de download livre. Por exemplo, aqui eu uso a assinatura da imagem "rose.gif" para criptografar e depois descriptografar a imagem "message.gif".
magick identify -format %# rose.gif |\
magick message.gif -encipher - -depth 8 png24:message_signed.png
magick identify -format %# rose.gif |\
magick message_signed.png -decipher - message_restored_3.png
A partir do IM v6.4.8-0, o arquivo usado por "[-encipher](https://imagemagick.org/command-line-options/#encipher)" e "[-decipher](https://imagemagick.org/command-line-options/#decipher)" pode ser um arquivo binário. Por isso, você poderia até usar diretamente uma imagem em si como frase secreta.
magick message.gif -encipher rose.gif -depth 8 png24:message_binary.png
magick message_binary.png -decipher rose.gif message_restored_4.png
| Antes do IM v6.4.8-0, um arquivo binário parava no primeiro caractere 'NULL' encontrado. Algo que aconteceria bem cedo se uma imagem PNG fosse usada.
---|---
Essa técnica é exata (a menos que parte dos dados tenha sido destruída na transmissão). E, por isso, você pode usá-la para criptografar uma imagem que contenha outras informações ocultas, como uma Imagem Stegano. Isso significa que, mesmo que as autoridades descriptografem a imagem ou forcem você a revelar a senha, elas verão uma imagem real, mas essa imagem pode não ser a imagem final oculta. | Os operadores "[-encipher](https://imagemagick.org/command-line-options/#encipher)" e "[-decipher](https://imagemagick.org/command-line-options/#decipher)" foram adicionados ao IM v6.3.8-6, mas exigiam que você incluísse uma opção "--enable-cipher" na configuração de compilação. Entretanto, no IM v6.4.6 (quando isso mudou?), esse item de configuração deixou de ser necessário e tornou-se uma configuração padrão. Por isso, você provavelmente pode usá-lo imediatamente.
---|---
| _A cifra foi implementada usando uma cifra de fluxo autossincronizada implementada a partir de uma cifra de bloco.
Isso significa que você ainda pode decifrar mesmo um download parcial da imagem, que foi destruído por erro de transmissão, mesmo que alguma parte da imagem possa ter sido destruída. Você também não precisa baixar a imagem inteira para descriptografar e examinar as partes que foram baixadas com sucesso.
Mas você precisa da frase secreta para ter qualquer chance de descriptografar a imagem com sucesso, pois é uma criptografia muito, muito forte.
Pixelizar uma Imagem
Pixelizar uma imagem é basicamente usado para transformar uma imagem em um conjunto de grandes 'pixels' coloridos que mostram apenas um contorno vago da imagem original. Ambas as técnicas envolvem encolher a imagem (para gerar menos pixels) e, então, ampliá-los de forma a criar 'blocos de pixel', usando um Operador de Escalonamento ou um Operador de Amostragem para gerar o bloco de cor. É apenas a forma como a imagem é reduzida que determina exatamente qual cor será usada. Uma única amostra de pixel ou uma cor média combinada.
magick rose: -sample 25% -scale 70x46\! rose_pixelate_sampled.gif
magick rose: -scale 25% -scale 70x46\! rose_pixelate_scaled.gif
magick rose: -resize 25% -scale 70x46\! rose_pixelate_resized.gif
Como você pode ver, as áreas 'amostradas' terão 'pixels' muito mais distintos (com aliasing), enquanto as outras duas usam uma cor combinada ou média, que tende a produzir uma representação de cor mais suave, porém mais precisa, para cada 'pixel'. Veja também Proteger o Anonimato de Alguém para um exemplo de uso disso apenas em uma área menor mascarada da imagem, como o rosto de uma pessoa.
Grades de Pixels
Colocar uma imagem em grade é muito semelhante a pixelizá-la. Neste caso, queremos apenas ampliar a imagem, para gerar uma visão distinta em nível de pixel dos detalhes da imagem. Tipicamente uma imagem muito pequena. A maneira mais simples é como no exemplo anterior: simplesmente Escalar uma imagem pequena, para ampliar os pixels.
magick rose: -crop 10x10+12+20 +resize grid_input.png
magick grid_input.png -scale 1000% grid_scale.png
O problema com um simples escalonamento é que, em áreas onde os pixels têm cor semelhante, você pode ter dificuldade em ver os 'blocos de pixel' individuais. O que precisamos é adicionar uma borda ao redor dos pixels, para separá-los. Para isso, precisamos sobrepor uma máscara de mosaico gerada. Veja Ladrilhamento com uma Imagem Já em Memória para vários métodos de uso de uma imagem de ladrilhamento gerada em um único comando. Aqui geramos uma 'grade' branca sobre preto que é sobreposta usando Composição por Screen (sobrepõe o branco, deixando as áreas pretas como estão). |
magick -size 10x10 xc: -draw 'rectangle 1,1 9,9' -write mpr:block +delete \
grid_input.png -scale 1000% -size 101x101 tile:mpr:block \
+swap -compose screen -composite grid_blocks.png
![[IM Output]](../static/img/transform/grid_blocks.png)
Observe que o tamanho usado para gerar o mosaico é _scale_ *_image_size_ +_gap_size_ (neste caso 10*10+1 => 101). Também Troquei as duas imagens para que o tamanho final da imagem venha da imagem do mosaico, em vez da imagem escalada, que é um pixel menor em tamanho. No entanto, isso pode perder quaisquer metadados de imagem que existissem na imagem original, pois usei a imagem em mosaico como destino. Aqui gero 'manchas' circulares de cor, mas desta vez usei uma Composição Multiply (sobrepor preto, deixando as áreas brancas como estão). |
magick -size 10x10 xc: -draw 'circle 5,5 1,3' -negate \
-write mpr:spot +delete \
grid_input.png -scale 1000% -size 101x101 tile:mpr:spot \
+swap -compose multiply -composite grid_spots.png
![[IM Output]](../static/img/transform/grid_spots.png)
Você pode tornar a borda da grade transparente também negando o overlay em mosaico (áreas pretas se tornam transparentes) e usando uma Composição CopyOpacity em vez de Multiply. Outras cores também podem ser adicionadas, mas para que isso funcione você precisa usar uma imagem de mosaico que realmente contenha transparência real. Para isso você precisa converter a imagem de mosaico preto e branco em uma Máscara de Forma. Por exemplo, aqui uso o Operador Básico de Morfologia para gerar 'buracos' em forma de diamante em um overlay colorido. Para isso, um único pixel 'semente' é desenhado e expandido usando um Núcleo de Morfologia Diamond. |
magick -size 10x10 xc: -draw 'point 5,5' -morphology Erode:4 Diamond \
-background Navy -alpha shape -write mpr:diamond +delete \
grid_input.png -scale 1000% -splice 1x1+0+0 \
-size 101x101 -background none tile:mpr:diamond \
-alpha set -compose Over -composite grid_diamonds.png
![[IM Output]](../static/img/transform/grid_diamonds.png)
| Observe que o codificador "tile:" substituirá qualquer transparência na imagem pela cor de fundo atual. Se você quiser preservar a transparência da imagem de mosaico, defina "-background none" ou "-compose Src". A primeira é mais fácil.
---|---
Observe que, tecnicamente, a modelagem alfa pode ser feita antes de salvar a imagem de mosaico, ou depois de fazer o mosaico da imagem, antes de sobrepô-la. A escolha é sua. Uma técnica final é usar um filtro de reamostragem ruim para produzir uma Falha de Reamostragem e gerar círculos com serrilhamento de cada pixel. Esta não é uma ótima técnica (uso indevido de uma falha de processamento de imagem), mas ela forma uma Grade de Pixels.
Espaçando os Mosaicos
Um problema semelhante é espaçar uma grade de mosaicos em uma imagem. Isso não é simplesmente escalar pixels individuais em 'blocos de pixels', mas inserir espaço entre áreas retangulares de uma imagem. Ou seja, Emendar pixels extras em uma imagem em intervalos regulares. Atualmente, a melhor solução é dividir a imagem em Linhas e Colunas e Emendar o espaçamento extra em cada mosaico antes de Anexar os mosaicos de volta. Por exemplo...
magick rose: -background SkyBlue \
-crop 10x0 +repage -splice 3x0 +append \
-crop 0x10 +repage -splice 0x3 -append \
grid_tile.png
Aqui está outro método que também separa a imagem original em mosaicos, mas depois usa algumas Expressões FX Improvisadas para calcular a nova posição de um mosaico a partir de sua posição antiga. |
magick rose: -crop 10x10 \
-set page '+%[fx:page.x+3*page.x/10]+%[fx:page.y+3*page.y/10]' \
-background skyblue -layers merge +repage grid_tile_fx.png
![[IM Output]](../static/img/transform/grid_tile_fx.png)
O número '3' acima é a largura do intervalo a adicionar, e '10' é o tamanho do mosaico. Tudo o que você precisa é adicionar uma borda ou outra aresta ao resultado. Com um pouco mais de trabalho, você pode até adicionar algum 'jitter' aleatório ao posicionamento de cada mosaico na grade acima, para um efeito menos regular. O problema com ambos os métodos é que gerar muitas imagens pequenas apenas para uni-las novamente gera muito trabalho. Especialmente para tamanhos de mosaico muito pequenos. Um método melhor que foi proposto é uma extensão especial ao Operador Splice, na Discussão do Fórum do IM Splice (adding tile gridding gaps).
Transformações de Visão Computacional
Detecção de Bordas
O operador "[-edge](https://imagemagick.org/command-line-options/#edge)" destaca áreas de gradientes de cor dentro de uma imagem. É um operador em escala de cinza, portanto é aplicado a cada um dos três canais de cor separadamente.
magick mask.gif -edge 1 mask_edge_1.gif
magick mask.gif -edge 2 mask_edge_2.gif
magick mask.gif -edge 3 mask_edge_3.gif
magick mask.gif -edge 10 mask_edge_10.gif
Como você pode ver, a borda é adicionada apenas às áreas com um gradiente de cor que é mais de 50% branco! Não sei se isso é um bug ou intencional, mas significa que a borda acima está localizada quase completamente nas partes brancas da imagem de máscara original. Este fato pode ser extremamente importante ao fazer uso dos resultados do operador "[-edge](https://imagemagick.org/command-line-options/#edge)". Por exemplo, se você estiver realizando detecção de bordas em uma imagem que contém um contorno preto, o operador "[-edge](https://imagemagick.org/command-line-options/#edge)" 'geminará' as linhas pretas, produzindo um resultado estranho.
magick piglet.gif -colorspace Gray -edge 1 -negate piglet_edge.gif
No entanto, negando a imagem antes de fazer a detecção de bordas, as linhas geminadas vão para dentro e se juntam, removendo o efeito de 'linha dupla'. |
magick piglet.gif -colorspace Gray \
-negate -edge 1 -negate piglet_edge_neg.gif
![[IM Output]](../static/img/transform/piglet_edge_neg.gif)
Descobri que as bordas tendem a ser muito nítidas, gerando uma borda não suave nas imagens resultantes. Por isso, acho que um desfoque muito muito leve no resultado melhora bastante a aparência. |
magick piglet_edge_neg.gif -blur 0x.5 piglet_edge_blur.gif
![[IM Output]](../static/img/transform/piglet_edge_blur.gif)
Aqui apliquei a detecção de bordas a uma imagem colorida e a uma versão em escala de cinza para mostrar seus efeitos em imagens semelhantes a fotos.
magick rose: -edge 1 rose_edge.gif
magick rose: -colorspace Gray -edge 1 rose_edge_grey.gif
Como você pode ver, sem converter a imagem para escala de cinza, as bordas dos diferentes canais de cor são geradas de forma completamente independente umas das outras.
Detector de Bordas Canny
A partir do IM v6.8.9-0, o IM agora suporta o detector de bordas canny. (Veja os Exemplos de Anúncio no Fórum do IM). Este é um algoritmo de detecção de bordas muito avançado, que produz linhas únicas muito fortes (binárias) de um pixel de largura em todas as bordas nítidas, com muito pouca interferência de ruído. Por exemplo, aqui o aplicamos às imagens de teste que usamos acima..
magick mask.gif -canny 0x1+10%+30% mask_canny.gif
magick piglet.gif -canny 0x1+10%+30% piglet_canny.gif
magick piglet.gif -negate -canny 0x1+10%+30% piglet_canny_neg.gif
magick rose: -canny 0x1+10%+30% rose_canny.gif
Como você pode ver, ele produz um resultado muito mais nítido que o Operador Edge acima. A borda difusa com anti-aliasing tem pouco ou nenhum efeito no resultado, produzindo linhas finas de bitmap. Além disso, como a imagem do piglet mostra, ela não é colocada em um lado específico como o operador de bordas anterior fazia. Como resultado, negar a imagem de entrada não tem efeito. Mas, como todos os detectores de bordas, ele pode ter problemas com imagens do mundo real com fundos 'movimentados', como a imagem rose embutida. Este resultado limpo é muito importante mais adiante na Detecção de Linhas Hough.
Contornos de Bordas a partir de Formas com Anti-Aliasing
O maior problema com os métodos normais de detecção de bordas é que o resultado é altamente serrilhado. Ou seja, ele gera um efeito de pixels muito parecido com uma escada, independentemente de a forma ser suave (com anti-aliasing) ou serrilhada. Por exemplo, aqui está um balão de fala suave com anti-aliasing (caractere '(' da fonte "WebDings"). |
magick -size 80x80 -gravity center -font WebDings label:')' voice.gif
![[IM Output]](../static/img/transform/voice.gif)
E aqui está sua imagem com bordas detectadas... |
magick voice.gif -edge 1 -negate voice_edge.gif
![[IM Output]](../static/img/transform/voice_edge.gif)
Como você pode ver, fica horrível, com algum anti-aliasing menor na parte externa da borda e um aspecto totalmente serrilhado (escada) na parte interna da linha. Negar a imagem gerou um contorno semelhante ao redor da parte externa da imagem, mas também tem forte serrilhamento fora da linha. |
magick voice.gif -negate -edge 1 -negate voice_edge_negate.gif
![[IM Output]](../static/img/transform/voice_edge_negate.gif)
Uma alternativa, quando você já tem uma imagem com uma borda com anti-aliasing, é gerar a imagem de diferença de um clone 'deslocado' da forma original. Por exemplo, aqui encontramos a imagem de diferença entre a imagem original e uma que foi deslocada (ou jitterizada) para a direita em 1 pixel. |
magick voice.gif \( +clone -roll +1+0 \) -compose difference -composite \
-negate voice_jitter_horiz.gif
![[IM Output]](../static/img/transform/voice_jitter_horiz.gif)
Observe que isso não produz uma boa borda para arestas inclinadas horizontais. No entanto, combinando uma imagem de diferença deslocada horizontal e vertical, podemos obter um contorno com anti-aliasing muito bom da forma. |
magick voice.gif \
\( -clone 0 -roll +1+0 -clone 0 -compose difference -composite \) \
\( -clone 0 -roll +0+1 -clone 0 -compose difference -composite \) \
-delete 0 -compose screen -composite -negate voice_jitter_edge.gif
![[IM Output]](../static/img/transform/voice_jitter_edge.gif)
Esta técnica também tem a vantagem de funcionar independentemente de a máscara estar negada ou não. Observe, no entanto, que o resultado tem um deslocamento de 1/2 pixel em relação à imagem original, portanto pode exigir algum processamento adicional de 'distorção' para realinhar a forma original ou o contorno, caso os dois precisem ser combinados para obter o resultado desejado.
Contornos de Bordas a partir de Formas de Bitmap
Imagens de bitmap são muito mais difíceis, pois não têm nenhum pixel com anti-aliasing que possa ser usado para produzir um contorno suave. Por exemplo, aqui está uma forma de 'Coração' elegante que foi extraída da fonte "WebDings" (caractere 'Y'). No entanto, eu a gerei propositalmente como um bitmap serrilhado, para simular uma imagem de bitmap horrível baixada da rede. Como o contorno de uma imagem GIF contendo transparência. |
magick +antialias -size 80x80 -gravity center \
-font WebDings label:Y heart.gif
![[IM Output]](../static/img/transform/heart.gif)
Então temos esta imagem horrível, mas queremos encontrar o contorno da imagem em vez de sua forma. O uso direto da detecção de bordas só gerará uma borda de bitmap pura ao redor da parte externa da forma de bitmap. |
magick heart.gif -edge 1 -negate heart_edge.gif
![[IM Output]](../static/img/transform/heart_edge.gif)
Uma borda negada gera uma imagem de borda, mas para o interior da área preta. |
magick heart.gif -negate -edge 1 -negate heart_edge_negate.gif
![[IM Output]](../static/img/transform/heart_edge_negate.gif)
Adicionando ambos os anteriores, você obtém uma borda de 2 pixels centrada na borda da forma de bitmap. |
magick heart.gif \( +clone -negate \) -edge 1 \
-compose add -composite -negate heart_edge_double.gif
![[IM Output]](../static/img/transform/heart_edge_double.gif)
Como você pode ver, a imagem resultante é altamente serrilhada com efeitos de 'escada' no contorno, mesmo que a imagem original não seja tão ruim nesse aspecto. Esta não é uma boa solução. Uma borda ligeiramente melhor pode ser criada usando um método de morfologia '[EdgeIn](morphology.html#edge-in)', ou outros semelhantes. |
magick heart.gif -negate -morphology EdgeIn Diamond -negate heart_edgein.gif
![[IM Output]](../static/img/transform/heart_edgein.gif)
E um efeito semelhante pode ser alcançado apenas usando redimensionamentos para desfocar a borda da maneira certa, antes de usar um Solarize para extrair os pixels cinza-médio que formam a borda. Uma borda mais espessa pode ser gerada adicionando uma configuração "-filter Cubic" ou algum outro Filtro de Reamostragem. |
magick heart.gif -resize 400% -resize 25% \
-solarize 50% -evaluate multiply 2 -negate heart_resize.gif
![[IM Output]](../static/img/transform/heart_resize.gif)
Ou, para um efeito mais controlado e difuso, você pode apenas desfocar a forma e extrair a borda de maneira semelhante. Acho que um desfoque de '0.7' é o melhor, com um limite de 3 pixels para acelerar as coisas. |
magick heart.gif -blur 3x.7 -solarize 50% -level 50%,0 heart_blur.gif
![[IM Output]](../static/img/transform/heart_blur.gif)
Observe o uso do Operador Level, que é o equivalente ao "-evaluate multiply 2 -negate" usado no exemplo anterior. Com uma borda com anti-aliasing, você agora pode readicionar a forma original se quiser apenas suavizar a forma original em vez de obter seu contorno. Apenas lembre-se de que o contorno é posicionado exatamente ao longo da borda da imagem original, então será meio pixel maior em tamanho do que nos exemplos anteriores. Você conhece alguma outra maneira de gerar um contorno com anti-aliasing a partir de uma forma (com anti-aliasing ou bitmap)? Se sim, por favor, envie-a para mim ou para o fórum do IM. Você receberá crédito.
Contornos usando um Conversor de Rasterizado para Vetor
Uma das soluções mais ideais é usar um programa de conversão de 'rasterizado para vetor' não pertencente ao IM para transformar esta forma de bitmap em um contorno vetorial. Programas que podem fazer isso incluem: "ScanFont", "CorelTrace", "Streamline" da Adobe e "[Vector Magic](http://vectormagic.com/home)". A maioria deles, no entanto, custa pelo menos algum dinheiro. "VectorMagick" e outro programa de traçado "AutoTracer" têm conversores de imagem online gratuitos disponíveis. Outras soluções gratuitas são "[AutoTrace](http://autotrace.sourceforge.net/)" ou "[PoTrace](http://potrace.sourceforge.net/)". Mais sugestões são bem-vindas. Esses programas de traçado são simples de usar, mas normalmente exigem alguma forma de configuração da imagem antes e depois. Eles têm um número limitado de formatos de entrada e produzem uma imagem vetorial que criará uma forma 'suavizada' da imagem de entrada. Eu prefiro o "AutoTrace", pois ele não escala os dados SVG resultantes, produzindo assim uma espessura de linha padrão; no entanto, você não pode usá-lo em um 'pipeline'. Para melhores resultados, é uma boa ideia garantir que só forneçamos a ele uma imagem de bitmap básica, o que podemos assegurar aplicando um limiar na imagem de entrada, enquanto a convertemos em um formato de imagem que o autotrace entenda. Posso então transformar essa imagem em uma imagem vetorial SVG.
magick heart.gif -colorspace gray -threshold 50% heart_tmp.pbm
autotrace -output-format svg -output-file heart.svg heart_tmp.pbm
magick heart.svg heart_svg.gif
rm -f heart_tmp.pbm
| | | ![[IM Text]](../static/img/transform/heart.svg.gif)
A partir do IM v6.4.2-6, você pode fazer a sequência acima diretamente usando o delegado de entrada de imagem "autotrace:". Isso só requer que o comando "autotrace" esteja instalado. Por exemplo |
magick autotrace:heart.gif heart_traced.gif
![[IM Output]](../static/img/transform/heart_traced.gif)
Se o seu IM foi compilado com a biblioteca delegada "[AutoTrace](http://autotrace.sourceforge.net/)", você também pode fazer o IM gerar diretamente a imagem SVG a partir de uma imagem na memória. Para detalhes sobre isso, veja Tratamento de Saída SVG. Por exemplo....
magick heart.gif heart_2.svg
Agora, a saída SVG representará, é claro, uma versão suavizada da imagem original, o que não é o que realmente queremos neste exemplo. Mas, como agora temos a forma do bitmap em forma vetorial, podemos simplesmente ajustar os atributos 'style' do SVG para 'stroke' (traçar) o contorno, em vez de 'fill' (preencher) a forma. O SVG modificado pode então ser realimentado no ImageMagick novamente para recriar a imagem rasterizada de contorno limpo. Por exemplo... |
cat heart.svg |
sed 's/"fill:#000000[^"]*"/"fill:none; stroke:black;"/' |
magick svg:- heart_outline.gif
![[IM Output]](../static/img/transform/heart_outline.gif)
Sim, é um pouco estranho, mas o resultado suave com anti-aliasing vale bem o esforço. Seria bom se o contorno ou algumas outras modificações pudessem ser especificados como opções para o próprio comando "autotrace", mas isso atualmente não é um recurso. Você também pode modificar ainda mais a saída SVG para engrossar a borda, ou especificar alguma outra cor de traço ou de fundo, alterar a cor de preenchimento da forma de borda vetorial. Por exemplo, aqui geramos um contorno mais espesso da forma com um preenchimento vermelho, tudo bem suavizado com anti-aliasing. |
cat heart.svg |
sed 's/"fill:#000000;[^"]*"/"fill:red; stroke:black; stroke-width:5;"/' |
magick svg:- heart_outline_thick.gif
![[IM Output]](../static/img/transform/heart_outline_thick.gif)
Um coração de aparência tão perfeita não poderia ter sido gerado a partir de uma forma de bitmap de nenhuma outra maneira. Também poderíamos apenas extrair o elemento de caminho 'd="..."' para usar diretamente como uma String de Caminho SVG no Comando Draw. Isso então permitiria que você usasse qualquer uma das outras configurações de desenho do IM com esse contorno vetorial, dando a você controle total sobre o resultado final. Para outro exemplo de uso do programa "[AutoTrace](http://autotrace.sourceforge.net/)", veja Esqueleto usando Autotrace.
Detector de Linhas Hough
O Detector de Linhas Hough ("[-hough-lines](https://imagemagick.org/command-line-options/#hough-lines)" adicionado no IM v6.8.9-1) é uma transformação muito complexa com muitos estágios (para detalhes, veja Wikipedia, Transformada de Hough). Basicamente, ele é projetado para examinar uma imagem, procurando linhas brancas sobre um fundo preto, e tentar retornar a localização exata de quaisquer segmentos de linha (sequências lineares de pixels) presentes na imagem. Isso pode ser muito importante para coisas como remover rotações da imagem ou determinar a transformação de perspectiva em uma imagem, para que possa ser repetida ou removida. Aqui está o conjunto completo de opções do operador
-background {_background_} -stroke {_line_color_} -hough-lines {_W_}x{_H_}+{_threshold_}
As cores (background e line_color) são usadas para definir as cores das linhas na imagem resultante (se você realmente as desenhar). O argumento para o Operador Hough (W}x{H}+{threshold) é usado para definir o tamanho e o limiar do filtro usado para encontrar 'picos' na 'imagem de busca' intermediária. Ou seja, ele controla o quão bem ele realmente 'encontra' as linhas que estamos tentando detectar (veja abaixo). Você ajustaria esses valores para ajudar a encontrar a detecção de linhas. Por exemplo, vamos tentar encontrar as linhas em uma imagem de forma retangular. Primeiro, precisamos reduzir a imagem a linhas e, para um resultado limpo, o Detector de Bordas Canny é recomendado.
magick shape_rectangle.gif -canny 0x1+10%+30% rectangle.gif
Agora vamos aplicar o Detector de Linhas Hough a esta imagem. |
magick rectangle.gif -background black -stroke red \
-hough-lines 5x5+20 rectangle_lines.gif
![[IM Output]](../static/img/transform/rectangle_lines.gif)
Como você pode ver, 5 linhas foram encontradas, 2 das quais estão muito próximas. A razão para a linha extra é que o retângulo na imagem não é perfeito. Agora, embora eu esteja exibindo um resultado de imagem rasterizada (GIF), o Operador Hough na verdade gera uma imagem vetorial no Formato Magick Vector Graphics. Isso significa que você pode listar as informações de linha para processamento posterior.
magick rectangle.gif -background black -stroke red \
-hough-lines 5x5+20 rectangle_lines.mvg
Observe que as linhas são desenhadas de uma borda (com valores de ponto flutuante) para outra borda da imagem. E, a partir disso, você pode ver que a segunda e a terceira linhas são as duas que estão próximas. O comentário na saída MVG fornece o número acumulado de pixels que a linha 'atinge' na imagem e, portanto, é uma boa indicação de quão forte a linha é na imagem. Este valor será sempre maior que o valor de limiar que você dá ao operador "[-hough-line](https://imagemagick.org/command-line-options/#hough-line)". A partir disso, você pode ver que a primeira e a última linhas (que são correspondências próximas) têm aproximadamente a mesma força, então seria difícil escolher uma delas em detrimento da outra. Se isso acontecer com você, sugiro que tente melhorar sua etapa de detecção de bordas. Observe que a imagem MVG não tem nenhuma cor definida. As configurações de cor neste exemplo não foram realmente usadas. As cores só são usadas se você realmente 'desenhar' os vetores ao converter o resultado acima em uma imagem 'rasterizada', como fizemos antes. Você também pode ver a 'imagem de busca' intermediária, ou 'acumulador', que está procurando por pixels brancos em todas as orientações, usando um define especial. |
magick rectangle.gif \
-define hough-lines:accumulator=true -hough-lines 5x5+20 \
-delete 0 -contrast-stretch 0.1% rectangle_accumulator.gif
![[IM Output]](../static/img/transform/rectangle_accumulator.gif)
O define apenas anexará a 'imagem de busca' ao resultado da imagem, que neste caso excluímos. Também aplicamos algum contraste aos 'valores acumulados' para torná-los mais visíveis. Esta é a imagem que os argumentos do Detector Hough estão pesquisando. A imagem tem sempre 180 pixels de largura (1 pixel por grau de ângulo de linha), enquanto a altura é o dobro do comprimento diagonal da imagem. Assim, a localização do pico definirá diretamente o ângulo da linha e a distância perpendicular da linha em relação ao ponto central da imagem de entrada. Ou seja, a coordenada X é o ângulo em graus, e a coordenada Y é a distância a partir do centro, de -distância diagonal a +distância diagonal. Se você olhar de perto o pico no canto inferior direito, poderá ver por que acabamos com duas linhas em vez de uma. O pico aqui está 'geminado' com uma pequena lacuna entre eles. O algoritmo é baseado no script "[houghlines](http://www.fmwconcepts.com/imagemagick/houghlines/)" de Fred Wienhaus, embora com um tratamento de acumulação de 'distância perpendicular' diferente.
Limiar Adaptativo Local
Em Construção
O operador "[-lat](https://imagemagick.org/command-line-options/#lat)" tenta aplicar um limiar adaptativo a cada pixel com base no valor dos pixels em uma janela circundante. Isso é comumente usado para aplicar limiar a imagens com um fundo irregular (ou seja, iluminação irregular). É baseado na suposição de que os pixels em uma pequena janela terão aproximadamente a mesma cor de fundo e aproximadamente a mesma cor de primeiro plano.
Por exemplo.
magick input.png -lat 17 output.png
No exemplo acima, uma 'janela' quadrada de 17 pixels é usada para determinar a cor média da imagem em cada ponto; se o pixel for mais escuro que essa média, ele se torna preto; se mais claro que essa média, ele se torna branco. Um tamanho de janela pequeno tornará o limiar mais sensível a pequenas mudanças na iluminação, é mais rápido de calcular, mas é adversamente afetado por ruído na imagem.
Exemplo
Um tamanho de janela maior tornará o limiar menos sensível a pequenas mudanças na iluminação, é mais lento de calcular e menos afetado por ruído na imagem. Isso tem o efeito de tornar a seleção do valor de limiar mais ou menos sensível a pequenas mudanças nos valores dos pixels.
Exemplo
A janela não precisa ser quadrada. por exemplo...
magick input.png -lat 15x25 output.png
Você também pode fornecer um deslocamento que será adicionado à cor média calculada, tornando o valor de limiar local para cada pixel mais claro ou mais escuro. Isso pode ser usado, por exemplo, para reduzir o efeito do ruído ou o efeito de pequenas mudanças nos valores dos pixels.
magick input.png -lat 15x25+2%
Essas pequenas mudanças normalmente ocorrem quando um scanner ou câmera digital é usado para adquirir a imagem. Use um valor de deslocamento positivo para tornar o limiar adaptativo menos sensível a pequenas variações nos valores dos pixels. Use um limiar negativo para tornar o limiar adaptativo mais sensível a pequenas variações nos valores dos pixels. Alternativamente, pode-se reduzir o ruído na imagem antes de processá-la com "-lat".
Em resumo, cada pixel recebe o limiar usando a seguinte lógica:
AVG = valor médio de cada pixel na janela
IF (pixel de entrada é > AVG + OFFSET)
Pixel de saída é PRETO
else
Pixel de saída é BRANCO
---
Uma alternativa é subtrair uma cópia desfocada da imagem original
usando Subtração (Modulus) e, em seguida, aplicar o limiar.
magick rose: -colorspace gray -lat 10x10+0% x:
é aproximadamente equivalente a...
magick rose: -colorspace gray \( +clone -blur 10x65535 \) \
-compose subtract -composite -threshold 50% x:
O especial "-blur 10x65535" é um desfoque de média linear que se limita a uma
janela de 10x10.
A composição 'Subtract', sendo uma operação matemática do tipo módulo,
reencaixa os valores que ficam negativos para um valor maior que 50%.
Se você quiser incluir um deslocamento, pode fazê-lo também subtraindo uma imagem
de fundo de cor sólida usando um -flatten... por exemplo
magick rose: -colorspace gray -lat 10x10+10% x:
é aproximadamente equivalente a...
magick rose: -colorspace gray \( +clone -blur 10x65535 \) \
-compose subtract -background gray10 -flatten -threshold 50% x:
O texto acima foi modificado a partir de notas iniciais fornecidas por D Hobson dhobson@yahoo.com
-adaptive-sharpen
Aguça as imagens apenas ao redor das bordas das imagens
-segment cluster-threshold x smoothing-threshold
Segmentação do espaço de cor (não de objetos da imagem)
Isso pode produzir uma saída muito verbosa.
Isso aplica o "algoritmo fuzzy c-means" se você quiser saber mais.
Também relacionado está o -despeckle. para remover pixels isolados de cor destoante.
Gera um estereograma 3d de duas imagens (uma para cada olho)
Isso também é conhecido como anaglifo
magick composite left.jpg right.jpg -stereo anaglyph.jpg
Realce 3D com Shade
Uso do Shade
O operador "[-shade](https://imagemagick.org/command-line-options/#shade)" eu sempre considerei um dos operadores mais interessantes fornecidos pelo ImageMagick. A documentação deste operador só dava uma vaga ideia de suas capacidades. Levou muita pesquisa pessoal para entender o operador e até descobrir a melhor forma de usar o poder que ele pode fornecer aos usuários do IM. Basicamente, o que este operador faz é assumir que a imagem dada é algo chamado 'campo de altura'. Ou seja, uma imagem em escala de cinza representando a superfície de algum objeto ou terreno. A cor 'white' representa o ponto mais alto de uma imagem, enquanto 'black' o ponto mais baixo. Esta representação surgiu da pesquisa de visão computacional de 1980, onde uma foto com uma forte 'luz de câmera' era usada, tornando os pontos próximos brilhantes e os pontos distantes escuros. |
Como uma imagem em escala de cinza é necessária pelo "[-shade](https://imagemagick.org/command-line-options/#shade)", o operador removerá automaticamente qualquer cor da imagem de entrada. Da mesma forma, qualquer transparência que possa estar presente na imagem é completamente inútil e ignorada pelo operador. |
|---|---|
Agora o "[-shade](https://imagemagick.org/command-line-options/#shade)" pega este campo de altura em escala de cinza e brilha uma luz sobre ele. O resultado é uma representação dos tons de luz que seriam assim produzidos. Lembre-se de que você deve pensar na imagem de entrada como uma 'superfície' para que a saída faça algum sentido. Para nossas demonstrações, precisaremos de uma imagem de 'campo de altura', então vamos desenhar uma. |
magick -font Candice -pointsize 64 -background black -fill white \
label:A -trim +repage -bordercolor black -border 10x5 \
shade_a_mask.gif
![[IM Output]](../static/img/transform/shade_a_mask.gif)
Esta imagem também é equivalente a uma 'máscara' de uma forma, sendo frequentemente usada não apenas como entrada para o "[-shade](https://imagemagick.org/command-line-options/#shade)", mas também para Mascarar Imagens e recortar a mesma forma dos resultados sombreados. Veja Mascarando uma Imagem Shade abaixo. Para o operador "[-shade](https://imagemagick.org/command-line-options/#shade)", esta imagem parecerá uma planície preta plana, com um platô branco plano erguendo-se verticalmente para cima. Apenas as bordas desta imagem produzirão, portanto, efeitos interessantes. Para esse efeito, os dois argumentos definem a direção da qual a luz está brilhando. O primeiro argumento é a direção da qual a luz vem. Assim, um ângulo de '0' grau virá do leste (ou esquerda), '90' é anti-horário a partir do norte (ou topo), e assim por diante. Por exemplo...
magick shade_a_mask.gif -shade 0x45 shade_direction_0.gif
magick shade_a_mask.gif -shade 45x45 shade_direction_45.gif
magick shade_a_mask.gif -shade 90x45 shade_direction_90.gif
magick shade_a_mask.gif -shade 135x45 shade_direction_135.gif
magick shade_a_mask.gif -shade 180x45 shade_direction_180.gif
Você entendeu a ideia. A luz pode vir de qualquer direção. O outro argumento é a elevação e representa o ângulo que a fonte de luz faz com o chão. Você pode pensar nisso como quão alto o sol está durante o dia, de modo que '0' é o amanhecer e '90' é diretamente acima da cabeça.
![[diagram]](../static/img/img_diagrams/shade_elevation.gif)
magick shade_a_mask.gif -shade 90x0 shade_elevation_0.gif
magick shade_a_mask.gif -shade 90x15 shade_elevation_15.gif
magick shade_a_mask.gif -shade 90x30 shade_elevation_30.gif
magick shade_a_mask.gif -shade 90x45 shade_elevation_45.gif
magick shade_a_mask.gif -shade 90x60 shade_elevation_60.gif
magick shade_a_mask.gif -shade 90x75 shade_elevation_75.gif
magick shade_a_mask.gif -shade 90x90 shade_elevation_90.gif
Como você pode ver, com uma elevação de '0', a forma é destacada apenas no lado do qual a luz vem. Todo o resto é preto, pois nenhuma luz incide sobre qualquer outra superfície. Eu chamo isso de 'Realce do Amanhecer' e tem seus próprios usos especiais. Isso nos traz ao primeiro item digno de nota. Uma imagem que passou por "[-shade](https://imagemagick.org/command-line-options/#shade)" frequentemente terá mais áreas escuras, ou sombreadas, do que áreas destacadas. O sombreamento não é igual. À medida que a luz fica mais alta sobre a imagem de 'campo de altura', o brilho geral da imagem se tornará mais branco, até que, ao 'meio-dia' ou uma elevação de '90', quaisquer áreas planas ficam brilhantemente brancas, e apenas inclinações e bordas são sombreadas para uma cor cinza, com um cinza-médio como máximo, ou mudança de inclinação 'tipo penhasco'. Esta imagem de 'meio-dia' é outro caso especial que é um pouco como um sistema de detecção de bordas, embora tenha entre 2 e 4 pixels de largura para bordas nítidas. Já usei esta imagem no passado para gerar uma máscara para a borda chanfrada de imagens "[-shade](https://imagemagick.org/command-line-options/#shade)", de modo a tornar as áreas planas transparentes. Se o ângulo de elevação ultrapassar '90' graus, você obterá o mesmo resultado como se a luz viesse da outra direção. Assim, o argumento '0x135' produzirá exatamente o mesmo resultado que '180x45'. Um ângulo de elevação negativo também produzirá os mesmos resultados, como se a luz viesse de baixo, sobre uma superfície 'translúcida'. Assim, '0x-45' será o mesmo que '0x45'. Em outras palavras, para um determinado sombreamento, geralmente há outros 4 argumentos que também produzirão o mesmo resultado. Do exposto acima, eu consideraria um argumento de '120x45' como sendo aproximadamente o melhor para uso direto da saída do shade. Por exemplo, aqui ele cria algum texto chanfrado...
magick -size 320x100 xc:black \
-font Candice -pointsize 72 -fill white \
-draw "text 25,65 'Anthony'" \
-shade 120x45 shade_anthony.jpg
Um dos maiores problemas com o "[-shade](https://imagemagick.org/command-line-options/#shade)" é a espessura do chanfro que é realmente produzido. Uma borda nítida como a que usei acima sempre produzirá um chanfro de cerca de 4 pixels de largura, tanto para dentro quanto para fora da área mascarada. Não há como ajustar essa espessura, a não ser redimensionando as imagens antes e depois de usar o operador "[-shade](https://imagemagick.org/command-line-options/#shade)". Se você quiser descobrir quão brilhantes as 'áreas planas' ficarão a partir de um ângulo específico de iluminação de elevação, então você pode usar o seguinte comando, para sombrear uma superfície de cor sólida plana.
magick -size 50x50 xc:white -draw 'circle 25,25 20,10' \
-blur 0x2 -shade 0x45 -gravity center -crop 1x1+0+0 txt:-
Como você pode ver, uma elevação de '45' graus produz uma cor plana bastante brilhante de cerca de 70% de cinza, que é um nível de cinza razoável para visualização geral. No entanto, se você planeja usar o shade para gerar realces 3-D de várias formas, então o nível de cinza real se torna muito importante. Isso será visto mais adiante em Criando Realces de Sobreposição. Ou seja, basicamente é isso para o operador "[-shade](https://imagemagick.org/command-line-options/#shade)". No entanto, usá-lo de forma eficaz apresenta toda uma gama de técnicas e possibilidades, que veremos a seguir.
Mascarando Formas Sombreadas
Como mencionado acima, uma forma de 'máscara' simples é frequentemente usada com o "[-shade](https://imagemagick.org/command-line-options/#shade)" para gerar efeitos 3-D complexos a partir de uma forma simples. Por exemplo, vamos fazer isso com uma imagem de máscara sombreada diretamente.
magick shade_direction_135.gif shade_a_mask.gif \
-alpha Off -compose CopyOpacity -composite shade_beveled.png
Observe que cerca de metade do chanfro gerado pelo operador "[-shade](https://imagemagick.org/command-line-options/#shade)" na verdade cai fora da área mascarada. Em outras palavras, um chanfro reto é reduzido pela metade quando mascarado. Por outro lado, a imagem shade vertical ou de 'meio-dia' (usando o ângulo de elevação de '90' graus) pode ser usada apenas para extrair a borda chanfrada, deixando o centro da imagem oco.
magick shade_direction_135.gif \
\( shade_elevation_90.gif -normalize -negate \) \
-alpha Off -compose CopyOpacity -composite shade_beveled_edge.png
Observe, no entanto, que a imagem shade de 'meio-dia', embora forneça uma forma de mascarar a localização (e intensidade) dos efeitos do operador "[-shade](https://imagemagick.org/command-line-options/#shade)", não cobre realmente esses efeitos por completo. Combinando a imagem shade de 'meio-dia' com a máscara original, você pode aumentar ligeiramente o tamanho dessa máscara para produzir uma imagem chanfrada mascarada melhor.
![[IM Output]](../static/img/transform/shade_direction_180.gif)
magick shade_direction_135.gif \
\( shade_elevation_90.gif -normalize -negate \
shade_a_mask.gif -compose screen -composite \) \
-alpha Off -compose CopyOpacity -composite shade_beveled_plus.png
![[IM Output]](../static/img/transform/shade_beveled_plus.png)
Lembre-se de que, com o IM v6, é possível gerar a imagem de 'shade' que gerei anteriormente tudo no mesmo comando. Dessa forma, o exemplo acima poderia ter sido completamente gerado do zero. Por exemplo. |
magick -font Candice -pointsize 72 -background black -fill white \
label:X -trim +repage -bordercolor black -border 10x5 \
\( -clone 0 -shade 135x45 \) \
\( -clone 0 -shade 0x90 -normalize -negate \
-clone 0 -compose screen -composite \) \
-delete 0 -alpha Off -compose CopyOpacity -composite \
shade_beveled_X.png
Imagens de Forma Sombreada
O Operador Alpha Extract não apenas extrai o canal alfa de imagens com forma como uma máscara em escala de cinza, mas também tem o efeito colateral de preservar a forma no canal alfa 'desligado'. Como está 'desligado', ele não será tocado por muitos operadores de processamento de imagem, incluindo "[-shade](https://imagemagick.org/command-line-options/#shade)", preservando seu detalhe. O que isso significa é que, para imagens com forma, você pode extrair a forma, fazer o trabalho e, então, simplesmente recuperar a transparência DEPOIS de ter terminado todo o processamento de imagem, bastando ligar o Alpha novamente! Por exemplo, aqui desenho um 'Coração' sobre um fundo transparente, aplico algum desfoque e sombreamento à imagem e, então, restauro o contorno original da forma da imagem. |
magick -size 100x100 -gravity center -background None \
-font WebDings label:Y \
-alpha Extract -blur 0x6 -shade 120x21 -alpha On \
-normalize +level 15% -fill Red -tint 100% shade_heart.png
![[IM Output]](../static/img/transform/shade_heart.png)
Tudo o que posso dizer é NOSSA, que economia de tempo! Bem mais simples do que o comando anterior com todo o seu processamento extra e clonagem de imagem.
Arredondando as Bordas do Sombreamento
Como você viu no último exemplo, ao desfocar a máscara de forma da imagem, a 'inclinação' dos 'penhascos' das bordas será suavizada, como se fosse desgastada pelo tempo. Isso produz um agradável efeito arredondado na imagem sombreada.
magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
shade_circle_mask.gif
magick shade_circle_mask.gif -shade 120x45 shade_blur_0.gif
magick shade_circle_mask.gif -blur 0x1 -shade 120x45 shade_blur_1.gif
magick shade_circle_mask.gif -blur 0x2 -shade 120x45 shade_blur_2.gif
magick shade_circle_mask.gif -blur 0x3 -shade 120x45 shade_blur_3.gif
magick shade_circle_mask.gif -blur 0x4 -shade 120x45 shade_blur_4.gif
magick shade_circle_mask.gif -blur 0x5 -shade 120x45 shade_blur_5.gif
Como você pode ver, o desfoque não apenas arredonda as bordas, mas também torna os efeitos de iluminação mais fracos. Você pode maximizar o contraste do resultado normalizando-o, de modo a trazer os pontos mais claros e mais escuros de volta às cores puras branco e preto, respectivamente.
magick shade_blur_3.gif -normalize shade_blur_3n.gif
O único inconveniente disso é que, em geral, isso também escurece a imagem sombreada. Isso é algo que precisaremos levar em conta ao Criar Realces de Sobreposição. Vamos finalizar esta imagem sombreada mascarando-a diretamente também..
magick shade_blur_3n.gif shade_circle_mask.gif \
-alpha Off -compose CopyOpacity -composite shade_blur_3n_mask.png
Como você pode ver, desfocar a imagem da máscara arredonda muito bem as bordas da forma resultante.
Criando Realce de Sobreposição
A saída do operador "[-shade](https://imagemagick.org/command-line-options/#shade)" é muito boa, mas é raro que você realmente queira uma imagem em escala de cinza simples da sua forma. O que ela precisa é de alguma cor. Isso, no entanto, não é tão fácil, pois as duas principais maneiras de adicionar cor, Tingimento de Cor dos Tons Médios para apenas recolorir uma escala de cinza, ou a composição alfa 'Overlay', para substituir as áreas cinza por uma imagem, ambas dependem de uma forma especial de imagem em escala de cinza. Ou seja, um cinza de tom médio perfeito ('grey50') é substituído pela cor ou imagem, enquanto cinzas mais claros ou mais escuros clareiam e escurecem a cor ou imagem conforme apropriado. Essas imagens especiais de 'realce de sobreposição' em escala de cinza, com cinzas de tom médio perfeito para as áreas não modificadas, não são tão simples de criar usando "[-shade](https://imagemagick.org/command-line-options/#shade)". Contudo, as seguintes são algumas das maneiras mais simples que descobri. Usar um ângulo de iluminação de 30 graus de elevação com "[-shade](https://imagemagick.org/command-line-options/#shade)" é uma maneira de produzir um cinza de tom médio perfeito para áreas planas da forma sendo sombreada. Por exemplo, aqui sombreio uma imagem e, então, extraio o pixel superior esquerdo para verificar a cor resultante de uma parte 'plana' da imagem.
![[IM Output]](../static/img/transform/shade_blur_5.gif)
| |
magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
-blur 0x2 -shade 120x30 shade_30.png
magick shade_30.png -gravity center -crop 1x1+0+0 txt:-
Infelizmente, alterar o efeito de arredondamento do "[-blur](https://imagemagick.org/command-line-options/#blur)" no comando acima também tende a variar a intensidade do realce resultante da imagem sombreada. Ou seja, usar um desfoque grande não apenas produz uma borda de aparência bem arredondada, mas também torna o realce tão fraco a ponto de ficar quase invisível. Isso significa que você precisa adicionar bem mais contraste à saída da imagem produzida por "[-shade](https://imagemagick.org/command-line-options/#shade)" para tornar o realce eficaz como imagem de sobreposição. Para corrigir isso, precisamos de uma maneira de remover esse efeito de contraste do ajuste de arredondamento. A maneira típica de fazer isso é simplesmente aplicar "[-normalize](https://imagemagick.org/command-line-options/#normalize)" na imagem, mas fazer isso em uma imagem sombreada de 30 graus resulta em que as áreas 'planas' deixarão de ser um cinza perfeito. Por exemplo... | |
magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
-blur 0x2 -shade 120x30 -normalize shade_30_norm.png
magick shade_30_norm.png -gravity center -crop 1x1+0+0 txt:-
Após algumas experiências adicionais, porém, descobri que usar um ângulo de elevação de sombreamento de 21,78 graus, depois de normalizado, produzirá o desejado nível de cinza de tom médio perfeito, bem como um bom e forte efeito de realce. | |
magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
-blur 0x2 -shade 120x21.78 -normalize shade_21_norm.png
magick shade_21_norm.png -gravity center -crop 1x1+0+0 txt:-
Como a imagem sombreada agora passa pelo operador "[-normalize](https://imagemagick.org/command-line-options/#normalize)", o valor de "[-blur](https://imagemagick.org/command-line-options/#blur)" usado para 'arredondar bordas' não afetará mais a intensidade final do resultado. Um método muito melhor. Em resumo, normalizar uma imagem sombreada desloca os tons médios para longe de uma cor cinza perfeita. Agora podemos ajustar a intensidade de saída dos realces produzindo uma saída completamente independente dos outros ajustes. Tipicamente, como o resultado normalizado é extremo, precisaremos de uma des-normalização controlada, ou um controle de anti-contraste, para reduzir o realce ao nível desejado. O método mais simples para ajustar o realce resultante é tingir com cor a imagem com um cinza perfeito. Isso deslocará todos os níveis de cor da imagem em direção à cor cinza de tom médio puro central. Por exemplo...
magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
\( +clone -blur 0x2 -shade 120x21.78 -normalize \) \
+swap -alpha Off -compose CopyOpacity -composite shade_tint_0.png
magick shade_tint_0.png -fill grey50 -colorize 10% shade_tint_10.png
magick shade_tint_0.png -fill grey50 -colorize 30% shade_tint_30.png
magick shade_tint_0.png -fill grey50 -colorize 50% shade_tint_50.png
magick shade_tint_0.png -fill grey50 -colorize 80% shade_tint_80.png
Uma alternativa a apenas tingir linearmente o realce é reduzir seu efeito geral enquanto se preservam os pontos extremos claros/escuros do realce, usando o Contraste Não-linear Sigmoidal em vez disso. Isso deve dar uma aparência mais 'natural' ao efeito de realce e pode tornar o realce mais claro, como se a superfície fosse mais reflexiva. No entanto, para tornar essa técnica mais eficaz, precisamos garantir que não tenhamos cores puras branco e preto no resultado do sombreamento. Isso pode ser alcançado usando primeiro um "[-contrast-stretch](https://imagemagick.org/command-line-options/#contrast-stretch)" de '0%' em vez de "[-normalize](https://imagemagick.org/command-line-options/#normalize)", e também des-normalizando esse resultado por uma pequena quantidade, como fizemos acima. Isso pode parecer apenas adicionar complexidade à geração da imagem de sobreposição de realce, mas enfatizar os pontos claros no realce faz com que o processamento extra valha o esforço. Por exemplo...
magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
\( +clone -blur 0x2 -shade 120x21.78 -contrast-stretch 0% \) \
+swap -alpha Off -compose CopyOpacity -composite shade_sig_0.png
magick shade_sig_0.png -sigmoidal-contrast 10x50% shade_sig-10.png
magick shade_sig_0.png -sigmoidal-contrast 5x50% shade_sig-5.png
magick shade_sig_0.png -sigmoidal-contrast 2x50% shade_sig-2.png
magick shade_sig_0.png +sigmoidal-contrast 2x50% shade_sig+2.png
magick shade_sig_0.png +sigmoidal-contrast 5x50% shade_sig+5.png
magick shade_sig_0.png +sigmoidal-contrast 10x50% shade_sig+10.png
Como você pode ver, o realce geral é reduzido em intensidade, mas o ponto claro da luz refletida permanece tão brilhante como sempre, apenas reduzido em tamanho. O resultado é uma aparência 'brilhante' muito mais natural para a forma. O único inconveniente dessa técnica é que um 'ponto' de sombra também é gerado, embora isso muitas vezes não seja tão perceptível. Por fim, podemos combinar um 'ponto de realce' com uma redução geral do realce para produzir um conjunto altamente configurável de controles geradores de sobreposição de realce...
![[IM Output]](../static/img/transform/shade_tint_80.png)
magick -size 50x50 xc:black -fill white -draw 'circle 25,25 20,10' \
\( +clone -blur 0x4 -shade 120x21.78 -contrast-stretch 0% \
+sigmoidal-contrast 7x50% -fill grey50 -colorize 10% \) \
+swap -alpha Off -compose CopyOpacity -composite shade_overlay.png
- Em resumo, o exemplo acima tem quatro controles separados...
- "
[blur](https://imagemagick.org/command-line-options/#blur)" : Arredondamento das bordas da forma (0.001=chanfrado 2=suavizado 10=arredondado) - "
[shade](https://imagemagick.org/command-line-options/#shade)" : A direção de onde a luz vem (120=superior-esquerdo 60=superior-direito) - "
[sigmoidal](https://imagemagick.org/command-line-options/#sigmoidal-contrast)" : controle de pontos de realce da reflexividade da superfície (1=plano 5=bom 10=reflexivo ) - "
[colorize](https://imagemagick.org/command-line-options/#colorize)" : Contraste geral do realce ( 0%=claro 10%=bom 50%=fraco )
Observe que, embora os exemplos acima tenham sido moldados à forma 'circle' original, a transparência só deve ser restaurada DEPOIS que a composição 'Overlay' tiver sido aplicada, não antes. Além disso, se você planeja usar um realce repetidamente na mesma forma (após qualquer rotação ser realizada), pode pré-gerar a sobreposição de realce uma vez para cada forma que planeja usar, salvando o resultado para múltiplas reutilizações. Um exemplo dessa reutilização de sobreposição de sombreamento está na geração de capas de DVD 3D a partir de imagens de origem planas nos Fóruns de Discussão do IM. Também recomendo fortemente que você experimente com as técnicas acima, pois elas são fundamentais para tornar suas imagens de formas planas com uma aparência muito mais realista. Se você tiver outras ideias para realce, por favor me avise.
FUTURE:
Color Tinting the Overlay image
Overlay Alpha Composition with an Image
Usando um Realce de Sombreamento ao Amanhecer
Em Mascarando Imagens Sombreadas acima, mostramos como uma imagem sombreada de 'meio-dia' ou 'sol a pino' (usando uma elevação de '90') pode ser útil para mascarar a localização e a extensão dos efeitos produzidos por "[-shade](https://imagemagick.org/command-line-options/#shade). No entanto, as imagens sombreadas horizontais ou de 'amanhecer' (usando uma elevação de '0') de uma forma também podem ser bastante úteis. Elas podem, por exemplo, ser usadas como máscara para imagens brancas ou pretas, a fim de gerar efeitos separados de realce e sombreamento nas formas. Isso também pode ser usado para garantir que uma forma receba quantidades aproximadamente iguais de áreas claras e escuras (ou até mesmo quantidades desiguais), pois eu as produzo separadamente, mas de uma maneira completamente controlada.
FUTURE: more detail here
Veja o primeiro Logotipo 3D Avançado para um exemplo do uso dessa técnica.
Usando FX, o Operador de Imagem Faça-Você-Mesmo O operador de lista de imagens "[-fx](https://imagemagick.org/command-line-options/#fx)" é um operador geral do tipo faça-você-mesmo que não se encaixa em nenhuma categoria específica de operadores do IM, pois pode ser usado para criar praticamente qualquer operação de imagem. Exemplos de seu uso estão espalhados por estas páginas, mas aqui examinaremos especificamente suas capacidades e como você pode usá-las. O comando é tão genérico em suas habilidades que pode,
- criar telas, gradientes, mapas de cores matemáticos.
- mover valores de cor entre imagens e canais.
- ajustar as cores da imagem de praticamente qualquer maneira imaginável
- transladar, virar, espelhar, rotacionar, escalar, inclinar e distorcer imagens de modo geral.
- mesclar ou compor várias imagens juntas.
- ladrilhar imagem(ns) de maneiras estranhas e maravilhosas.
- convolver ou mesclar pixels vizinhos.
- gerar métricas de imagem ou 'impressões digitais'
- comparar imagens de maneiras incomuns.
Naturalmente, muitas dessas técnicas já fazem parte do IM, produzindo um resultado mais rápido e mais flexível. Mas, se não for algo embutido, o "[-fx](https://imagemagick.org/command-line-options/#fx)" permite que você gere sua própria versão da operação desejada. De fato, eu e outros frequentemente o usamos para prototipar novas operações que mais tarde são incorporadas à biblioteca central do IM. Como exemplo, veja Substituição Faça-Você-Mesmo do Novo Ordered Dither, onde usei "[-fx](https://imagemagick.org/command-line-options/#fx)" para desenvolver uma versão revisada do operador [-ordered-dither](https://imagemagick.org/command-line-options/#ordered-dither)". O operador essencialmente permite que você realize operações matemáticas de forma livre em uma ou mais imagens. Para o resumo oficial do comando, veja FX, o Operador de Imagem de Efeitos Especiais no Site do ImageMagick.
Uso Básico do FX
O comando recebe uma sequência de imagens com quantas imagens de entrada você quiser. Tipicamente, uma ou duas imagens, e substitui TODAS as imagens de entrada por uma cópia da primeira imagem, que foi modificada pelos resultados da função "[-fx](https://imagemagick.org/command-line-options/#fx)". Ou seja, quaisquer metadados presentes na primeira imagem serão preservados no resultado do operador "[-fx](https://imagemagick.org/command-line-options/#fx)". Para facilidade de uso matemático, todos os valores de cor fornecidos são normalizados em uma faixa de valores de 0.0 a 1.0. Também se espera que os resultados estejam nessa faixa. Isso inclui o canal de transparência ou alfa, que vai de 0.0 (significando totalmente transparente) a 1.0 (significando totalmente opaco). Os valores representam a 'transparência alfa' e são, na verdade, o negativo de como o IM normalmente armazena a transparência internamente (como valores de matte). Contudo, essa forma é mais correta matematicamente e mais fácil de usar. A configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" define qual(is) canal(is) na primeira imagem (também chamada de 'zerésima' ou "u") é substituído pelo resultado do operador "[-fx](https://imagemagick.org/command-line-options/#fx)". Isso é limitado, por padrão, apenas aos canais de cor ('RGB') da imagem original. Qualquer transparência existente nessa imagem não será modificada, a menos que a configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" seja alterada para incluir o canal alfa ('A'). A expressão é executada uma vez para cada pixel, bem como uma vez para cada canal de cor no pixel que está sendo processado. Além disso, como a expressão é reanalisada a cada vez que é executada, uma expressão complexa pode levar algum tempo para ser processada em uma imagem grande. Por exemplo, aqui definimos uma imagem preta, mas então definimos o canal azul como meio brilho para formar uma cor 'azul-marinho' em vez disso. |
magick -size 64x64 xc:black -channel blue -fx '1/2' fx_navy.gif
![[IM Output]](../static/img/transform/fx_navy.gif)
E aqui pegamos um gradiente preto-branco e, então, definimos os canais azul e verde como zero, de modo que ele se torne um gradiente preto-vermelho. |
magick -size 64x64 gradient:black-white \
-channel blue,green -fx '0' fx_red.gif
![[IM Output]](../static/img/transform/fx_red.gif)
| _Para tornar a configuração "-channel" mais parecida com o operador "-fx", ela aceitará quaisquer combinações das letras 'RGBA' para especificar os canais aos quais os operadores devem confinar suas ações.
Isso significa que, para limitar a saída de "-fx" apenas aos canais azul e verde, você agora pode dizer "-channel BG" em vez do mais longo "-channel blue,green"._
---|---
Poderíamos ter gerado os exemplos acima sem usar "[-fx](https://imagemagick.org/command-line-options/#fx)", mas o fato de poder fazer isso em uma imagem existente é o que torna este um poderoso operador de imagem. A função pode, de fato, ler e usar QUALQUER pixel, ou cor específica, de QUALQUER uma das imagens já presentes na sequência de imagens atual na memória. À primeira imagem 'zero' é dado o nome especial de "u". A segunda imagem, "v". Outras imagens na memória podem ser referenciadas por um índice. Assim, "u[3]" é a quarta imagem na sequência de imagens atual, enquanto "u[-1]" é a última imagem da sequência. Este é o mesmo esquema de indexação usado pelos Operadores de Lista de Imagens, então você deve se sentir em casa. Se nenhum outro qualificador for fornecido, o valor de cor usado é a mesma cor usada na imagem especificada. Ou seja, a menos que você diga especificamente que quer usar a cor vermelha, ele usará o valor de cor do canal de cor que o comando está processando naquele momento. Ou seja, ele aplicará a expressão para o valor de cor azul quando estiver processando o canal azul. A menos que instruído de outra forma, ele processará cada um dos valores de cor RGB (conforme definido pela configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" padrão), para cada e todo pixel na imagem. Ou seja, 3wh cálculos que modificam todos os valores na imagem pela expressão fornecida. Por exemplo, aqui pegamos a imagem "rose:" embutida no IM e multiplicamos todos os valores de pixel por 50%. |
magick rose: -fx 'u*1.5' fx_rose_brighten.gif
![[IM Output]](../static/img/transform/fx_rose_brighten.gif)
No exemplo acima, cada um dos valores individuais de vermelho, verde e azul foi multiplicado por 1.5. Se o valor resultante estiver fora da faixa de 0 a 1, ele será limitado ao limite apropriado (1.0 neste caso), a menos que você esteja usando a versão HDRI do ImageMagick. Muitas outras fórmulas de "[-fx](https://imagemagick.org/command-line-options/#fx)" para recolorir imagens são exploradas em Ajustes Matemáticos de Cor e Curvas de Histograma. Como também podemos referenciar qualquer imagem na sequência de imagens atual, como parte da expressão para modificar a primeira imagem, podemos mesclar duas, ou até mais imagens, de praticamente qualquer maneira que quisermos. Aqui geramos uma imagem de tabela de cores preto-vermelho-azul, copiando o canal azul de um gradiente preto-azul (rotacionado) para o gradiente preto-vermelho anterior que geramos acima.
magick -size 64x64 gradient:black-blue -rotate -90 fx_blue.gif
magick fx_red.gif fx_blue.gif \
-channel B -fx 'v' fx_combine.gif
| _Naturalmente, poderíamos ter usado apenas um Método de Composição por Cópia de Canal em vez disso, o que seria muito mais rápido. Mas esse não é o ponto.
Embora o inverso também seja verdadeiro. Praticamente toda operação de imagem do IM poderia ser substituída por uma função FX equivalente.
_
---|---
Agora, a segunda imagem no exemplo acima é usada apenas como imagem de origem. O que realmente acontece é que "[-fx](https://imagemagick.org/command-line-options/#fx)" primeiro cria uma cópia apenas da primeira imagem. Ele então modifica essa imagem de acordo com a fórmula, usando todas as outras imagens fornecidas. E finalmente descarta todas as imagens de entrada, substituindo-as pela cópia modificada da primeira imagem. Você também pode calcular valores com base em cada localização de pixel dentro da imagem. Os valores 'i,j' são a posição atual do pixel sendo processado, enquanto 'w,h' dão o tamanho da imagem (a primeira imagem, a menos que um qualificador de imagem específico seja fornecido). Por exemplo, aqui geramos uma Imagem de Gradiente Faça-Você-Mesmo. |
magick rose: -channel G -fx 'sin(pi*i/w)' -separate fx_sine_gradient.gif
![[IM Output]](../static/img/transform/fx_sine_gradient.gif)
Ou algo mais complexo usando ambos os valores de posição 'i,j'. |
magick -size 80x80 xc: -channel G -fx 'sin((i-w/2)*(j-h/2)/w)/2+.5'\
-separate fx_2d_gradient.gif
![[IM Output]](../static/img/transform/fx_2d_gradient.gif)
Ao gerar gradientes em escala de cinza, você pode fazer o operador -fx trabalhar cerca de 3 vezes mais rápido, simplesmente pedindo que ele processe apenas um canal de cor, como o canal 'G' ou verde no exemplo acima. Esse canal pode então ser Separado para gerar a imagem final em escala de cinza. Isso pode representar um enorme ganho de velocidade, especialmente ao usar uma fórmula "[-fx](https://imagemagick.org/command-line-options/#fx)" muito complexa. Para mais gradientes gerados por FX, veja os exemplos Crie Seus Próprios Gradientes. Você pode usar a informação de posição para consultar pixels específicos da imagem de origem usando a sintaxe 'p{x,y}'. Por exemplo, você pode facilmente criar sua própria função do tipo 'imagem espelhada' (como o operador de imagem "[-flop](https://imagemagick.org/command-line-options/#flop)"), que substitui cada pixel pelos valores de cor da posição 'espelho' da origem original. |
magick rose: -fx 'p{w-i-1,j}' fx_rose_mirror.gif
![[IM Output]](../static/img/transform/fx_rose_mirror.gif)
Esse tipo de 'distorção de imagem' foi tornado mais poderoso ao criar Mapeamento de Imagem de Distorção, ou outros tipos de Tabelas de Consulta de Valores, na forma de imagens. Exemplos de como fazer isso foram fornecidos em Padrões de Pontilhamento Faça-Você-Mesmo e Mapas de Limiar, onde o FX é usado para substituir cores específicas por padrões de outras imagens. Agora, o tamanho da imagem final gerada por uma expressão FX é o mesmo da primeira imagem fornecida, portanto, para gerar uma imagem maior, você precisará definir a primeira imagem com o tamanho que desejar. Nesse tipo de situação, uma segunda imagem (ou até uma terceira imagem) pode ser usada como fonte de cor (daí o Swap no próximo exemplo). Por exemplo, aqui redimensionamos a imagem rose (usando Escalonamento ou Redimensionamento Interpolado) para gerar uma imagem maior. |
magick rose: -size 120x80 xc: +swap \
-fx 'v.p{ (i+.5)*v.w/w-.5, (j+.5)*v.h/h-.5 }' \
fx_scaled.png
![[IM Output]](../static/img/transform/fx_scaled.png)
Observe como a consulta de pixel é realizada; pode parecer complexo, mas é a maneira correta de escalar (distorcer) uma imagem. Basicamente, todos os valores '0.5' extras adicionados à expressão são necessários para converter corretamente entre as Coordenadas de Pixel usadas para as coordenadas de entrada 'i,j' e a consulta de localização 'v.p{...}', enquanto as Coordenadas de Imagem mais corretas matematicamente são necessárias para os cálculos matemáticos propriamente ditos (escalonamento). O acima é, na verdade, exatamente a metodologia usada por qualquer forma de Distorção de Imagem. Você pode ver esse equivalente em FX para a maioria das distorções ativando o Resumo Verboso de Distorção. Isso reporta um equivalente em FX para a maioria das distorções de imagem, como forma de verificar se a distorção está fazendo o que se espera. O uso do Operador Faça-Você-Mesmo FX para fazer distorções de imagem mostra o quão poderoso este operador realmente é. Se não fosse por este operador, duvido que muitas das novas operações, como distorções, sparse-color ou ordered dithers, teriam sido adicionadas à Biblioteca Central do ImageMagick. Aqui está algo um pouco mais simples, trocando os canais vermelho e azul da imagem rose. Veja se você consegue descobrir como funciona. |
magick rose: \( +clone -channel R -fx B \) \
+swap -channel B -fx v.R fx_rb_swap.gif
![[IM Output]](../static/img/transform/fx_rb_swap.gif)
| _Uma maneira mais rápida e melhor de fazer a mesma coisa é usar "[-separate](https://imagemagick.org/command-line-options/#separate)" e "[-combine](https://imagemagick.org/command-line-options/#combine)"). Veja Combinando Imagens de Canal RGB. Como alternativa, você também pode usar uma "[-color-matrix](https://imagemagick.org/command-line-options/#color-matrix)" para fazer a mesma coisa ainda mais rápido.
Você percebe uma tendência aqui?_
---|---
Como a configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" padrão limita a saída do operador "[-fx](https://imagemagick.org/command-line-options/#fx)" apenas aos três canais de cor. Isso significa que, se você quiser afetar o canal alfa ou de transparência, deve especificá-lo explicitamente, alterando a configuração do canal. Por exemplo, vamos criar uma imagem "rose:" semi-transparente, definindo todos os valores do canal alfa para a metade. |
magick rose: -alpha set -channel A -fx '0.5' fx_rose_trans.png
![[IM Output]](../static/img/transform/fx_rose_trans.png)
Observe que, para que o exemplo acima funcione corretamente, precisei garantir que a "rose:" realmente tivesse um canal alfa com o qual o "[-fx](https://imagemagick.org/command-line-options/#fx)" pudesse trabalhar. Fiz isso com o Operador de Controle do Canal Alfa. Essa capacidade do operador "[-fx](https://imagemagick.org/command-line-options/#fx)" de manipular os canais RGBA de uma imagem torna este operador perfeito para manipular Canais e Máscaras.
A partir do IM 6.2.10, você pode adicionar atribuições de variáveis às expressões "[-fx](https://imagemagick.org/command-line-options/#fx)", o que permite reduzir a complexidade de algumas expressões que basicamente seriam impossíveis de qualquer outra maneira. Por exemplo, aqui crio um gradiente com base na distância a partir de um ponto específico (atribuído às variáveis 'xx' e 'yy'). Sem o uso das variáveis, esta fórmula poderia ter se tornado muito difícil de ler. |
magick -size 100x100 xc: -channel G \
-fx 'xx=i-w/2; yy=j-h/2; rr=hypot(xx,yy); (.5-rr/70)*1.2+.5' \
-separate fx_radial_gradient.png
![[IM Output]](../static/img/transform/fx_radial_gradient.png)
| Devido ao tratamento simples de tokenização usado pelo "[-fx](https://imagemagick.org/command-line-options/#fx)", os nomes de variáveis só podem consistir em letras e não devem conter números. Além disso, como muitas letras individuais são usadas para variáveis internas de acesso à informação da imagem, recomenda-se que os nomes de variáveis tenham pelo menos duas letras de comprimento. Por isso, uso 'xx' e 'yy' em vez de apenas 'x' ou 'y'.
---|---
| _A função "[-fx](https://imagemagick.org/command-line-options/#fx)" 'rr=hypot(xx,yy)' foi adicionada ao IM v6.3.6 para acelerar a expressão muito comumente usada 'rr=sqrt(xx*xx+yy*yy)'.
Naturalmente, se você precisar da distância ao quadrado, deve evitar a função 'hypot()' e a função sqrt() que ela implica._
---|---
Para mais exemplos de algumas expressões realmente complexas, veja Gradientes Faça-Você-Mesmo Mais Complexos, que seriam impossíveis sem atribuições de múltiplas instruções. O mesmo vale para a forma FX da Distorção de Perspectiva. A partir da versão IM 6.3.0-1, a complexidade das expressões "[-fx](https://imagemagick.org/command-line-options/#fx)" começou a exigir arquivos externos, então o padrão '@_filename_' agora pode ser usado para ler a expressão de um arquivo. |
echo "u*2" | magick rose: -fx "@-" fx_file.png
![[IM Output]](../static/img/transform/fx_file.png)
Isso também significa que você pode usar scripts mais complexos para gerar as expressões FX específicas para um determinado trabalho. Internamente, o arquivo é simplesmente lido para uma string e interpretado normalmente. Outras configurações importantes para o "[-fx](https://imagemagick.org/command-line-options/#fx)" são "[-virtual-pixel](https://imagemagick.org/command-line-options/#virtual-pixel)" e "[-interpolate](https://imagemagick.org/command-line-options/#interpolate)". A Configuração de Pixel Virtual permite definir quais cores ou resultados de imagem devem ser retornados quando as coordenadas de consulta saem da área coberta pela imagem de entrada. Isso permite definir efeitos de borda para coisas como desfoques, bem como ladrilhar a imagem sobre uma área maior. A Configuração de Interpolação permite especificar como o IM deve misturar as cores de pixels vizinhos quando as coordenadas de consulta (valores de ponto flutuante) caem entre as coordenadas inteiras dos pixels na imagem de entrada. Para mais informações, veja Consulta de Pixel Interpolada. | Mais algumas funções foram adicionadas em diferentes momentos
IM v6.3.6 : hypot()
IM v6.7.3-4 : while(), not(), guass(), squish()
---|---
Depuração de FX
O 'debug(_expr_)' é essencialmente uma maneira de imprimir um valor de ponto flutuante, cada vez que a expressão FX é calculada. Isso, por sua vez, fornece um método para depurar suas expressões. No entanto, você pode limitar a saída do "debug()" usando uma expressão ternária if-else. Por exemplo, isto imprimirá os valores de cor de ponto flutuante para o pixel 10,10 da imagem "rose:" embutida. O resultado real da imagem é ignorado usando o manipulador de imagem '[NULL:](files.html#null)'. |
magick rose: -fx 'i==10&&j==10?debug(u):1; u' null:
![[IM Output]](../static/img/transform/fx_debug.txt.gif)
Lembre-se de que a saída está no erro padrão, não na saída padrão normal, de modo que você pode usar isso em um pipeline de comandos, sem problemas. Observe como a expressão FX foi executada três vezes, uma vez para cada canal apenas para aquele único pixel. Multiplique isso pelo número de pixels e você pode imaginar o tamanho da saída se o "debug()" não estivesse limitado a apenas um pixel, mesmo para esta pequena imagem.
Operações Embutidas Semelhantes ao FX
O operador [-fx](https://imagemagick.org/command-line-options/#fx) representa uma maneira de desenvolver novas funções de processamento de imagem que antes não existiam no ImageMagick. O resultado desse desenvolvimento pelos usuários permitiu que o ImageMagick se expandisse, com novas funções e métodos, como a Tabela de Consulta de Cor ("[-clut](https://imagemagick.org/command-line-options/#clut)"). Geralmente, no entanto, uma vez que um novo método se estabiliza usando "[-fx](https://imagemagick.org/command-line-options/#fx)", a expressão é convertida em uma operação embutida mais rápida, geralmente adicionada como parte de um grupo de operadores semelhantes. Estes incluem o seguinte operador geral de imagem e seus métodos... -evaluate | Funções de modificação direta de pixel, valores de cor e canal.
(Veja Evaluate abaixo).
---|---
-function | Funções mais complexas de modificação de pixel, valor de cor e canal.
(Veja Function abaixo).
-evaluate-sequence | Mescla matematicamente uma sequência de múltiplas imagens
(Veja Evaluate-Sequence abaixo).
-sparse-color | Operador Geral de Recoloração de Imagem.
(Veja Gradientes de Sparse Color )
-compose | Método geral de combinação e sobreposição de múltiplas imagens.
(Veja Composição Alfa).
-distort | Operador Geral de Distorção de Imagem, usando mapeamento reverso de pixel.
(Veja o Operador Distort )
-morphology | Função geral de Convolução/Morfologia de Efeito de Área.
(Veja o Operador Morphology e o Operador Convolve )
À medida que as pessoas desenvolviam novos tipos de operações de imagem, elas geralmente os prototipavam usando primeiro um operador "[-fx](https://imagemagick.org/command-line-options/#fx)". Quando o têm bem resolvido, esse 'método' é então convertido em um novo operador embutido super-rápido na biblioteca Central do ImageMagick. Os usuários são bem-vindos a contribuir com suas próprias expressões "[-fx](https://imagemagick.org/command-line-options/#fx)" (ou outras funções definidas) que acreditam ser um acréscimo útil ao IM, mas que ainda não são cobertas por outros operadores de imagem; se puderem ser tratadas por um dos operadores generalizados acima, deve ser razoavelmente fácil adicioná-las. Por exemplo, eu mesmo precisei de uma operação do tipo 'mascarar se a cor for similar' para comparar duas imagens. Isso foi adicionado como um novo método "[-compose](https://imagemagick.org/command-line-options/#compose)" chamado "[ChangeMask](compose.html#changemask)". Isso, por sua vez, me permitiu adicionar uma Otimização de Transparência mais complexa para animações GIF. Se a velocidade e a complexidade do "[-fx](https://imagemagick.org/command-line-options/#fx)" começarem a se tornar um problema, então provavelmente é melhor passar para uma linguagem de script de API, como o PerlMagick. Um exemplo disso usando PerlMagick "[pixel_fx.pl](https://github.com/ImageMagick/ImageMagick/blob/main/PerlMagick/demo/pixel-fx.pl)" faz parte da distribuição dessa API.
Expressões FX como Escapes de Formato e Anotação
A partir da versão IM 6.2.10, você agora pode usar Expressões FX dentro de strings de Escape de Propriedade de Imagem, como as usadas pelos argumentos "[-format](https://imagemagick.org/command-line-options/#format)" e "[-annotate](https://imagemagick.org/command-line-options/#annotate)". A sequência de escape '%[fx:...]' é substituída por um número como um valor de ponto flutuante, calculado uma vez para cada imagem na sequência de imagens atual. A Expressão FX, no entanto, é modificada ligeiramente durante o processamento. Especificamente...
- As coordenadas de pixel atuais '
i', 'j' são fixadas no valor 0, então, por si só, uma variável de imagem só retorna o valor do pixel 0,0, a menos que um índice 'p{}' seja usado. - A menos que um canal de cor seja selecionado, apenas o valor do canal vermelho é retornado.
- A referência de imagem padrão '
s' é definida como a imagem atual, sendo anotada ou identificada. - O índice '
t' retorna o índice da imagem referida por 's'.
| Antes do IM v6.6.8-6, ambos os valores da expressão FX de "t" (índice da imagem) e "n" (número total de imagens) estavam quebrados e retornavam apenas os valores 0 e 1, respectivamente, para TODAS as imagens. O mesmo vale para os escapes de porcentagem equivalentes '%p' e '%n'.
---|---
Por exemplo, aqui "[-annotate](https://imagemagick.org/command-line-options/#annotate)" cada imagem com a cor do canto superior esquerdo de cada imagem. |
magick -size 150x25 xc:DarkRed xc:Green xc:Blue \
-fill white -gravity center \
-annotate 0 '%[fx:t] / %[fx:n] : %[fx:r],%[fx:g],%[fx:b]' \
annotate_fx_%d.gif
![[IM Output]](../static/img/transform/annotate_fx_2.gif)
Observe como o texto que é escrito é diferente para cada imagem, pois 'r' é, na verdade, equivalente a 's.p{0,0}.r'. O mesmo vale para os valores dos canais de cor 'g' e 'b'. Naturalmente, cada um retorna um valor normalizado na faixa de 0.0 a 1.0. Para tornar mais fácil a saída de valores de cor de pixel específicos, um escape '%[pixel:...]' também foi adicionado no IM v6.3.0. Este operador chama a expressão FX fornecida uma vez para cada canal em cada imagem e formata o valor retornado em uma cor que o IM pode tratar como um argumento de cor.
magick -size 300x100 gradient:yellow-limegreen \
-gravity NorthWest -annotate 0 '%[pixel:s.p{0,0}]' \
-gravity Center -annotate 0 '%[pixel:s.p{0,50}]' \
-gravity SouthEast -annotate 0 '%[pixel:s.p{0,99}]' \
annotate_pixel.gif
Você pode simplesmente gerar o resultado diretamente usando um "[-format](https://imagemagick.org/command-line-options/#format)" com o comando "[identify](basics.html#identify)". |
magick identify -format '%[fx:atan(1)*4]' null:
![[IM Output]](../static/img/transform/fx_math.txt.gif)
Isso calculará matematicamente e retornará o valor de PI , embora esse valor esteja disponível como a variável embutida 'pi'. Você pode gerar números aleatórios. Por exemplo, para gerar um inteiro entre -5 e 10 inclusive. Aqui uso o equivalente "[info:](https://usage.imagemagick.org/files/#info:)" ao comando "magick identify". |
magick xc: -format '%[fx:int(rand()*16)-5]' info:
![[IM Output]](../static/img/transform/fx_rand.txt.gif)
Para mais métodos, veja Alternativas ao Identify: Opções de Saída de Texto. Veja também Borda com Canto Arredondado, que usou uma Expressão FX para gerar uma string de desenho com base nas informações de largura e altura da imagem. Você pode Calcular Posições de Imagens usando fórmulas FX ou até posicionar usando o tamanho e a localização de outras imagens (Veja Posições Calculadas Incrementalmente). Você também pode usar Escapes FX em Escapes de Porcentagem de Nome de Arquivo para gerar novos arquivos com base em valores calculados. Para um exemplo, veja o exemplo final em Recorte em Ladrilho.
Todos os exemplos acima essencialmente executarão o "[-format](https://imagemagick.org/command-line-options/#format)" e, portanto, qualquer Expressão FX contida uma vez para cada imagem na sequência de imagens atual. O operador "[-print](https://imagemagick.org/command-line-options/#print)" funcionará de maneira muito semelhante ao "[-identify](https://imagemagick.org/command-line-options/#identify)", exceto que é executado apenas uma vez, com acesso a TODAS as imagens na sequência de imagens atual. Com este operador, você pode usar 'u[{i}]' para acessar valores de qualquer imagem, ao contrário do acima.
Expressões FX podem ser aplicadas a imagens em outros espaços de cor, então posso, por exemplo, descobrir o valor de 'Matiz' (no canal 'vermelho') para três cores diferentes. |
magick xc:red xc:green xc:blue -colorspace HSL \
-format '%[fx: s.r ]\n' info:
![[IM Output]](../static/img/transform/fx_hues.txt.gif)
Você também pode usar o IM para alguns cálculos diretos de cor, como descobrir a cor média de 'gold', 'yellow' e 'khaki'. |
magick xc: -format '%[pixel:(gold+yellow+khaki)/3]' info:
![]()
Enquanto isso mostra como a cor se parece em comparação com as três cores de origem... |
magick xc:gold xc:yellow xc:khaki +append \
\( xc: -fx '(gold+yellow+khaki)/3' \) \
-scale 90x30\! -append fx_hues.png
![[IM Output]](../static/img/transform/fx_hues.png)
Você também pode usar "[-print](https://imagemagick.org/command-line-options/#print)" para imprimir informações. Isso é aplicado apenas uma vez em toda a sequência de imagens. Isso significa que você pode usar este operador para calcular expressões '%[fx:...]' muito mais complexas envolvendo múltiplas imagens.
Acessando dados de outras imagens
Há, no entanto, um problema sério ao usar expressões escapadas de FX. O IM não tem acesso direto às outras imagens na sequência de imagens atual quando você está criando imagens. Isso geralmente não é necessário na criação típica de imagens, pois novas imagens geralmente não dependem de imagens anteriores na memória. Basicamente, se você quiser obter a cor de um pixel específico em uma imagem diferente daquela que está desenhando (como acima), ou está criando uma nova imagem, então as funções centrais do IM não têm nenhum vínculo direto com a informação desejada. Por exemplo, se você tentar criar um rótulo com a cor do pixel 12,26 da imagem "rose:" embutida (um pixel azulado), a abordagem direta falhará! |
magick rose: label:'%[pixel:p{12,26}]' -delete 0 label_fx_direct.gif
![[IM Output]](../static/img/transform/label_fx_direct.gif)
Bem, a imagem rose na verdade não contém nenhum pixel preto, então o resultado acima estava errado. A maneira de corrigir isso é extrair a informação desejada e salvá-la nos metadados globais do IM. Isso é passado para todas as sub-rotinas no núcleo da biblioteca, incluindo aquelas para criação de imagem. |
magick rose: -set option:mylabel '%[pixel:u.p{12,26}]' -delete 0 \
label:'%[mylabel]' label_fx_indirect.gif
![[IM Output]](../static/img/transform/label_fx_indirect.gif)
Isso não é intuitivo, mas agora obtemos o resultado correto. A tag especial 'option:' diz à opção "[-set](https://imagemagick.org/command-line-options/#set)" que você quer que a configuração fornecida seja salva como um Artefato global, em vez de como uma string de 'Atributo' ou 'Propriedades' da imagem, assim como o "[-define](https://imagemagick.org/command-line-options/#define)" pode. No entanto, a forma "[-set](https://imagemagick.org/command-line-options/#set)" permite que você expanda os Escapes de Porcentagem ao definir o Artefato, enquanto o "[-define](https://imagemagick.org/command-line-options/#define)" não. Quando o operador "label:" expande seus escapes de porcentagem, a 'chave' fornecida é procurada primeiro como um 'atributo' ou 'propriedades' por imagem, mas, se não encontrar nada, então procurará a 'chave' nas configurações globais de Artefato. Assim, o 'artefato' global que criamos a partir da imagem anterior é usado, mesmo que essa imagem não esteja mais presente no momento em que o Artefato foi criado. Basicamente, as configurações de 'Artefato' são globais durante o tempo de vida do comando "magick" e, portanto, podem ser usadas para passar informação de uma imagem para outra. Para APIs programadas, essa situação pode ser evitada, pois você pode ler os dados necessários diretamente da imagem e gerar a string do rótulo você mesmo, sem precisar que o IM armazene essa informação de forma tão complicada.
Evaluate e Function, Modificadores de Canal de Forma Livre
Como o Operador FX é um manipulador de expressões interpretadas, o operador "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)" foi adicionado para permitir que você faça modificações simples de imagem mais rapidamente. Mais tarde, um operador "[-function](https://imagemagick.org/command-line-options/#function)" mais complexo foi adicionado no IM v6.4.8-8, para permitir maior flexibilidade em ajustes complexos de imagem. Esses dois operadores, junto com outros Operadores de Ajuste de Nível de Imagem, como "[-negate](https://imagemagick.org/command-line-options/#negate)", "[-level](https://imagemagick.org/command-line-options/#level)", provavelmente serão mais úteis para pequenos ajustes em imagens em escala de cinza, antes de você aplicar essas imagens. Especialmente em imagens em escala de cinza, como as usadas para Remoção de Fundo, Sobreposições de Realce e Sombra, e a geração e o ajuste fino de Mapas de Imagem.
Evaluate, Operações Matemáticas Simples
O operador "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)" é basicamente uma versão rápida, mas muito simples, do operador "[-fx](https://imagemagick.org/command-line-options/#fx)" (na verdade, precede sua adição ao IM por apenas alguns meses). No entanto, ele é limitado a apenas uma operação simples, usando um único número constante fornecido pelo usuário. Você pode descobrir quais funções foram embutidas no evaluate usando
magick -list evaluate
Isso inclui as funções matemáticas típicas 'add', 'subtract', 'multiply' e 'divide', contra valores constantes. Ao contrário do operador [-fx](https://imagemagick.org/command-line-options/#fx), os valores não são normalizados em uma faixa de 0 a 1, mas permanecem os valores de cor reais da imagem. Assim, subtrair um valor de 50 em um IM Q8 (Veja Qualidade e Profundidade) resultará em uma grande subtração, mas para uma versão Q16 do IM, será apenas uma pequena alteração quase imperceptível. No entanto, se você adicionar um '%' ao argumento, esse argumento representará uma porcentagem do valor máximo de cor (conhecido como 'QuantumRange', que é igual a ('2 _quality_ -1'). Isso significa que você pode tornar seus argumentos "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)" independentes do nível de qualidade do IM, pelo uso apropriado de porcentagens para os métodos de evaluate apropriados. Por exemplo, simplesmente substituir todos os valores de cor de uma imagem por um nível de cinza de 50% é muito simples e muito rápido, usando 'Set ' |
magick rose: -evaluate set 50% rose_set_gray.gif
![[IM Output]](../static/img/transform/rose_set_gray.gif)
O operador "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)" também inclui as funções matemáticas típicas 'add', 'subtract', 'multiply' e 'divide'. Por exemplo, para reduzir pela metade o contraste da imagem, você pode 'divide '-la por '2' e então 'add ' '25% para recentralizá-la em torno de um cinza perfeito. |
magick rose: -evaluate divide 2 -evaluate add 25% rose_de-constrast.gif
![[IM Output]](../static/img/transform/rose_de-constrast.gif)
Isso é algumas ordens de magnitude mais rápido do que usar diretamente o operador "[-fx](https://imagemagick.org/command-line-options/#fx)" com 'u/2+.25'. Assim, você deve usar este operador em preferência ao "[-fx](https://imagemagick.org/command-line-options/#fx)" sempre que possível. O principal problema com o "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)" é que todos os resultados são cortados nos limites de 0 a 'QuantumRange' (a menos que você esteja usando uma versão HDRI do ImageMagick), pois cada valor modificado é salvo de volta nos dados da imagem. Isso significa que, após qualquer operação individual de "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)", os valores poderiam ser cortados pelo 'QuantumRange'. Assim, se você tentar aplicar uma função de aumento de contraste (equivalente a "[-fx](https://imagemagick.org/command-line-options/#fx) '2*u-.25' ") diretamente como está, você falhará em obter os resultados corretos, pois o valor dobrado será cortado antes que a subtração seja feita. |
magick rose: -evaluate multiply 2 -evaluate subtract 25% \
rose_contrast.gif
![[IM Output]](../static/img/transform/rose_contrast.gif)
Primeiro, o 'multiply ' cortará todos os grandes valores de cor no valor máximo, então o 'subtract' cortará os valores do limite inferior. o resultado é um corte incorreto dos limites superiores, produzindo um resultado escuro e com cor distorcida. A solução direta é 'subtract ' a constante apropriada primeiro (fazendo o corte final, mas correto, dos limites inferiores), antes de multiplicar, usando efetivamente a fórmula equivalente '(u-.125)*2' |
magick rose: -evaluate subtract 12.5% -evaluate multiply 2 \
rose_contrast2.gif
![[IM Output]](../static/img/transform/rose_contrast2.gif)
No entanto, há muitas alternativas a esse problema de 'corte'. A primeira lógica sendo o mais novo Método de Função Polinomial (veja abaixo). Outras alternativas também incluem usar Operadores de Ajuste de Nível ou até um Ajuste de Nível por Cor, para simplesmente especificar os valores de cor originais que você quer expandir, para preencher toda a faixa de cor. Basicamente, tenha cuidado com relação ao corte de valores de cor ao usar múltiplos métodos "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)".
O operador "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)", como o "[-fx](https://imagemagick.org/command-line-options/#fx)" (e a maioria dos outros operadores de baixo nível do IM), é afetado por "[-channel](https://imagemagick.org/command-line-options/#channel)". Isso permite que você controle a transparência alfa de uma imagem separadamente dos canais de cor. E sim, como o "[-fx](https://imagemagick.org/command-line-options/#fx)", a transparência é tratada como 'valores alfa' e não como um valor de 'matte'. Por exemplo, para tornar uma imagem 50% transparente, como parte de uma operação do tipo Dissolve. |
magick rose: -alpha set -channel A -evaluate divide 2 rose_transparent.png
![[IM Output]](../static/img/transform/rose_transparent.png)
O resultado é uma imagem semi-transparente, o que significa que, quando exibida, metade da cor que você vê é a cor de fundo da página web. Assim, a imagem mostrada é atenuada em direção à cor de fundo. Muitas vezes, também descobri que costuma ser mais fácil usar "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)" nos canais de cor individuais antes de separar os vários canais em imagens separadas para propósitos específicos, (Veja Separando Canais). Por exemplo, aqui o uso para fazer uma forma rápida, mas incomum, de conversão em escala de cinza. Basicamente, multiplico cada canal pela quantidade apropriada, então separo e adiciono os canais juntos para produzir uma imagem que foi convertida em escala de cinza usando um conjunto específico de proporções de cor. |
magick test.png -channel R -evaluate multiply .2 \
-channel G -evaluate multiply .5 \
-channel B -evaluate multiply .3 \
-channel RGB -separate -background black -compose plus -flatten gray_253.png
Funções Matemáticas do Evaluate
Incluído no Evaluate, há também um conjunto de funções matemáticas de propósito especial. Essas funções são implementadas para geralmente usar um valor de cor normalizado (faixa de 0 a 1) com a saída novamente normalizada de modo a se ajustar à faixa completa de cor da imagem. A função de Contraste Sigmoidal também é um exemplo desse ajuste de função matemática.
Potência de
A função 'Pow ' (adicionada no IM v6.4.1-9), por exemplo, opera com valores de cor normalizados e permite ao usuário fazer modificações no brilho da imagem. É exatamente equivalente à função pow() do C (usando valores de cor normalizados na faixa de 0 a 1)
value = pow(value, constant)
Assim, para criar um gradiente 'parabólico', você pode usar um argumento de '2'. Ou usar um valor de '0.5' para criar um gradiente de 'raiz quadrada'. Por exemplo...
magick -size 20x600 gradient: -rotate 90 gradient.png
magick gradient.png -evaluate Pow 2 eval_pow_parabola.png
magick gradient.png -evaluate Pow 0.5 eval_pow_sq_root.png
| As três imagens inferiores mostram o perfil do gradiente produzido, tanto em um gráfico quanto na própria imagem original. Isso facilita ver como uma imagem de gradiente foi modificada para se tornar outra. Foi gerado usando o programa de plotagem de gráficosGnuplot, através do script "[im_profile](../static/img/scripts/im_profile)" no diretório Scripts dos IM Examples.
---|---
Isso é, na verdade, equivalente ao operador de Ajuste de Gamma, mas com o argumento invertido. Por exemplo, uma operação "-gamma 2" seria equivalente a uma operação "-evaluate pow 0.5" ou a uma função de 'raiz quadrada'. Da mesma forma, "-gamma 0.5" é equivalente a elevar ao quadrado usando "-evaluate pow 2"Fazendo algumas manipulações especiais de gradiente, você pode usar esse método para transformar um gradiente linear em um arco circular complexo. |
magick -size 20x300 gradient: -rotate 90 \
-evaluate Pow 2 -negate -evaluate Pow 0.5 \
-flop \( +clone -flop \) +append eval_circle_arc.png
![[IM Output]](../static/img/transform/eval_circle_arc_pf.gif)
Para aqueles que quiserem entender isso, a segunda linha acima é equivalente à expressão FX 'sqrt(1-u^2)'. Isso gera um único arco de quarto de círculo, que é então Invertido horizontalmente e Anexado para produzir um arco semicircular. Também é muito mais rápido do que usar uma expressão FX, embora exija muitos mais passos individuais (menores). Veja também a mais avançada Função Polinomial.
Logarítmico
A função 'Log ' (adicionada no IM v6.4.2-1) também opera com valores normalizados (com 1.0 adicionado para evitar infinitos), sendo a constante fornecida usada como a base logarítmica. A fórmula real (com valores normalizados) é, portanto...
value = log(value*constant+1.0)/log(constant+1.0)
Por exemplo... |
magick gradient.png -evaluate Log 10 eval_log.png
![[IM Output]](../static/img/transform/eval_log_pf.gif)
Isso pode parecer muito semelhante ao Método Pow de Evaluate anterior, mas não é exatamente igual. 'Log' produzirá uma inclinação apreciável à medida que se aproxima de '0', enquanto 'Pow' produzirá uma inclinação vertical. O valor controla a inclinação. Uma função logarítmica também está estreitamente relacionada a uma função exponencial, que atualmente só está implementada como o operador de Ajuste de Contraste Sigmoidal. Ele contém as mesmas características de inclinação que você pode ver nas curvas logarítmicas acima. Isso explica por que "[-sigmoidal-contrast](https://imagemagick.org/command-line-options/#sigmoidal-contrast)" é uma técnica melhor para realçar imagens que envolvem condições de baixa luminosidade do que um Ajuste de Gamma ou uma curva de 'potência de'.
Seno e Cosseno
A partir do IM v6.4.8-8, os métodos 'sin ' e 'cos ' foram adicionados. Esses métodos pegam o valor fornecido na imagem e o normalizam em um ângulo, de modo que a faixa completa cubra um círculo completo de ângulos. O resultado recebe um viés de 50% e é escalado novamente para se ajustar à faixa normal de valores. A constante é usada como um multiplicador para o valor (e, portanto, para o ângulo), de modo que 'N' significa que a função percorrerá o círculo 'N' vezes ao longo de toda a faixa de valores. Especificamente, isso define estas funções (usando valores normalizados) como...
value = 0.5 * sin( constant*value*2*PI ) + 0.5
value = 0.5 * cos( constant*value*2*PI ) + 0.5
Em essência, o que essas funções fazem é remapear os valores da imagem (geralmente valores em escala de cinza) para uma curva senoidal/cossenoidal. Por exemplo, aqui eu pego uma imagem de gradiente e a modifico usando esses métodos de evaluate.
magick gradient.png -evaluate sin 1 eval_sin_1.png
magick gradient.png -evaluate cos 1 eval_cos_1.png
Agora, como o parâmetro da constante é um multiplicador de ângulo, o valor fornecido ao método de evaluate criará esse número de picos ao longo de todo o gradiente dentro de uma imagem. |
magick gradient.png -evaluate cos 5 -negate eval_cos_5.png
![[IM Output]](../static/img/transform/eval_cos_5_pf.gif)
Isso é perfeito para muitas tarefas, desde a geração de efeitos de ondulação ou dispersão até a geração de curvas de deslocamento com aparência de ondulação. Usando uma constante multiplicadora de '0.5', você pode simplesmente transformar um gradiente linear em um gradiente de curva senoidal, que ainda tem a mesma inclinação do original. Negando o resultado, você pode garantir que o gradiente também se incline corretamente. |
magick gradient.png -evaluate cos 0.5 -negate eval_cos.5.png
![[IM Output]](../static/img/transform/eval_cos.5_pf.gif)
O que é ótimo para gerar gradientes suaves para uso em fotos sobrepostas. No entanto, esses dois últimos métodos de "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)" são raramente usados, pois foram substituídos por uma Função Sinusoid mais geral (veja abaixo), que fornece mais opções de controle, além de uma simples opção de frequência.
Function, Evaluate com Múltiplos Argumentos
Os geradores de ondas acima provaram ser extremamente úteis, especialmente com o Mapeamento de Imagem por Distorção. Mas descobriu-se que era necessário um controle muito mais fino das funções, exigindo mais de um parâmetro. Por causa disso, o operador "[-function](https://imagemagick.org/command-line-options/#function)" foi adicionado no IM v6.4.8-9. Basicamente, "[-function](https://imagemagick.org/command-line-options/#function)" é uma forma com múltiplos argumentos de "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)". No entanto, ao contrário do Operador Evaluate, esses operadores, assim como os operadores matemáticos, todas as funções acima operam apenas com valores de canal normalizados (faixa de 0.0 a 1.0) da imagem, o que na maioria dos casos os torna mais fáceis de usar.
Função Polinomial
O método 'polynomial ' aceita qualquer número de valores e modificará os valores de cor em uma imagem de acordo com a expressão exata fornecida, muito mais rápido do que o Operador FX consegue.
-function Polynomial a,b,c,...
Cada valor será usado como um coeficiente, da ordem mais alta para a mais baixa, para produzir um polinômio com o número de termos fornecido. Por exemplo, um argumento de '4,-4,1' gerará a expressão polinomial equivalente à expressão "[-fx](https://imagemagick.org/command-line-options/#fx)" " 4*u^2 - 4*u + 1 ". Se você conhece sua matemática do ensino médio, deve saber que essa função polinomial produz uma curva parabólica indo de 1.0 a 0.0 e de volta a 1.0, ao longo da faixa de cores de entrada ('u') de 0.0 a 1.0. Ou seja, ela tornará as cores preta e branca em 'branco' e os cinzas perfeitos em 'preto'. |
magick gradient.png -function Polynomial 4,-4,1 func_parabola.png
![[IM Output]](../static/img/transform/func_parabola_pf.gif)
Você pode até criar um gradiente muito mais complexo, por exemplo, um polinômio quártico, que foi o resultado da geração de um Ajuste de Nível por Curva, usando um conjunto de 'pontos de controle de nível'. Isso é tipicamente usado para ajustar as cores de uma imagem, dando a ela vários efeitos de sombreamento. |
magick gradient.png -function Polynomial '-25, 53, -36, 8.3, 0.2' \
func_quartic.png
![[IM Output]](../static/img/transform/func_quartic_pf.gif)
Claro que uma modificação linear simples também é possível, exatamente como você obtém se usasse um Operador Level... |
magick gradient.png -function Polynomial '4, -1.5' func_linear.png
![[IM Output]](../static/img/transform/func_linear_pf.gif)
Observe, no entanto, que você não pode usar 'Polynomial' para fazer uma operação completa de Limiar, devido à necessidade de coeficientes infinitos para isso, embora você possa chegar bem perto. Um único valor é naturalmente apenas uma constante, e resulta em uma atribuição direta desse valor. Em outras palavras, é exatamente como o método "[-evaluate](https://imagemagick.org/command-line-options/#evaluate) Set ", neste caso para um valor de cinza de 33%. |
magick gradient.png -function Polynomial 0.33 func_constant.png
![[IM Output]](../static/img/transform/func_constant_pf.gif)
Combinando um 'Polynomial' com outras funções matemáticas, você pode criar modificações de gradiente ainda mais complexas. Por exemplo, tirando a raiz quadrada de um polinômio, posso criar um verdadeiro arco circular sobre um gradiente linear. A expressão "[-fx](https://imagemagick.org/command-line-options/#fx)" equivalente 'sqrt( -4*u^2 + 4*u + 0 )'... |
magick gradient.png -function Polynomial -4,4,0 -evaluate Pow 0.5 \
func_circle_arc.png
![[IM Output]](../static/img/transform/func_circle_arc_pf.gif)
Veja também o Método Pow de Evaluate para uma alternativa ao acima.
Função Sinusoid
O método de função 'Sinusoid ' é uma versão muito mais avançada dos métodos 'sin' e 'cos' de "[-evaluate](https://imagemagick.org/command-line-options/#evaluate)", e de fato pode replicar essas funções, mas você tem controles muito melhores sobre como ela modifica os valores de cor em uma imagem.
-function Sinusoid frequency,phase,amplitude,bias
E é implementado usando a fórmula...
value = ampl * sin(2*PI( freq*value + phase/360 ) ) + bias
Isso pode parecer complexo, mas garante que a função seja fácil de usar. Apenas o primeiro valor, 'frequency', que funciona exatamente como acima, é obrigatório, sendo todos os outros parâmetros opcionais. Por padrão, ele gerará uma Curva Senoidal. |
magick gradient.png -function Sinusoid 1 func_sine.png
![[IM Output]](../static/img/transform/func_sine_pf.gif)
Adicionando um argumento 'phase ' em graus, você pode especificar o ângulo inicial da curva. Permitindo que você transforme a curva senoidal padrão em uma cossenoidal. |
magick gradient.png -function Sinusoid 1,90 func_cosine.png
![[IM Output]](../static/img/transform/func_cosine_pf.gif)
Ajustando a 'frequency' e a 'phase', posso transformar diretamente um gradiente linear em um gradiente sinusoidal suave que vai de preto a branco (do mínimo ao máximo ao longo de uma curva senoidal). Veja o Método Cosseno de Evaluate para um método menos direto. |
magick gradient.png -function Sinusoid 0.5,-90 func_sine_grad.png
![[IM Output]](../static/img/transform/func_sine_grad_pf.gif)
Os próximos dois valores opcionais, 'amplitude' e 'bias', controlam a escala e a linha central da curva sinusoidal. Por exemplo, aqui eu crio uma onda (curva cossenoidal negada) que oscila entre branco e cinza (valores variando de 0.75 ±0.25, ou 0.5 a 1.0), começando e terminando no branco. |
magick gradient.png -function Sinusoid 5,90,.25,.75 func_sine_bias.png
![[IM Output]](../static/img/transform/func_sine_bias_pf.gif)
Tenha cuidado com esses últimos parâmetros, pois eles podem facilmente fazer com que a forma de onda exceda os limites da faixa de valores de cor e, assim, seja cortada (a menos que você esteja usando uma versão HDRI do ImageMagick).
Função Arcsin
A função sinusoidal inversa 'Arcsin ' foi adicionada no IM v6.5.3-0. Esta é uma curva especial que era necessária para gerar um Mapa de Deslocamento Cilíndrico. Seus parâmetros são...
-function Arcsin width,center,range,bias
E é implementado usando a fórmula...
value = range/PI * asin(2/width*( value - center ) ) + bias
Por padrão, os valores (se não definidos) '1, 0.5, 1, 0.5' garantem que a função seja centralizada de modo a cobrir toda a faixa de cores de 0,0 a 1,1. |
magick gradient.png -function Arcsin 1 func_arcsin.png
![[IM Output]](../static/img/transform/func_arcsin_pf.gif)
Reduzindo pela metade a 'width ' da curva resultante, você obtém... |
magick gradient.png -function Arcsin 0.5 func_arcsin_width.png
![[IM Output]](../static/img/transform/func_arcsin_width_pf.gif)
O 'center ' permitirá que você reposicione a curva de acordo com os valores de cinza de entrada. |
magick gradient.png -function Arcsin 0.4,0.7 func_arcsin_center.png
![[IM Output]](../static/img/transform/func_arcsin_center_pf.gif)
O argumento 'range ' permite reduzir a faixa de saída dos valores de cor, e o 'bias ' ajustará o centro dessa faixa. |
magick gradient.png -function Arcsin 0.5,0.5,0.5,0.5 func_arcsin_range.png
![[IM Output]](../static/img/transform/func_arcsin_range_pf.gif)
Observe como os valores que são inválidos como resultado da função são tratados. Isso permite um melhor controle quando a função é usada em deslocamentos, e fornece maneiras de limpá-los. Os valores reais usados são '_bias_ ± _range_ /2', como seria de esperar. Observe que se a 'width ' ou o 'range ' forem tornados negativos, a inclinação da função será invertida, como resultado desse valor negativo. |
magick gradient.png -function Arcsin -1 func_arcsin_neg.png
Função Arctan
O método 'Arctan ' foi adicionado no IM v6.5.3-1. Seus parâmetros são...
-function Arctan slope,center,range,bias
E é implementado usando a fórmula...
value = range/PI * atan(slope*PI*( value - center ) ) + bias
Como você pode ver, é quase exatamente igual à função 'Arcsin', com apenas uma pequena mudança para torná-la mais útil. Ela até tem o mesmo conjunto de valores padrão (se não definidos) '1, 0.5, 1.0, 0.5'. Isso significa que se você especificar um valor de inclinação de '1.0', a inclinação da mudança no histograma produzirá uma mudança de 1:1 em torno do cinza puro (sem escalonamento), enquanto torna o branco e o preto em um valor mais acinzentado. Por exemplo |
magick gradient.png -function Arctan 1 func_arctan.png
![[IM Output]](../static/img/transform/func_arctan_pf.gif)
Ou seja, a parte central do gradiente na verdade permanece inalterada, com apenas as extremidades preta e branca perdendo contraste. À medida que a 'slope ' da curva se torna maior, o gradiente no centro se tornará mais forte (mais comprimido no meio), nessa proporção. |
magick gradient.png -function Arctan 10 func_arctan_10.png
![[IM Output]](../static/img/transform/func_arctan_10_pf.gif)
Isso, de muitas maneiras, é muito semelhante a um operador de modificação de cor de Contraste Sigmoidal. No entanto, uma função 'Arctan' NUNCA atingirá de fato os limites da faixa de saída de preto e branco puros. Ela se aproximará desses limites, mas nunca os cruzará. Da mesma forma que as funções anteriores (e o Contraste Sigmoidal), o segundo argumento ajustará a posição da curva em relação aos valores de gradiente de entrada. |
magick gradient.png -function Arctan 10,.7 func_arctan_center.png
![[IM Output]](../static/img/transform/func_arctan_center_pf.gif)
E os dois últimos argumentos, 'range ' permitirá que você ajuste a faixa de saída dos valores que serão gerados. Por exemplo, expandindo esse valor ligeiramente, você pode garantir que ele cubra completamente toda a faixa de valores possíveis. |
magick gradient.png -function Arctan 5,0.7,1.2 func_arctan_range.png
![[IM Output]](../static/img/transform/func_arctan_range_pf.gif)
No entanto, se você realmente quiser gerar uma curva para modificar todo o contraste de uma imagem dessa forma, é mais típico usar o Operador de Contraste Sigmoidal, que foi projetado para esse propósito. O uso mais típico de uma função de gradiente 'Arctan' é criar uma curva que se aproxime muito rapidamente de um valor específico, mas não o exceda. São esses valores limites que os argumentos 'range ' e 'bias ' controlam. Por exemplo, esta curva modificará o gradiente em uma imagem para produzir um limiar muito acentuado em torno do nível de cinza de entrada de 0.7, mas com os valores mudando entre os limites da faixa de 0.5 e 1.0 |
magick gradient.png -function Arctan 15,0.7,0.5,0.75 func_arctan_typ.png
![[IM Output]](../static/img/transform/func_arctan_typ_pf.gif)
Isso é algo que o Contraste Sigmoidal não consegue gerar.
Matemática sobre Imagens de Gradiente
Agora, as funções acima fornecem algumas transformações muito básicas para imagens de gradiente. Mas e se você quiser fazer alguma matemática com duas ou mais imagens de gradiente? Ou seja, modificar um gradiente usando o gradiente de outra imagem. Para isso, você precisa usar os Métodos Matemáticos de Composição especiais (como "[Plus](compose.html#plus)" e "[Divide](#divide)"). Antes de começarmos, porém, gostaria de dar-lhe uma palavra de aviso. Se suas imagens de gradiente forem imagens puramente em escala de cinza, sem canais alfa, então você pode usar os Métodos Matemáticos de Composição diretamente. No entanto, se você quiser limitar esses métodos a um canal específico, ou aplicá-los ao canal alfa (transparência), então você precisa garantir que definiu a configuração "[-channel](https://imagemagick.org/command-line-options/#channel)" apropriada, sem a flag de canal 'Sync' especial. Veja Matemática de Imagens usando Composição de Imagens para mais detalhes. Normalmente, usar os Métodos Matemáticos de Composição não é realmente tão difícil. As complicações surgem quando você tem gradientes que também contêm um 'bias'. Ou seja, o gradiente deve representar um valor de 'zero' em 50% de cinza, e cobrir uma faixa de -1 (preto) a +1 (branco). Tais imagens são frequentemente usadas para o Mapeamento de Imagem por Distorção. Assim, realizar matemática sobre 'gradientes com viés ' é o verdadeiro problema, e o que será examinado mais especificamente aqui.
Atenuar um Gradiente com Viés
Por exemplo, aqui eu quero criar uma onda senoidal, mas uma que comece pequena e depois fique maior em amplitude. Isso é conhecido como 'atenuar' um gradiente com viés. Ou, colocando de outra forma, multiplicar um gradiente com viés por outro gradiente absoluto. É também assim que a 'Modulação de Amplitude ', como no rádio AM, funciona! Então, primeiro precisamos de uma onda senoidal, que podemos simplesmente gerar a partir de um gradiente linear...
magick -size 5x300 gradient: -rotate 90 math_linear.png
magick math_linear.png -evaluate sine 12 math_sine.png
Agora, para atenuar isso, multiplicamos a onda senoidal por um gradiente linear, usando uma composição alfa Multiply...
magick math_sine.png math_linear.png \
-compose Multiply -composite math_sine_2.png
Mas para usar isso, digamos, em um Mapa de Deslocamento de Ondulações de Água, a onda deve permanecer centralizada em torno de um cinza perfeito. Para fazer isso, precisamos adicionar um viés à imagem original. Aconteceu de ser a mesma função que usamos para multiplicar a imagem original, negada e dividida por dois....
magick math_linear.png -negate -evaluate divide 2 math_bias.png
magick math_sine_2.png math_bias.png \
-compose Plus -composite math_attenuated.png
E assim temos um Gradiente de Onda Senoidal atenuado linearmente, adequado para uso em um mapa de deslocamento.
Claro que você pode fazer todo o processo em um único comando, e também não precisa ser uma simples atenuação linear. Por exemplo, aqui eu atenuo a onda senoidal de alta frequência usando uma onda cossenoidal negada, em vez de um gradiente linear.
magick math_linear.png -evaluate cos 1 -negate math_cosine_peak.png
magick math_sine.png math_cosine_peak.png \
\( -clone 0,1 -compose multiply -composite \) \
\( -clone 1 +level 50%,0 \
-clone 2 -compose plus -composite \) \
-delete 0--2 math_cosine_atten.png
A partir do IM v6.5.4-3, agora é possível fazer todos os passos acima em um único método de composição, usando o Método Matemático de Composição especial. Basicamente, reconhecendo que uma operação de atenuação é a fórmula Sc*Dc-.5*Sc+.5 ou os argumentos "1,-.5,0,.5". |
magick math_sine.png math_cosine_peak.png \
-compose Mathematics -set option:compose:args 1,-.5,0,.5 \
-composite math_attenuate.png
![[IM Output]](../static/img/transform/math_attenuate_pf.gif)
O mesmo resultado também pode ser alcançado primeiro ajustando o gradiente de atenuação usando uma Função Polinomial e depois usando um operador de composição Exclusion, para mesclar as imagens. |
magick math_sine.png \( math_cosine_peak.png -function polynomial -.5,.5 \) \
-compose Exclusion -composite math_poly_excl.png
Multiplicar Gradientes com Viés
Mas e se AMBAS as funções tiverem viés, de modo que um cinza perfeito signifique zero, e o preto e o branco representem a faixa de -1 a +1? Bem, isso é um pouco mais complexo, pois você não pode simplesmente multiplicá-los e esperar que o resultado saia correto, já que a multiplicação pode consistir em valores negativos. Isso requer algum cuidado para garantir que você não acabe cortando os valores e obtendo a negação correta da curva na imagem resultante. O truque é dividir a multiplicação em várias etapas. Ou seja, A × B também pode ser escrito como A × abs(B) × sign(B). Fazendo isso, você evita multiplicar por um valor negativo, que não pode ser armazenado em uma imagem de gradiente normal. Então, tudo o que precisamos fazer é pegar um dos gradientes com viés e separá-lo em duas partes para que possam ser aplicadas ao outro gradiente adequadamente. O 'sign()' de um gradiente com viés, ou obter uma máscara de quais partes são negativas, pode ser extraído usando um Limiar no gradiente no nível do viés. Você pode posteriormente negar seletivamente o outro gradiente usando uma Composição Difference, com essa imagem de limiar. O 'abs()' de um gradiente com viés pode ser extraído facilmente usando Solarize, depois negando e dobrando (usando Level) isso para obter o valor absoluto do gradiente variando de 0.0 a 1.0. Como também precisaremos do deslocamento de viés como parte da multiplicação (como em Atenuar acima), você pode usar diretamente a saída do solarize negada e escalada pela metade, antes de ela ser convertida no valor absoluto do gradiente. Então, vamos transformar um gradiente nesses três componentes.
magick math_cosine_peak.png -threshold 50% -negate math_m_sign.png
magick math_cosine_peak.png -solarize 50% math_m_bias.png
magick math_m_bias.png -level 50%,0 math_m_abs.png
|
| Sinal do Gradiente
branco = negativo
---|---|---
|
| Deslocamento de Viés
|
| Valor Absoluto
Agora que temos essas três partes de uma das imagens de gradiente, podemos mesclá-las com o outro gradiente. Para fazer isso, multiplicamos pelo valor absoluto, readicionamos o viés e depois negamos as partes que devem ser tornadas negativas.
magick math_sine.png math_m_abs.png \
-compose Multiply -composite math_m_1.png
magick math_m_1.png math_m_bias.png \
-compose Plus -composite math_m_2.png
magick math_m_2.png math_m_sign.png \
-compose Difference -composite math_multiply.png
E essa é uma multiplicação perfeita de duas imagens de gradiente com viés! Aqui está novamente, mas tudo em um único comando...
magick math_sine.png math_cosine_peak.png \
\( -clone 1 -threshold 50% -negate \) \
\( -clone 1 -solarize 50% \) \
\( -clone 3 -level 50%,0 \) \
\( -clone 0,4 -compose multiply -composite \
-clone 3 -compose plus -composite \
-clone 2 -compose difference -composite \) \
-delete 0--2 math_multiply_2.png
Uma nota final: ao contrário da Atenuação, esta Multiplicação de gradientes com viés é comutativa. Ou seja, trocar as imagens de entrada não afeta o resultado final. Como o acima é equivalente à fórmula 2*Sc*Dc-Sc-Dc+1, a partir do IM v6.5.4-3, você pode implementar os passos complexos acima como um único método de composição '[Mathematics](compose.html#mathematics)' usando o argumento "2,-1,-1,1". |
magick math_sine.png math_cosine_peak.png \
-compose Mathematics -set option:compose:args 2,-1,-1,1 \
-composite math_bias_multiply.png
![[IM Output]](../static/img/transform/math_bias_multiply_pf.gif)
Ou seja, um método muito mais fácil e rápido do que a dúzia ou mais de passos necessários sem este método de composição com argumentos. Acontece que, assim que vi aquela fórmula, percebi que ela é simplesmente a negação do método de composição '[Exclusion](compose.html#exclusion)'. Estranho, mas verdade. Assim, o seguinte também gerará a mesma multiplicação com viés zero. |
magick math_sine.png math_cosine_peak.png \
-compose exclusion -composite -negate math_excl_neg.png
Somar Gradientes com Viés
Com o advento do método de composição '[Mathematics](compose.html#mathematics)', somar gradientes com viés também é relativamente fácil. A fórmula FX equivalente é "u+v-0.5" ou um argumento de composição de "0,1,1,-.5". Por exemplo, o seguinte foi um Exemplo de Transformada de Fourier que eu havia gerado manualmente, exigindo a soma de 3 sinusoides com viés e um valor DC constante.
magick math_linear.png -function sinusoid 3.5,0,.25 wave_1.png
magick math_linear.png -function sinusoid 1.5,-90,.13 wave_2.png
magick math_linear.png -function sinusoid 0.6,-90,.07 wave_3.png
magick wave_1.png wave_2.png wave_3.png -background gray40 \
-compose Mathematics -set option:compose:args 0,1,1,-.5 \
-flatten added_waves.png
Observe no exemplo acima como usei o operador "[-flatten](https://imagemagick.org/command-line-options/#flatten)" com uma configuração "[-background](https://imagemagick.org/command-line-options/#background)" para implementar uma composição de múltiplas imagens. Ou, neste caso, uma 'Soma com Viés' de todas as imagens fornecidas mais a constante de fundo.
Modulação de Frequência
Aplicando uma função diretamente à saída de outra função, você NÃO produz um resultado simples. A razão é que todas essas funções matemáticas são aplicadas ao 'valor' do gradiente de pixels individuais, e não em relação ao valor x do pixel no gradiente. Por exemplo.... |
magick gradient.png -evaluate sin 0.5 -normalize \
-evaluate cos 8 math_cos_var.png
![[IM Output]](../static/img/transform/math_cos_var_pf.gif)
Isso gera uma função muito complexa que é essencialmente equivalente a
cos( 8 * sin( _{value}_ /2 ) )
Em outras palavras, uma frequência variável, onde a frequência varia com o gradiente da primeira curva senoidal. Basicamente, quanto mais rápido o gradiente muda na imagem original, menor a distância entre os picos. No entanto, a altura (amplitude) do pico não varia. É assim que a 'Modulação de Frequência ' realmente funciona, onde uma função aparentemente simples produz um resultado muito complexo.
Em Construção
Técnicas Diversas de Transformação de Imagem.
Estas ainda não foram exemplificadas, mas são algumas transformações básicas
desenvolvidas no IM que podem ser úteis. Se você tiver um efeito interessante, contribua.
pixelizar uma imagem
redimensione uma imagem reduzindo em 10 e depois escale a imagem em 10 para produzir blocos
de cor aproximadamente média.
Por exemplo...
magick input.jpg -resize 10% -sample 1000% output.jpg
Corrigir a inclinação de imagens levemente rotacionadas
-deskew {threshold}
endireita uma imagem. Um limiar de 40% funciona para a maioria das imagens.
Use -set option:deskew:auto-crop {width} para recortar automaticamente a imagem. O argumento
set é a largura em pixels do fundo da imagem (por exemplo, 40).
Programaticamente, recortamos automaticamente executando um filtro de mediana pela imagem
para eliminar o ruído sal e pimenta. Em seguida, obtemos os limites da imagem do
filtro de mediana com um fator de fuzz (por exemplo, -fuzz 5%). Finalmente, nós
recortamos a imagem original pelos limites. O código se parece com isto:
median_image=MedianFilterImage(image,0.0,exception);
geometry=GetImageBoundingBox(median_image,exception);
median_image-DestoryImage(median_image);
print(" Auto-crop geometry: %lux%lu%+ld%+ld",
geometry.width,geometry.height, geometry.x,geometry.y);
crop_image=CropImage(rotate_image,&geometry,exception);
Veja [Aparando Imagens 'Ruidosas'](crop.html#trim_blur)
Segmentação
veja os scripts
[divide_vert](../static/img/scripts/divide_vert)
[segment_image](../static/img/scripts/segment_image)
para alguns scripts simples que escrevi para segmentar imagens bem definidas em
partes menores. Espero conseguir colocar funções simples de segmentação como estas
na biblioteca principal, para permitir coisas como a subdivisão automática de
animações GIF, e a separação de imagens e diagramas de documentos digitalizados.
![[IM Output]](../static/img/transform/inside_border2.jpg)
![[IM Output]](../static/img/transform/spread_rose.png)
![[IM Output]](../static/img/images/rose.gif)
![[IM Output]](../static/img/transform/rose_paint_1.gif)
![[IM Output]](../static/img/transform/rose_paint_3.gif)
![[IM Output]](../static/img/transform/rose_paint_5.gif)
![[IM Output]](../static/img/transform/rose_paint_10.gif)
![[IM Output]](../static/img/transform/rose_blur_paint_10.gif)
![[IM Output]](../static/img/transform/rose_charcoal_1.gif)
![[IM Output]](../static/img/transform/rose_charcoal_3.gif)
![[IM Output]](../static/img/transform/rose_charcoal_5.gif)
![[IM Output]](../static/img/transform/rose_emboss_0x05.gif)
![[IM Output]](../static/img/transform/rose_emboss_0x09.gif)
![[IM Output]](../static/img/transform/rose_emboss_0x10.gif)
![[IM Output]](../static/img/transform/rose_emboss_0x11.gif)
![[IM Output]](../static/img/transform/rose_emboss_0x12.gif)
![[IM Output]](../static/img/transform/rose_emboss_0x20.gif)
![[IM Output]](../static/img/images/rose_grey.gif)
![[IM Output]](../static/img/transform/rose_g_emboss_0x05.gif)
![[IM Output]](../static/img/transform/rose_g_emboss_0x09.gif)
![[IM Output]](../static/img/transform/rose_g_emboss_0x10.gif)
![[IM Output]](../static/img/transform/rose_g_emboss_0x11.gif)
![[IM Output]](../static/img/transform/rose_g_emboss_0x12.gif)
![[IM Output]](../static/img/transform/rose_g_emboss_0x20.gif)
![[IM Output]](../static/img/transform/message.gif)
![[IM Text]](../static/img/transform/message_size.txt.gif)
![[IM Output]](../static/img/transform/rose_difference.png)
![[IM Text]](../static/img/transform/rose_diff_pae.txt.gif)
![[IM Output]](../static/img/transform/message_hidden.png)
![[IM Output]](../static/img/transform/message_obfuscate.png)
![[IM Output]](../static/img/transform/message_restored_2.png)
![[IM Output]](../static/img/transform/message_signed.png)
![[IM Output]](../static/img/transform/message_restored_3.png)
![[IM Output]](../static/img/transform/message_binary.png)
![[IM Output]](../static/img/transform/message_restored_4.png)
![[IM Output]](../static/img/transform/grid_input.png)
![[IM Output]](../static/img/transform/grid_scale.png)
![[IM Output]](../static/img/transform/grid_tile.png)
![[IM Output]](../static/img/transform/mask.gif)
![[IM Output]](../static/img/transform/mask_edge_1.gif)
![[IM Output]](../static/img/transform/mask_edge_2.gif)
![[IM Output]](../static/img/transform/mask_edge_3.gif)
![[IM Output]](../static/img/transform/mask_edge_10.gif)
![[IM Output]](../static/img/images/piglet.gif)
![[IM Output]](../static/img/transform/piglet_edge.gif)
![[IM Output]](../static/img/transform/rose_edge.gif)
![[IM Output]](../static/img/transform/rose_edge_grey.gif)
![[IM Output]](../static/img/transform/mask_canny.gif)
![[IM Output]](../static/img/transform/piglet_canny.gif)
![[IM Output]](../static/img/transform/piglet_canny_neg.gif)
![[IM Output]](../static/img/transform/rose_canny.gif)
![[IM Output]](../static/img/transform/heart_svg.gif)
![[IM Text]](../static/img/transform/heart_2.svg.gif)
![[IM Output]](../static/img/images/shape_rectangle.gif)
![[IM Output]](../static/img/transform/rectangle.gif)
![[IM Text]](../static/img/transform/rectangle_lines.mvg.gif)
![[IM Output]](../static/img/transform/shade_anthony.jpg)
![[IM Text]](../static/img/transform/shade_elevation_45.txt.gif)
![[IM Output]](../static/img/transform/shade_beveled.png)
![[IM Output]](../static/img/transform/shade_elevation_90.gif)
![[IM Output]](../static/img/transform/shade_beveled_edge.png)
![[IM Output]](../static/img/transform/shade_elevation_0.gif)
![[IM Output]](../static/img/transform/shade_elevation_15.gif)
![[IM Output]](../static/img/transform/shade_elevation_30.gif)
![[IM Output]](../static/img/transform/shade_elevation_45.gif)
![[IM Output]](../static/img/transform/shade_elevation_60.gif)
![[IM Output]](../static/img/transform/shade_elevation_75.gif)
![[IM Output]](../static/img/transform/shade_beveled_X.png)
![[IM Output]](../static/img/transform/shade_blur_3n.gif)
![[IM Output]](../static/img/transform/shade_blur_3n_mask.png)
![[IM Image]](../static/img/transform/shade_30.png)
![[IM Text]](../static/img/transform/shade_30.txt.gif)
![[IM Image]](../static/img/transform/shade_30_norm.png)
![[IM Text]](../static/img/transform/shade_30_norm.txt.gif)
![[IM Image]](../static/img/transform/shade_21_norm.png)
![[IM Text]](../static/img/transform/shade_21_norm.txt.gif)
![[IM Output]](../static/img/transform/shade_sig-10.png)
![[IM Output]](../static/img/transform/shade_sig-5.png)
![[IM Output]](../static/img/transform/shade_sig-2.png)
![[IM Output]](../static/img/transform/shade_sig_0.png)
![[IM Output]](../static/img/transform/shade_sig+2.png)
![[IM Output]](../static/img/transform/shade_sig+5.png)
![[IM Output]](../static/img/transform/shade_sig+10.png)
![[IM Output]](../static/img/transform/shade_overlay.png)
![[IM Output]](../static/img/transform/fx_blue.gif)
![[IM Output]](../static/img/transform/fx_combine.gif)
![[IM Output]](../static/img/transform/grey_253.png)
![[IM Output]](../static/img/transform/gradient.png)
![[IM Output]](../static/img/transform/eval_pow_parabola.png)
![[IM Output]](../static/img/transform/eval_pow_sq_root.png)
![[IM Output]](../static/img/transform/gradient_pf.gif)
![[IM Output]](../static/img/transform/eval_pow_parabola_pf.gif)
![[IM Output]](../static/img/transform/eval_pow_sq_root_pf.gif)
![[IM Output]](../static/img/transform/eval_sin_1.png)
![[IM Output]](../static/img/transform/eval_cos_1.png)
![[IM Output]](../static/img/transform/eval_sin_1_pf.gif)
![[IM Output]](../static/img/transform/eval_cos_1_pf.gif)
![[IM Output]](../static/img/transform/func_arcsin_neg.png)
![[IM Output]](../static/img/transform/func_arcsin_neg_pf.gif)
![[IM Output]](../static/img/transform/math_linear_pf.gif)
![[IM Output]](../static/img/transform/math_sine_pf.gif)
![[IM Output]](../static/img/transform/math_sine_2_pf.gif)
![[IM Output]](../static/img/transform/math_bias_pf.gif)
![[IM Output]](../static/img/transform/math_attenuated_pf.gif)
![[IM Output]](../static/img/transform/math_cosine_atten_pf.gif)
![[IM Output]](../static/img/transform/math_poly_excl_pf.gif)
![[IM Output]](../static/img/transform/math_m_1_pf.gif)
![[IM Output]](../static/img/transform/math_m_2_pf.gif)
![[IM Output]](../static/img/transform/math_multiply_pf.gif)
![[IM Output]](../static/img/transform/math_multiply_2_pf.gif)
![[IM Output]](../static/img/transform/math_excl_neg_pf.gif)
![[IM Output]](../static/img/transform/wave_1_pf.gif)
![[IM Output]](../static/img/transform/wave_2_pf.gif)
![[IM Output]](../static/img/transform/wave_3_pf.gif)
![[IM Output]](../static/img/transform/added_waves_pf.gif)