Pag: 1/47 Sumário Agradecimentos......................................................................................................... 3 Quem é o ImageMagick?............................................................................................ 4 Sobre este trabalho.................................................................................................... 4 Os utilitários............................................................................................................... 5 Convert................................................................................................................... 6 Convertendo formato e redimensionando..........................................................6 Usando texto...................................................................................................... 9 Emoldurando.................................................................................................... 19 Efeitos especiais............................................................................................... 23 Moldura oval esfumaçada (Vinheta).............................................................23 Distorsões.................................................................................................... 25 Implosão....................................................................................................... 26 Borrando imagens............................................................................................ 27 Blur de movimento....................................................................................... 31 Blur radial..................................................................................................... 32 Sombreando (blur)........................................................................................... 33 Sombreando (shadow)...................................................................................... 34 Carvão.............................................................................................................. 34 Bico de pena..................................................................................................... 34 Pintura a óleo................................................................................................... 35 Pulverização..................................................................................................... 36 Enfatizando cores............................................................................................. 36 Negativo........................................................................................................... 36 Solarização....................................................................................................... 37 Metalizando imagens........................................................................................ 38 3D em imagens................................................................................................ 38 Identify..................................................................................................................... 39 Mogrify................................................................................................................. 42 Composite............................................................................................................ 43 Montage............................................................................................................... 45 Sintaxe dos utilitários........................................................................................... 49 Arquivo de entrada........................................................................................... 49 Usando metacaracteres de expansão de arquivos.......................................49 Um nome explicito de formato de imagem..................................................49 Usando imagens e padrões intrínsecos (built-ins)........................................50 Lendo uma imagem da entrada padrão.......................................................50 Pag: 2/47 Índice alfabético clear............................................................................................................................. 18 dst................................................................................................................................ 19 dst-in............................................................................................................................ 19 dst-out.......................................................................................................................... 19 dst-over........................................................................................................................ 19 label:............................................................................................... 11, 12, 13, 14, 15, 22 letra vazada.................................................................................................................. 13 matte channel.............................................................................................................. 18 rgb.............................................................................................................. 18, 29, 30, 32 src..................................................................................................................... 18, 19, 35 src-in............................................................................................................................. 19 src-out.......................................................................................................................... 19 src-over........................................................................................................................ 19 xc:........................................................................................................................... 16, 22 -annotate................................................................................................................ 16, 31 -background.......................................................................11, 12, 13, 15, 22, 24, 25, 30 -border............................................................................................ 17, 18, 24, 25, 30, 31 -bordercolor................................................................................................ 18, 24, 25, 30 -chop...................................................................................................................... 17, 31 -compose.......................................................................................................... 18, 22, 31 -fill................................................................................ 11, 12, 13, 15, 22, 24, 25, 30, 34 -font.................................................................................... 11, 12, 13, 15, 22, 24, 30, 34 -frame.....................................................................13, 14, 15, 16, 17, 18, 23, 24, 25, 31 -gravity................................................................................................ 12, 13, 15, 22, 30 -interword-spacing........................................................................................................ 14 -kerning........................................................................................................................ 14 -list............................................................................................................... 5, 10, 11, 21 -mattecolor..................................................................................... 16, 17, 18, 24, 25, 30 -pointsize......................................................................11, 12, 13, 14, 15, 22, 24, 30, 34 -resize............................................................................................... 6, 7, 8, 9, 10, 29, 31 -shave..................................................................................................................... 17, 31 -size...................................................................................................... 12, 13, 22, 29, 30 -strokewidth...................................................................................................... 13, 15, 30 -undercolor............................................................................................................. 13, 30 Agradecimentos Pelas belas paisagens que mostro neste trabalho, agradeço à minha Cidade Maravilhosa e ao Rio de Janeiro, meu Estado Maravilhoso, que continuam lindos apesar dos políticos, da difamação da mídia e do esvaziamento financeiro que vêm sofrendo. Pag: 3/47 Quem é o ImageMagick? Segundo definição do seu site oficial (http://www.imagemagick.org), ImageMagick® é uma suíte de softwares para compor, criar e editar imagens bit map. Ele pode ler, converter e escrever imagens em uma imensa gama de formatos (mais de 100. Para listar todos, faça: identify list format | more) incluindo DPX, EXR, GIF, JPEG, JPEG-2000, PDF, PhotoCD, PNG, Postscript, SVG, and TIFF. Use ImageMagick® para traduzir, virar, espelhar, girar, alterar escala, fazer corte e transformação de imagens, ajustar cores de imagens, aplicar diversos efeitos especiais, ou desenhar textos, linhas, polígonos, elipses e curvas Bézier. ImageMagick® é um Software Livre distribuído com uma licença compatível com a GPL que roda em praticamente todos os sistemas operacionais e tem biblioteca para inúmeras linguagens. ImageMagick é formado por uma série de utilitários de linha de comando para manipular imagens. Quem usa muito imagens, seja em fotos, em edições de texto ou de outra forma, provavelmente está acostumado a editar as imagens uma a uma usando interface gráfica (GUI) através de programas como gimp ou photoshop. No entanto, uma GUI nem sempre é conveniente. Suponha que você deseja processar uma imagem dinamicamente a partir de um script da web, ou pretende aplicar as mesmas operações para muitas imagens, ou ainda repetir uma operação específica em horários diferentes para a mesma ou para outra imagem. Para estes tipos de operações, um utilitário de processamento de imagens orientado a linha de comando é mais adequado. Bem, cá entre nós, esta foi a definição clássica. A minha definição é um pouco mais suscinta: "ImageMagick é uma coletânea de utilitários para edição de imagens que faz tudo que você precisa fazer com uma imagem e muito mais". Segundo seu site oficial, o ImageMagick não tem intenção de ser o mais veloz, sua única preocupação é quanto a qualidade final do trabalho. Talvez por isso, não foi nenhuma surpresa para mim quando me deparei com 3 benchmarks (muito bem feitos, por sinal) envolvendo o ImageMagick, o gimp e o photoshop. Dos 3, o que menos precisava de hardware e tinha a melhor qualidade nas imagens geradas era o ImageMagick. Também, como já era de se esperar, o photoshop ficou com a última colocação nesses quesitos. Sobre este trabalho Estava escrevendo uma matéria sobre o zenity, quando me deparei com um problema: sua opção notification gera um ícone no gnome-panel algo assim como a figura ao lado. Ora o zenity cria janelas para trocar dados com os usuários e eu copiava essas janelas usando a opção do gnome "Gráficos" > "Capturar Imagem da Tela" (que provavelmente faz esta captura usando o ImageMagick), mas agora o negócio era diferente, eu não queria copiar uma janela inteira, mas sim uma parte do painel superior do gnome. Foi então que o meu grande e querido amigo Franklin Carvalho, pioneiro no uso de Linux, me disse: – Julio, dê um CTRL+F2 e escreva import gnomepanel.png. Assim que você mandar executar, o cursor do mouse se transformará em uma cruz e basta arrastálo sobre a parte da tela que você deseja copiar. Quando soltar o botão, será gerado no seu diretório home um arquivo chamado gnomepanel.png contendo a parte da tela que você marcou para copiar. Pag: 4/47 Fiquei tão empolgado que dei um man import para ver o que era aquela ferramenta e fiquei abestalhado com o monte de opções que tinha. Descobri também que era parte integrante do conjunto de utilitários que formam a suíte ImageMagick. Dei então uma olhada no man ImageMagick e após uma rápida passada de olhos, resolvi que o dia que tivesse tempo escreveria algo a respeito dessa suíte. Eis que nos feriados do Natal de 2008, tive esse tempo e arregacei as mangas. No início, pensei em basear-me nas man pages para fazer seu esqueleto e índice, mas devido à enorme quantidades de opções, a especificidade do tema e a terminologia técnica de imagens à qual nós, profissionais de TIC não estamos habituados, desisti e resolvi colocar aqui somente o que costumo usar nos meus trabalhos com imagens e fotos, tentando abordar a maior parte das opções possíveis. Por isso esta coletânea de dicas está longe de ser uma obra completa ou uma tradução, porém creio que será bastante útil para os usuários Unix/Linux. Mas, inexplicavelmente, alguns profissionais de TIC tem pavor do Unix/Linux e outros que atuam nesta área, fogem do Shell como o diabo foge da cruz. A essas pessoas, tenho somente uma coisa a dizer: "sinto muito, mas este trabalho abordará somente o ImageMagick sob Linux, e interpretador de comandos usado será o Shell (bash), por se tratar do ambiente para o qual ele foi criado, e pela portabilidade para qualquer sistema operacional Unix/Linux/Mac OS X". Pag: 5/47 Convert Converte formatos de imagem, redimensiona-as, tira o foco,corta, junta, e muito mais (muito mais mesmo!); Convertendo formato e redimensionando Vamos ver um exemplo para mudar o formato da imagem e ao mesmo tempo alterar o seu tamanho. $ convert Corcovado.jpeg resize 50% Corcovado.png Corcovado.png Corcovado.jpeg Mas também é possível dizer exatamente as dimensões que você deseja na imagem final. Veja: $ convert resize 84x110 PaoDeAcucar.jpg PaoDeAcucar.png PaoDeAcucar.png PaoDeAcucar.jpg Como você viu redimensionamos o Pão de Açúcar (para a viagem no bondinho ser mais rápida ;) e ao mesmo tempo mudamos o seu formato de .jpg para .png. Você já deve ter visto um recurso muito usado na imprensa para esconder o rosto de determinados indivíduos, "pixelando-o". Isso se faz reduzindo drasticamente o tamanho da imagem (ou de pedaço(s) dela e posteriormente ampliando-a de volta a seu tamanho anterior. Veja: Pag: 6/47 $ convert Bush.jpeg resize 10% resize 119x140 BushPxl.jpg Bush.jpeg BushPxl.jpg Acabamos de ter contato com a primeira flag usada pelo ImageMagick, o sinal de percentagem (%), mas ele usa muitas outras. Digamos que você deseja informar o tamanho final da sua imagem pela quantidade total de pixels por algum motivo, para isso basta usar a flag arroba (@). Vejamos como: $ convert resize 8052@ Corcovado.jpeg Corcovadox2Tercos.png Corcovadox2Tercos.png Corcovado.jpeg O Corcovado tinha inicialmente 99x122, o que multiplicando, dá um total de 12.078 pixels. Fizemos então 12.078 * 2 / 3 para reduzir a imagem para dois terços do seu tamanho original, produzindo 8052. A imagem gerada após a execução do comando, tinha 80x99, ou seja, 7920 pixels. A diferença entre o pretendido e o obtido é porque este foi o maior tamanho que mantinha a proporção largura x altura da imagem inicial. Mas a opção resize que usamos, tem seus macetes, o uso das 3 flags a seguir, mudam seu comportamento, veja: ● Usando o sinal maior que (>), após resize, só poderemos diminuir seu tamanho, se esta opção for causar um aumento de tamanho, ele será ignorado; ● Ao contrário, usando o menor que (<), o resize só fará efeito se a imagem aumentar o tamanho; ● Usando um ponto de espantação (!) (ou será ponto de exclamação? ;) o rezise ignora a proporção prévia da figura e a redimensiona para o tamanho imposto pela instrução. Nos exemplos a seguir, usaremos a imagem do Pão de Açúcar que no exemplo anterior fora redimensionado para 84x110. Veja: Pag: 7/47 $ convert resize 125x167\> PaoDeAcucar.png PaoDeAcucar1.png $ convert resize 54x72\> PaoDeAcucar.png PaoDeAcucar2.png PaoDeAcucar2.png PaoDeAcucar.png PaoDeAcucar1.png Na primeira tentativa, nada ocorreu porque usamos o sinal de maior que (>) e tentamos redimensioná-lo para um tamanho maior. Na segunda tentativa, fomos bem sucedidos, porque o encolhemos. É importante notar que se não "escaparmos" o maior que com uma contrabarra (\>) o Shell irá interpretá-lo como um redirecionamento da saída primária (stdin) e isso causará problemas, com certeza. Agora vejamos exemplos em que do uso da flag menor que (<), ainda usando as imagens do Pão de Açúcar: $ convert resize 54x72\< PaoDeAcucar.png PaoDeAcucar1.png $ convert resize 123x165\< PaoDeAcucar.png PaoDeAcucar2.png PaoDeAcucar.png PaoDeAcucar1.png PaoDeAcucar2.png Contrariamente ao exemplo anterior, na primeira tentativa, nada ocorreu porque usamos a flag menor que (<) e tentamos redimensioná-lo para um tamanho menor. Na segunda tentativa fomos bem sucedidos, porque o aumentamos. Vamos entender o uso da flag ponto de exclamação (!): $ convert PaoDeAcucar.png resize 110x84 SaiuPelaCulatra.png $ convert PaoDeAcucar.png resize 110x84\! PaoDeAcucarGordo.png Pag: 8/47 SaiuPelaCulatra.png PaoDeAcucarGordo.png PaoDeAcucar.png A imagem original do Pão de Açúcar era 84x110 na primeira tentativa, não coloquei o ponto de exclamação (!) e veja só o que aconteceu: para não distorcer a imagem o convert gerou uma imagem 63x84, isto é, casou a largura que havia sido pedida e harmonizou a altura. Na segunda tentativa, as novas dimensões foram aceitas , o que agora nos obriga mandar o Pão de Açúcar para um spa. Usando texto A equipe do ImageMagick é, sem trocadilho, textual em dizer que a sua função é trabalhar com imagens e não com textos. Para isso procure algo melhor, como o Tex (sic). O que acontece é que os caras são muito tímidos. É verdade que ele não tem todos os recursos do Tex, mas tem muito mais recurso que qualquer outro editor de textos que conheço. Vejam se não tenho razão (e aqui não tem tudo que ele pode fazer). Antes de começar este item é bom você conhecer a opção list que serve basicamente para listar os argumentos de diversas opções. E aí você me pergunta: " e o que uma opção dessas te a ver com texto?" A opção propriamente dita, nada, porém temos de usá-la para conhecer as fontes que dispomos e as cores que poder ser usadas. Mas não só estas que esta opção nos apresenta. Para começar, vamos ver tudo que ela lista: $ convert list list Viu? É coisa pra chuchu! Agora preste atenção nas opções que ele te gerou, porque mais cedo ou mais tarde você irá precisar consultá-las. Por enquanto vejamos somente as cores e as fontes. $ convert list color | more $ convert list font | more Pronto agora já temos as ferramentas iniciais e como você viu é uma penca de cores e fontes diferentes. Algumas fontes que serão usadas, neste trabalho, não costumam fazer parte do mapa básico de fontes após uma instalação Linux. Porém instalar fontes neste Sistema Operacional é muito mais fácil que você pode imaginar. Se você der uma “googlada”, achará inúmeros sites especializados em download de fontes. Pag: 9/47 Dica: Para instalar fontes no Debian/Ubuntu basta você criar um diretório sob /usr/share/fonts, digamos /usr/share/fonts/novas, fazer download das fontes que você deseja para aquele diretório e em seguida executar o defoma (DEbian FOnt MAnager) da seguinte forma: $ sudo defomafont v registerall /usr/share/fonts/novas/* Vamos começar por uma coisa bem simples: $ convert background darkred fill cyan \ font PurisaMedium pointsize 60 label:Juliana Ju1.gif Ju1.gif Opções usadas no exemplo Opção Significado background Define a cor de fundo fill Define a cor de preenchimento do texto. Para preencher de azul, por exemplo, podemos usar qualquer das notações: fill blue fill "#0000FF" fill "rgb(0,0,256)" font Define o tipo de fonte a ser usado pointsize Define o tamanho da fonte label Define o que será escrito Dica: Tendo um espaço limitado para inserir o texto, prefira usar a opção size <alt>x<larg>, pois assim procedendo, não será necessário especificar pointsize, pois será gerado o texto que melhor se enquadrar no espaço disponível. Vamos ver se é isso mesmo: Pag: 10/47 $ convert background darkred fill cyan font PurisaMedium \ size 165x90 label:Juliana Ju2.gif Ju2.gif Mas se você reparar, horizontalmente o texto não ficou no centro. Vejamos duas formas de contornar este problema: A primeira é mais genérica e nela usaremos a opção gravity que se distribui conforme o gráfico abaixo: northwest north west center southwest south northeast east southeast Valores possíveis da opção gravity e seus alinhamentos Se não for informado qual o tipo de gravidade, o padrão (defaulf) é northwest. Então, usando gravity center poderíamos fazer assim: $ convert background darkred fill cyan font PurisaMedium \ size 165x90 gravity center label:Juliana Ju3.gif Ju3.gif E na segunda forma citada, deixaríamos o ImageMagick calcular a altura otimizada, voltando a usar a opção size, porém sem especificar a altura. $ convert background darkred fill cyan font PurisaMedium \ size 165x label:Juliana Ju4.gif Pag: 11/47 Ju4.gif Vamos simular uma letra vazada: $ convert background white fill darkred font CandiceRegular \ strokewidth 2 stroke cyan undercolor darkred size 165x70 \ gravity center frame 5x5+2+2 label:Paula Paula1.gif Paula1.gif Opções usadas no exemplo Opção Significado stroke Define a cor da borda das letras strokewidth Define a largura das bordas das letras undercolor Define a cor que fica por baixo das letras frame Circunda a imagem com uma moldura Neste exemplo, simulamos letra vazada, definindo a mesma cor da letra (fill) e a de fundo (undercolor) e contornando as letras (stroke) com uma cor diferente. A opção frame foi usada para mostrar os limites da imagem. Sua sintaxe é <espessura da haste vertical>x<espessura da haste horizontal>+<alto relevo>+<baixo horizontal>. Tá legal, tá legal! Eu sei que os parâmetros de frame não estão bem explicados, mas porém darei outros exemplos para você entender melhor. Mas já fique você sabendo que a soma dos relevos tem de ser menor ou igual à menor das espessuras das hastes. Ahh, você é curioso ou impaciente e não pode esperar a explicação completa? Então varie estes números e analise os resultados. Acho esta a melhor forma de aprender. Dica: Para ocupar horizontalmente um espaço definido, a partir da versão 6.4.7-8 do ImageMagick você tem mais dois recursos: 1. Usar a opção kerning n para aumentar o intervalo entre as letras; 2. Usar a opção interwordspacing n para aumentar o intervalo entre as palavras. n, em ambos os casos é um inteiro, positivo ou negativo. Pag: 12/47 Podemos também escrever um texto lendo um arquivo como entrada. Veja isso: $ convert pointsize 15 label:@QuebraLingua.txt \ frame 12x12+6+6 DeArquivo.gif DeArquivo.gif Duas observações a fazer: 1. Quando estamos usando um arquivo como entrada seu nome deve ser precedido por um arroba (@); 2. Sobrou uma linha em branco no final, referente ao new-line (ASCII 10) na última linha do arquivo. Se não quiser que isso aconteça temos de removê-lo antes da execução do comando. Usei estes parâmetros de frame para você ir analisando o comportamento desta opção e para reparar que desta forma fica parecido com um super botão. Podemos também ler os dados da entrada primária. Vamos a um exemplo para escrever na vertical, mas primeiramente vamos ver como preparar o texto para ser passado para o convert. $ echo n Paula | sed r 's/(.)/\1\n/g'; echo fim P a u l a fim $ echo n Paula | sed r 's/(.)/\1\n/g;s/\n$//'; echo fim P a u l afim Epa, isso não é ImageMagick, é Shell, mas não resisto à tentação... Vejamos a primeira linha: o comando echo com a opção n não salta linha após sua execução. Num sed, os parênteses armazenam o valor que está em seu interior. O ponto (.) representa qualquer caractere, mas somente um, e o \1 devolve o valor que foi guardado pelos parênteses. Assim sendo o sed está pegando cada um dos caracteres do literal Paula e está o jogando para a saída seguido de um new-line (ASCII 10). Parece tudo OK mas repare que o new-line adicionado após a última letra, fez o literal fim passar para a linha seguinte. E foi para removê-lo demos uma esticada no sed, conforme pode ser visto na segunda linha de comandos. Então vamos ao ImageMagick, que é o que interessa. Pag: 13/47 $ echo n Paula | sed r 's/(.)/\1\n/g;s/\n$//' | \ convert background darkred fill darkred \ font CandiceRegular strokewidth 2 stroke cyan \ pointsize 40 gravity center \ frame 10x10+0+10 label:@ Paula2.gif Paula2.gif O mais importante deste exemplo é que, assim como diversos comandos (inclusive builtins como o set, p. ex.) o convert usa um hífen () para receber o que vem da entrada primária (stdin), tratando-o como o arquivo de entrada. Agora a opção frame mostra um baixo relevo. A partir da versão 6 do ImageMagick, existe a opção annotate, que faz isso tudo que foi descrito e mais algumas coisas, sendo portanto a mais indicada para se trabalhar com texto. Vamos vê-la em sua aplicação básica, isto é, vamos definir uma caixa e nela vamos inserir um texto numa determinada posição. $ convert size 260x100 xc:wheat3 \ font CactusSandwichFMRegular \ pointsize 65 stroke green \ annotate +40+60 'Cactus' Cactus1.gif Cactus1.gif Veja que neste exemplo montei uma caixa de 260x100 e pintei o fundo (xc:) da cor do trigo (wheat em inglês). o –annotate recebeu o texto (Cactus) e o mandou para a saída deslocando-o 40 pixels para a direita e 60 para baixo. Quanto ao mais vocês já sabem. Usei uma fonte engraçada e pouco convencional, porque lá no início deste Pag: 14/47 trabalho, ensino como instalá-las. Mas uma coisa muito legal do annotate é o fato de permitir rotação em torno do eixo horizontal (X) e vertical (Y) do texto. Sua sintaxe é: annotate <graus no eixo X>x<graus no eixo Y> ±<desloc X> ±<desloc Y> Veja esta linha de comandos. $ convert font BitstreamVeraSansRoman pointsize 22 \ gravity center size 40x40 xc:white \ annotate XxY "Tux" XxY.gif Para exemplificar, porque fica muito mais fácil de entender, vamos dar umas rodadinhas nela, variando X e Y, de forma a montar a tabela a seguir: 0x0.gif 0x45.gif 0x90.gif 0x135.gif 0x180.gif 0x225.gif 0x270.gif 0x315.gif 45x0.gif 45x45.gif 45x90.gif 45x135.gif 45x180.gif 45x225.gif 45x270.gif 45x315.gif 90x0.gif 90x45.gif 90x90.gif 90x135.gif 90x180.gif 90x225.gif 90x270.gif 90x315.gif 135x0.gif 135x45.gif 135x90.gif 135x135.gif135x180.gif135x225.gif135x270.gif135x315.gif 180x0.gif 180x45.gif 180x90.gif 180x135.gif180x180.gif180x225.gif180x270.gif180x315.gif 225x0.gif 225x45.gif 225x90.gif 225x135.gif225x180.gif225x225.gif225x270.gif225x315.gif 270x0.gif 270x45.gif 270x90.gif 270x135.gif270x180.gif270x225.gif270x270.gif270x315.gif 315x0.gif 315x45.gif 315x90.gif 315x135.gif315x180.gif315x225.gif315x270.gif315x315.gif Desta forma, para fontes que não possuem itálico, podemos simulá-lo. Veja: $ convert font CactusSandwichFMRegular \ pointsize 80 stroke green size 260x80 \ xc:wheat4 annotate 0x45+0+50 'Cactus' Cactus2.gif Pag: 15/47 Cactus2.gif Nos dois exemplos a seguir, colocarei legenda no rodapé das fotos. Na primeira terá um literal, que é a descrição da foto e a segunda, terá alguns dados técnicos da foto. $ convert ArraialDoCabo7.png fill white font ArialNegrito \ pointsize 10 gravity south annotate 0 \ 'Arraial Por do Sol no Mar' ArraialDoCabo8.png $ convert ArraialDoCabo7.png fill white font ArialNegrito \ pointsize 10 gravity south annotate 0 \ 'Arquivo: %f %wx%h Pixels' ArraialDoCabo9.png ArraialDoCabo8.png ArraialDoCabo9.png Estas duas fotos foram posicionadas uma-a-uma na mão, mas eu poderia ter pedido ao ImageMagick para fazer isso para mim da seguinte forma: $ convert ArraialDoCabo8.png ArraialDoCabo9.png \ +append ArraialDoCabo10.png ArraialDoCabo10.png Nos exemplos anteriores, além do +append para juntar as imagens como vimos no último e que esmiuçaremos mais tarde, devemos ressaltar duas coisas nos primeiros: 1. A opção annotate requer dois argumentos, assim sendo, caso não seja necessário informar os dados de posicionamento e angulação, devemos informar zero, que equivaleria a zero grau em X, zero graus em Y, deslocamento Pag: 16/47 zero em X e deslocamento zero em Y; 2. Os caracteres de formatação usados, %f e %w representam o nome do arquivo e seu tamanho. No entanto existem muito mais formatos pré definidos que esses, que encontram-se na tabela a seguir. Fmt Atributo listado Fmt Atributo listado %b file size %u unique temporary filename %c comment %w current width in pixels %d directory %x x resolution %e filename extension %y y resolution %f filename %z image depth %g page geometry %A image alpha channel %h current image height in pixels %C image compression type %i input filename %D image dispose method %k number of unique colors %H page height %l label %W page width %m magick %X page x offset %n number of scenes %Y page y offset %o output filename %Q image compression quality %p page number %T image delay %q quantum depth %@ bounding box %r image class and colorspace %# signature %s scene number %% a percent sign %t top of filename \n newline \r carriage return Uma outra forma de escrever texto é com a opção draw, que permite escrever a partir de um deslocamento, dentro da moldura. Veja: $ convert size 285x85 xc:yellow font CandiceRegular \ pointsize 72 draw "text 25,60 'Silvina'" channel RGBA \ gaussian 0x6 fill blue stroke cyan strokewidth 2 \ draw "text 20,55 'Silvina'" Silvina1.png Pag: 17/47 Silvina1.png A opção draw é muito complexa e usa diversas primitivas, de acordo com a tabela a seguir, mas por enquanto vamos nos limitar à text. Primitiva Sintaxe point x,y line x0,y0 x1,y1 rectangle x0,y0 x1,y1 roundRectangle x0,y0 x1,y1 wc,hc arc x0,y0 x1,y1 a0,a1 ellipse x0,y0 rx,ry a0,a1 circle x0,y0 x1,y1 polyline x0,y0 ... xn,yn polygon x0,y0 ... xn,yn Bezier x0,y0 ... xn,yn path path specification image operator x0,y0 w,h filename text x0,y0 string Voltando ao exemplo anterior, o que fizemos foi escrever o texto duas vezes, sendo a segunda defasada 5 pixels para baixo e para a direita. O gaussian cria um efeito de névoa (blur) na cor cujo canal não estava citado. Como citei todos, a ausência de todas as cores é o preto. Assim sendo o segundo texto apareceu como uma névoa preta, dando a impressão de uma sombra difusa. Emoldurando Bem, já batemos uma bola sobre a opção frame, mas não é só com ela que se monta molduras, então vamos dar uma viajada genérica sobre o tema. Uma bonita tela deve ser realçada por bonitas moldura, não é? Então vamos começar vendo uma forma interessante de se montar molduras (em inglês frame) compostas. Pag: 18/47 $ convert ArraialDoCabo3.jpg mattecolor orange \ frame 5x5+5+0 mattecolor darkred frame 8x8 \ mattecolor navyblue frame 5x5+0+5 PorDoSolEmArraial.png PorDoSolEmArraial.png O que deu para deduzir deste exemplo? 1. A opção mattecolor define a cor de moldura; 2. Usei cores diferentes para mostrar que a primeira moldura definida é a mais interna e a última a mais externa. Se quiséssemos fazer ao contrário, isto é, tirar a moldura, usaríamos a opção shave, veja como: $ convert PorDoSolEmArraial.png shave 18x18 \ PorDoSolEmArraial1.png PorDoSolEmArraial1.png Podemos cortar uma imagem também com a opção chop. A diferença é que shave, por cortar simetricamente, recebe como parâmetros <larg>x<alt>, isto é, deve-se especificar quanto se deve cortar na largura e na altura em ambos os lados. O chop <larg>x<alt>+<desloc horiz>+<desloc vert> especifica 2 faixas, uma horizontal e outra vertical de corte. Já havia feito o Pão de Açúcar Gordo. Agora veja o Pão de Açúcar Magro: $ convert PaoDeAcucar1.jpg chop 12x50+40+0 PaoDeAcucarMagro.png Pag: 19/47 PaoDeAcucarMagro.png PaoDeAcucar1.jpg Neste exemplo foi tirada uma faixa de 12 pixels a partir do 50º pixel horizontal e outra de 40 pixels a partir do topo da imagem. Voltando à vaca fria, vamos ver que o frame não é a única forma de fazermos molduras, podemos fazê-las com border que também usa mattecolor, mas duas diferenças no uso dos dois são notáveis: 1. A opção border faz uma moldura plana ao redor da imagem e frame como já vimos, tem volume. Esta sensação 3D é conseguida pela adoção de 5 matizes da cor escolhida (mattecolor) para a moldura. 2. A opção bordercolor <cor> define <cor> como a cor de fundo da moldura sobre a qual a imagem irá repousar. Quando o fundo da imagem for transparente, se usado com border, adotará <cor> ou o seu valor padrão (defaulf) que é cinza claro (ligth grey). quando usado com frame, a transparência permanece. Se você estiver usando border e quiser que a transparência da imagem permaneça, use bordercolor none ou bordercolor transparent. Ambos (frame e border) usam o operador compose que especifica o tipo de composição que será feito. Um pouco de teoria para entender: Cada pixel da imagem é representado por gradações de vermelho, verde e azul (em inglês Red Green Blue, de onde saiu o acrônimo RGB). Cada pixel da imagem por sua vez, caso o canal de opacidade (matte channel) esteja ativo, tem um nível de opacidade, variando de transparente para opaco, que será usado para determinar a influência da cor do pixel quando compondo com um pixel de outra imagem. Se o canal de opacidade está desabilitado, todos os pixel são tratados como opacos. A cor de um pixel opaco é totalmente visível, ao passo que a cor de um pixel transparente é completamente ignorada. A seguir os mais importantes métodos de composição serão apresentados, onde trabalharemos com a seguinte linha de comandos: convert Tux.png bordercolor Blue \ compose <metodo> frame 6x6+2+2 Tux.gif Nesta linha de comandos o <metodo> variará de acordo com a coluna da esquerda da tabela a seguir e terá como origem e destino as seguintes imagens: Tux.png moldura Pag: 20/47 Onde a origem Tux.png tem o fundo transparente e a moldura destino será formada pelas opções bordercolor Blue e frame 6x6+2+2. Método Descrição A imagem (origem) nem a moldura (destino para onde a origem iria) são copiados para a saída src Somente a origem (source) é copiada para a saída dst O destino (destination) é deixado intocado srcover A origem se composição dstover A composição é feita com o destino se superpondo à origem e o resultado substitui o destino srcin A parte da origem que está dentro do destino substitui este último dstin A parte do destino que está superposta pela origem substitui o destino srcout A parte da origem fora do destino substitui o destino dstout A parte do destino fora da origem substitui o destino sobrepõe ao destino VAZIO clear na VAZIO Esta tabela, possui apenas uma parte dos métodos disponíveis para a opção compose. Vamos dar um mergulho mais fundo neste tema, quando estudarmos o utilitário composite). Pag: 21/47 Para terminar este assunto de moldura, caso você seja como eu, e goste que se coloque uma moldura branca em volta das fotos ampliadas para papel, vamos ver um script que faça isso automaticamente, de forma que você não tenha que pagar um pouco mais por esse serviço extra na ampliação. $ cat emoldura.sh #!/bin/bash # Esse script coloca molduras em fotografias. # Versão para zenity # Larg=5 # quanto maior for este número, mais larga será a moldura Arq=$(zenity fileselection multiple separator '^') || exit 1 # Tenho uma lista de arquivos separados por circunflexo (^) #+ Vamos trocar por ~+= os espaços em branco dos nomes dos arquivos #+ e depois substituir os circunflexos por espaços em branco para #+ criar uma lista para o mogrify rodar todos de uma vez. Arq=$(sed 's/ /~+=/g;s/\^/ /g' <<< "$Arq") for CadaUm in $Arq do CadaUm=$(sed 's/~+=/ /g' <<< $CadaUm) # Repondo os espaços em branco do nome de cada arquivo convert "$CadaUm" bordercolor white border $Larg "$CadaUm" done Efeitos especiais Vamos dar uma olhada em alguns efeitos, que algumas vezes embelezam imagens, outros que são engraçados, outros artísticos e, parece que estou me repetindo porque o ImageMagick é extremamente vasto, muito mais. Moldura oval esfumaçada (Vinheta) Sua sintaxe é vignette Raio{xSigma}{+}x{+}y{%}, onde: Raio é o raio da vinheta, Sigma é a largura da borda esfumaçada, isto é, quanto maior o número, mais larga será a borda e x e y são os deslocamentos horizontal e vertical, respectivamente, sendo que x positivo espreme a imagem horizontalmente e negativo, alarga. O y é a mesma coisa, quando positivo achata a imagem, quando negativo aumenta a altura. Esses 2 parâmetros atuam como descrito até a metade do tamanho da imagem depois os sinais invertem. Vamos logo mostrar, porque esse é fácil de entender: Pag: 22/47 $ convert Corcovado.jpeg background black \ vignette 0x0 CoVinPr0x0.png $ convert Corcovado.jpeg background black \ vignette 0x4 CoVinPr0x4.png $ convert Corcovado.jpeg background black \ vignette 0x8 CoVinPr0x8.png $ convert Corcovado.jpeg background black \ vignette 0x4+01 CoVinPr0x4+01.png $ convert Corcovado.jpeg background transparent \ vignette 0x4+01 CorcVinhetaOK.png CoVinPr0x0.png CoVinPr0x4.png CoVinPr0x8.png CoVinPr0x4+0-1.png CorcVinhetaOK.png Neste exemplo eu fiz um estudo para colocar uma vinheta em torno do Corcovado. Após testar 3 valores de sigma, cheguei a conclusão que o 0x4 era o melhor, mais repare que a cor de fundo está cobrindo as mãos e parte da lua e foi por isso que fiz um pequeno deslocamento do foco para cima (+01). Quando aprovei a imagem final, foi só passar para fundo transparente. Fala a verdade: ficou lindo, não é? Eu soube que você queria botar uma foto bem antiga na sua mesa, pra tirar uma onda e dizer que a sua vovó era linda. Então veja isso: $ convert Bundchen.jpg sepiatone 65% \ vignette 0x10+11 Camafeu.jpg Pag: 23/47 Bundchen.jpg Camafeu.jpg Pronto... Taí a vovó linda... ;) A opção sepiatone passa todas as cores para matizes de cinza e muda todos os meio tons para um marrom especial (sépia) que dá o jeitão envelhecido à foto. Distorsões O ImageMagick contempla alguns efeitos de distorções. vejamos alguns deles, como sempre com exemplos: $ convert size 150x150 xc:blue \ fill yellow draw 'rectangle 5,5 145,72.5' \ fill yellow draw 'rectangle 5,77.5 145,145' base.png $ convert base.png wave 10x70 wave.png $ convert base.png swirl 180 swirl180.png $ convert base.png swirl 720 swirl720.png base.png swirl180.png swirl.720.png wave.png Bem, já que não tem jeito, vamos às explicações: • A primeira linha de código, desenhou a base. E como? Primeiramente um retângulo azul de 150x150 que é a área total do desenho. Dentro desta, Pag: 24/47 desenhamos dois retângulos amarelos de forma a sobrar 5 linhas de 5 pixels cada, 4 formando um quadrado e uma dividindo horizontalmente este quadrado ao meio; • A segunda usou, em cima da base, a opção wave, que gera uma onda senoidal e que recebe 2 parâmetros: o primeiro é a altura máxima da onda (ou amplitude) e o segundo é o comprimento de onda (ou frequência); • Nas duas últimas linhas de comandos usamos a opção swirl, que gira a imagem a partir de seu centro a quantidade de graus estipulada. A primeira girou 180° e a segunda 720°. Entendido isso, então vamos ver um script de animação, usando o arquivo base.png, que acabamos de ver, e a opção swirl. $ cat entorta.sh #!/bin/bash # Montando uma animação no ImageMagick # Vou fazer uma figura que servirá como base da animação. #+ Ela será composta por 1 quadrado azul com 2 retângulos #+ inscritos, formando a figura base.png convert size 150x150 xc:blue \ fill yellow draw 'rectangle 5,5 145,72.5' \ fill yellow draw 'rectangle 5,77.5 145,145' base.png for ((i=1; i<=40; i++)) { # Vou gerar 40 imagens de trabalho, torcendo (swirl) #+ a imagem base.png com incrementos de 35 graus convert swirl $((35*$i)) base.png Trab_$i.png # Vou concatenar o nome de todas as imagens em Arqs Arqs="$Arqs Trab_$i.png" } # A animação a seguir é garantida pela opção coalesce. #+ A opção dither é usada para diminuir a perda de qualidade #+ com a redução da qtd de cores. #+ A opção colors 32 reduz a qtd de cores. #+ A opção layers optimize, usada com a anterior visam #+ acelerar o processo. convert coalesce dither colors 32 layers optimize $Arqs Anim.gif # Agora, se vc abrir Anim.gif no browser, verá a animação. Implosão O ImageMagick nos permite implodir uma imagem, de forma tal que seus pixels são "chupados" para o seu centro geométrico, como se ali houvesse um buraco negro. Tal buraco é tão voraz, que devemos começar nossos testes com valores bem pequenos para a opção implode, sob pena da imagem ficar tão deformada (ou distorcida) que não entenderemos do que se trata. Entendido isso, vamos ver uns exemplos para examinar seu comportamento. Pag: 25/47 $ convert Tux.png implode 0.4 TuxImp0.4.png $ convert Tux.png implode 0.8 TuxImp0.8.png $ convert Tux.png implode 1.5 TuxImp1.5.png $ convert Tux.png implode 3.0 TuxImp3.0.png Tux.png TuxImp0.4.png TuxImp0.8.png TuxImp1.5.png TuxImp3.0.png Mas trocando o sinal, também poderemos explodir. veja: $ convert size 200x70 xc:darkred \ fill white draw 'roundrectangle 5,5 195,65 5,5' \ fill black pointsize 35 draw \ "text 42,45 't e x t o'" texto.gif $ convert size 200x70 xc:darkred \ fill white draw 'roundrectangle 5,5 195,65 5,5' \ fill black pointsize 35 draw \ "text 12,45 'i m p l o d e'" implode 0.5 implode.gif $ convert size 200x70 xc:darkred \ fill white draw 'roundrectangle 5,5 195,65 5,5' \ fill black pointsize 35 draw \ "text 12,45 'e x p l o d e'" implode 0.5 explode.gif texto.gif implode.gif explode.gif Como você viu foi só botar o fator de implosão negativo que conseguimos uma explosão. Borrando imagens Quando falamos em borrar imagem não nos damos conta da importância disso. Este "esfumaçamento", responsável por isso, é bastante útil para gerarmos efeitos de fundo, sombras difusas e para termos efeitos de alta luminosidade de forma a criar imagens em 3D. O efeito de borrar é conseguido misturando as bordas das cores que formam as imagens. Existem 2 tipos: o gaussian e o blur, cujos resultados são semelhantes. Apesar do algorítimo matemático do primeiro ser melhor, e segundo é mais veloz e, talvez por isso, mais usado. Os argumentos dos dois são idênticos: <raio>x<sigma> sigma é uma função estatística que representa a distância na qual 90% do efeito, seja ele qual for, se aplica. Ou seja seu valor determina o tamanho da vizinhança que será usada. Pag: 26/47 O raio delimita a área de pixels que serão atingidos, e assim sendo, só tem sentido se for maior que sigma. O normal é este valor ser pelo menos 2 vezes o valor de sigma ou zero, quando então o valor será arbitrado pela opção. Assim sendo o mais importante é nos preocuparmos com o segundo, ele pode ser imaginado como uma aproximação de quanto você deseja que a imagem fique enevoada, em pixels. Poderia ser comparada ao calibre da pistola de pintura que você está usando para borrar a imagem. Esses fatores usam ponto flutuante, então você pode usar valores bem pequenos, como 0.5. Vi uma tabela muito interessante, que nos servirá de exemplo em http://www.imagemagick.org/Usage/convolve/blur_montage.jpg. Lá foi executado o seguinte comando: $ convert font Gecko pointsize 48 label:A \ bordercolor white border 20x10 blur_source.png blur_source.png - A imagem original não tem moldura Em seguida foram aplicadas sobre esta letra, cada uma das opções abaixo de cada gravura. Tirado de http://www.imagemagick.org/Usage/convolve/blur_montage.jpg Agora podemos notar que: Um pequeno fator para raio, limita o efeito da opção blur a um círculo de seu tamanho ao redor de cada pixel, assim um raio pequeno como 1 praticamente Pag: 27/47 anula o blur; Assim sendo, nunca use raio menor do que sigma. A exceção a esta regra é quando fazemos raio igual a zero. Esta inclusive é a solução ideal, pois desta forma você estará habilitando o cálculo automático do raio ideal para o dado fator do sigma. Isso pode ser facilmente constatado pela última linha da tabela. Então vamos ver como o blur funciona para começar a tirar proveito: $ convert size 100x100 xc:yellow frame 5x5+2+2 \ fill blue draw "circle 55,55 40,40" Circ.png $ convert Circ.png blur 0x8 CircBorrado.png Circ.png CircBorrado.png Repare que neste caso, a opção blur borrou tudo, inclusive a moldura, Agora vamos trocar o fundo amarelo, por um transparente e tirar a moldura: $ convert size 100x100 xc:none \ fill blue draw "circle 55,55 40,40" Circ1.png $ convert Circ1.png blur 0x8 CircBorrado1.png Circ1.png CircBorrado1.png Hiii, agora não borrou, o que houve? Repare que no exemplo com fundo amarelo, a faixa borrada do círculo tem a parte interna com predominância do azul e em sua área mais externa o que predomina é o amarelo, ou seja, ocorre uma mistura de cores que, assim como um gradiente, vai aumentando a densidade uma cor enquanto a outra diminui. Isso não pode ocorrer, quando temos somente uma cor, como no segundo exemplo em que o fundo era transparente (none). Do parágrafo anterior, deduzimos que o blur pode ser afetado pelos canais de cor. Para facilitar nossa vida, por enquanto trabalharemos com RGBA, ou seja vermelho, verde, amarelo e transparência (também chamado de alpha channel). Vamos ver o exemplo anterior usando esta técnica: $ convert Circ1.png channel RGBA blur 0x8 CircBorrado2.png Pag: 28/47 CircBorrado2.png Vamos voltar ao exemplo anterior para reparar que CircBorrado1.png, está ligeiramente mais escurecido em sua borda e isso se deu porque a transparência tem cor. Não adianta você perguntar: "Tem cor? Como assim?" Minha resposta será "Não sei, mas que tem, tem! E é isso que se lê em todas as fontes de consulta". Naquele exemplo a cor da transparência era preta e por isso escureceu um pouco a borda da figura, mas podemos usar isso a nosso favor. Vamos voltar ao nosso círculo azul em fundo amarelo, porém vamos brincar um pouco com a transparência: $ convert size 100x100 xc:#FF00 fill blue \ draw "circle 55,55 40,40" Circ2.png $ convert size 100x100 xc:#FF0F fill blue \ draw "circle 55,55 40,40" Circ3.png $ convert size 100x100 xc:#FF00 +matte fill blue \ draw "circle 55,55 40,40" Circ4.png Circ2.png Circ3.png Circ4.png Vamos analisar as 3 linhas de código: 1. Repare a notação xc:#FF00, isto é o mesmo que ligar as cores vermelho e verde (RG de RGB), deixando o azul e o alpha desligados, o resultado é um fundo amarelo (que é o resultado da soma de vermelho com verde) que não aparece por estar transparente; 2. Repare agora a notação xc:#FF0F, parecida com o anterior, porém agora tirando a transparência (ligando o canal alpha); 3. No último da série, a opção +matte explicitou a cor de fundo que estava transparente. Então essa é a única explicação que posso dar para provar que o canal alpha tem cor. Mas como eu disse, podemos usar isso a nosso favor. Vamos dar uma borrada em Circ2.png para ver o que ocorre. $ convert Circ2.png blur 0x8 CircBorrado3.png Pag: 29/47 CircBorrado3.png Desta forma a opção blur atuou somente para dentro do círculo. Além dessa opção temos mais duas que são: – motionblur <raio>x<sigma>+<angulo>; – radialblur <angulo> Blur de movimento Como o nome indica, o primeiro serve para dar ideia de movimento na direção do ângulo apontado por <angulo>. $ convert size 100x100 xc:black channel RGBA \ fill yellow stroke firebrick strokewidth 4 \ draw 'circle 55,55 35,35' motionblur 0x20+0 \ Astro1.png $ convert size 100x100 xc:black channel RGBA \ fill yellow stroke firebrick strokewidth 3 \ draw 'circle 55,55 35,35' blur 0x2 motionblur 0x24+45 \ draw 'circle 55,55 35,35' blur 0x2 motionblur 0x18+45 \ draw 'circle 55,55 35,35' blur 0x2 motionblur 0x6+45 \ Astro2.png $ convert size 100x100 xc:black channel RGBA \ fill yellow stroke firebrick strokewidth 4 \ draw 'circle 55,55 35,35' motionblur 0x18+25 \ draw 'circle 55,55 35,35' motionblur 0x18+55 \ draw 'circle 55,55 35,35' motionblur 0x18+40 \ Astro3.png Astro1.png Astro2.png Astro3.png Neste exemplo fiz uma tentativa de fazer algo semelhante a um cometa e para tal fiz 3 tentativas: – Na primeira usei somente um círculo amarelo com borda cor de tijolo com bastante motionblur; – No seguinte usei 3 círculos com o tamanho do motionblur variando. Como a circunferência (stroke) ficou muito marcada, fiz um blur 0x2 para diluila; – No último variei um pouco o ângulo da trajetória (assumiu os valores 25, 55 e Pag: 30/47 40) para dissipar o efeito do motionblur. Mais um exemplo. A minha vontade era dar uma idéia de movimento a uma foto de um carro, então procedi da seguinte maneira: $ convert Ferrari.jpeg motionblur 0x20+30 Ferrari1.png $ convert Ferrari.jpeg \( +clone motionblur 0x20+30 \) \ compose Overlay composite Ferrari2.png Ferrari.jpeg Ferrari1.png Ferrari2.png Repare que quando tentei somente jogar um motionblur o carro descaracterizouse, não dando nem para ver o Massa pilotando-o ;). Então o que fiz em seguida foi clonar a imagem original e mandar um motionblur no clone (os parênteses usados foram para dar prioridade à clonagem com blur e as contrabarras para escapá-los). O que fiz em seguida, foi uma ginástica para colocar a imagem original por cima do clone borrado, sem perder as características de ambos. Mais tarde, teremos um capítulo inteiramente dedicado a esta técnica de composição de imagens, que vai lhe permitir fazer uma série de truques. Blur radial A opção radialblur <angulo> deverá ser usada para criar um enevoado proveniente de um giro de <angulo> graus em torno do centro da imagem. Veja os dois exemplos a seguir: $ convert size 100x100 xc:black stroke white \ strokewidth 5 draw 'line 0,50 50,50' linha1.gif $ convert linha1.gif channel RGBA \ radialblur 60 FachoDeLuz.gif $ convert size 100x100 xc:black stroke red \ strokewidth 10 draw 'line 25,30 25,70' \ stroke yellow draw 'line 35,30 35,70' \ stroke blue draw 'line 45,30 45,70' linha2.gif $ convert linha2.gif channel RGBA radialblur 360 \ normalize circulos.gif linha1.gif FachoDeLuz.gif linha2.gif Pag: 31/47 No primeiro exemplo, com a linha branca girando 60° obtivemos um efeito parecido com o facho de uma lanterna no escuro. No segundo exemplo, colocamos lado a lado três barras coloridas, cujo fim coincidia com o centro da figura. Quando a giramos 360° conseguimos estes círculos concêntricos. Como o blur esmaece as cores, a opção -normalize foi usada somente para aumentar o contraste, "esticando" a faixa de intensidade dos valores. Sombreando (blur) Uma forma interessante de fazer sombras difusas é usando o blur como acabamos de ver. Repare a linha de comandos abaixo: $ convert size 280x90 xc:white pointsize 72 \ font CandiceRegular fill black \ draw "text 25,60 'Silvina'" blur 0x8 \ fill blue stroke yellow strokewidth 1.2 \ draw "text 20,55 'Silvina'" Silvina2.png Silvina2.png Esta imagem foi montada em duas etapas, na primeira escrevi o texto em preto e borrei, criando a sombra. Na segunda, defasei o texto em relação ao primeiro em 5 pixels para a esquerda e 5 pixels para cima, caprichando na apresentação, pois este que será o texto propriamente dito. O mesmo efeito poderia ser obtido se fizéssemos: $ convert size 280x90 xc:white pointsize 72 \ font CandiceRegular draw "text 25,60 'Silvina'" \ channel RGBA blur 0x8 fill blue stroke yellow \ strokewidth 1.2 draw "text 20,55 'Silvina'" Silvina3.png Silvina3.png Desta forma, não estipulei a cor do primeiro texto, mas usei todos os canais para fazer o blur, que assim resulta em preto. Veja agora este anúncio de neon e a velocidade do texto: Pag: 32/47 $ convert size 380x100 xc:black fill dodgerblue \ font SFCartoonistHandItalic pointsize 90 \ draw "text 20,80 'Bar Carnal'" blur 0x25 \ level 0%,50% draw "text 20,80 'Bar Carnal'" Neon.png $ convert size 200x80 xc:yellow fill navyblue \ stroke red font SFCartoonistHandItalic \ pointsize 70 draw "text 20,60 'Veloz'" \ motionblur 0x50+180 fill blue \ draw "text 20,60 'Veloz'" Veloz.png Veloz.png Neon.png No primeiro exemplo a opção level foi usada para aumentar o contraste do preto com o azul após o blur. O exemplo teria dado mais idéia de velocidade se tivesse usado um fonte cujo itálico fosse mais acentuado. Carvão Para dar um efeito de pintura a carvão (grafite muito macio) usamos a opção charcoal <num>, onde <num> seria algo como a "maciez" do carvão (quanto maior num, mais macio o carvão). Veja como fica: $ convert ArraialDoCabo13.png charcoal 1 ArrChac1.png $ convert ArraialDoCabo13.png charcoal 3 ArrChac3.png $ convert ArraialDoCabo13.png charcoal 6 ArrChac6.png ArraialDoCabo13.png ArrChac1.png ArrChac3.png ArrChac6.png Bico de pena Este efeito é um pouco parecido com o do carvão. Com ele podemos simular um desenho usando a técnica de bico de pena ou como preferem outros, um rascunho a lápis. O responsável por isso é a opção sketch <raio>x<sigma>+<angulo>, onde <raio>x<sigma> é como vimos na seção "Borrando imagens" e <angulo> seria o ângulo que os riscos de lápis fariam com relação à horizontal. Vejamos um exemplo: Pag: 33/47 $ convert ArraialDoCabo13.png \ sketch 0x10+135 ArrSket1.png $ convert ArraialDoCabo13.png colorspace gray \ sketch 0x10+135 ArrSket2.png ArraialDoCabo13.png ArrSket1.png ArrSket2.png A imagem ArrSket1.png não ficou como queríamos porque estava ainda colorida. Com o uso da opção colorspace, colorimos a imagem com matizes de cinza e ai sim, ficou parecendo um esboço de lápis ou uma imagem usando a técnica de bico de pena. Para ver todos os parâmetros possíveis da opção colorspace, faça: convert list colorspace Pintura a óleo Bem, já que estamos falando de estilos de pintura, como carvão e bico de pena, vamos ver a opção paint <raio>, para tornar as imagens parecidas com uma pintura a óleo. Com esta opção, cada pixel é trocado pela cor mais frequente na vizinhança de um círculo com <raio> pixels, isto é, <raio> seria algo como o diâmetro do pincel que está pintando o quadro. $ convert paint 2 Girasois.jpg GirasoisP2.png $ convert paint 5 Girasois.jpg GirasoisP5.png Girasois.jpg GirasoisP2.png GirasoisP5.png Pulverização O que chamo de pulverização é a opção spread <num> que troca aleatoriamente a ordem dos pixels que estão dentro da área <num> em volta de cada pixel, criando um Pag: 34/47 efeito parecido com um "polvilhamento". Veja: $ convert spread 3 ArraialDoCabo13.png ACSpread.png ArraialDoCabo13.png ACSpread.png Enfatizando cores Você pode "puxar" uma ou mais cores usando a opção colorize. Os argumentos desta opção podem podem ser passados na sequência RGB em valores absolutos ou percentuais, Assim 20,30,40 ou 20/30/40 significa enfatizar o vermelho, o verde e o azul com estes valores respectivamente. Vamos ver um exemplo: $ convert ArraialDoCabo13.png \ colorize 20,30,40 ArrColor.png ArraialDoCabo13.png ArrColor.png Negativo A opção negate troca cada pixel pela sua cor complementar, isto é, o branco tornase preto, o amarelo (que é formado por R+G) torna-se azul (B), e por aí vai... Se for usado +negate, somente os pixels da escala cinza da imagem serão negados. O efeito final é de um negativo fotográfico. A opção negate é sensível aos canais RGBA, isto é, você pode pegar o complemento de somente uma (ou mais) cor(es). Pag: 35/47 $ convert ArraialDoCabo13.png negate ACNeg1.png $ convert ArraialDoCabo13.png \ colorspace gray ACCinza.png $ convert +negate ACCinza.png ACNeg2.png ACNeg1.png ACCinza.png ACNeg2.png Veja a figura a seguir: R Magenta B Amarelo Ciano G Se você olhar o padrão RGB como um triângulo, você verá que o complemento de uma cor básica (as que formam os vértices do triângulo) é o lado oposto (assim sendo o complemento do vermelho é o ciano) e o complemento de de uma cor composta (as que formam os lados do triângulo) é o vértice oposto (assim sendo o complemento do magenta é o verde). Outra forma de mostrar o triângulo RGB e seus complementos Solarização Já que estamos falando em negativos fotográficos, a solarização é feita em laboratórios de ampliação dando-se um flash de luz após o negativo ser projetado no papel e antes de ir para o líquido de revelação. Isso causa um efeito de "queimado" na fotografia, quando as cores mais brilhantes são distorcidas. Para repetir esse efeito, usamos a opção solarize <num>. Se <num> for 0%, o efeito será o mesmo de negate. Se <num> for 100% não será produzido nenhum Pag: 36/47 efeito na imagem. $ convert ArraialDoCabo13.png solarize 90% ACSol.png ArraialDoCabo13.png ACSol.png Metalizando imagens A função emboss <raio>x<sigma> "metaliza" as imagens, como se pusesse um papel aluminizado sobre a imagem, dando-lhe esta aparencia. Acho que o algorítimo dos parâmetros estava "bugado" na versão instalada (6.3.7), pois <raio> não altera nada no efeito final, portanto em seu lugar usarei sempre zero. No exemplo a seguir, preferi usar uma imagem em tons cinza pois o efeito é melhor observado, mas isso não quer dizer que não possa ser usado em imagens à cores. Experimente e veja. $ convert ACCinza.png emboss 0x0.8 ACMetal0.8.png $ convert ACCinza.png emboss 0x1.3 ACMetal1.3.png ACCinza.png ACMetal0.8.png ACMetal1.3.png 3D em imagens Uma forma de conseguirmos um efeito 3D é com a opção shade <angulo horizontal>x<angulo vertical>. A palavra shade em inglês significa sombra e por isso os parâmetros definem os dois ângulos de entrada de luz. Assim sendo, em shade 0x0 o segundo zero significa que a luz entra junto ao plano horizontal e o primeiro indica que a luz está vindo horizontalmente pela direita, como no diagrama a seguir: Pag: 37/47 Luz Linha de Terra Visão lateral Vista de cima Vamos então mostrar diversos formas de sombrear usando a linha de comandos a seguir, para fazer um círculo que nos servirá como modelo: $ convert size 50x50 xc:black fill white \ draw 'circle 25,25 5,25' CircBasico.gif CircBasico.gif Tendo esta imagem vamos então variar <angulo horizontal> e <angulo vertical> na seguinte linha de código: $ convert CircBasico.gif shade \ <angulo horizontal>x<angulo vertical> SombraHxV.gif No nome da imagem gerada, HxV equivale a <angulo horizontal>x<angulo vertical>. Poderemos então montar a tabela a seguir: 270 90 <angulo vertical> 60 45 30 0 0 <angulo horizontal> 45 90 180 Pag: 38/47 Identify Descreve os formatos e características de arquivo(s) de imagens. A descrição padrão apresentada contém o nome da imagem, o formato do arquivo, o tamanho da imagem, o tamanho do plano de fundo da imagem (em inglês canvas) com o deslocamento da imagem sobre este plano, profundidade de cor, tipo de formato interno (como vimos na tabela de formatos na seção "Usando Texto") e o espaço da imagem em disco. $ identify CoretoFlorestaDaTijuca.jpg CoretoFlorestaDaTijuca.jpg JPEG 1086x820 1086x820+0+0 DirectClass 8bit 446.51kb 0.130u 0:02 Você também pode conseguir resultado semelhante usando a opção info: do convert. $ convert CoretoFlorestaDaTijuca.jpg info: CoretoFlorestaDaTijuca.jpg JPEG 1086x820 1086x820+0+0 DirectClass 8bit Se tivesse usado a opção verbose, teria de volta todas as informações que você possa imaginar que uma imagem tenha, e muito mais. Veja só: $ identify verbose CoretoFlorestaDaTijuca.jpg | wc l 97 Nesta linha de código o wc l conta a quantidade de linhas geradas pela opção verbose, e tivemos como resposta 97 linhas. Usei este exemplo para mostrar que não dá para listar todas as propriedades nesta publicação, mas aconselho que você o faça, usando uma fotografia tirada com a sua câmera. Então você vai encontrar informações como: exif:DateTime=2007:10:01 22:39:51 exif:Make=Panasonic exif:Model=DMCFZ50 exif:Orientation=1 Permite ordenar fotos cronologicamente Fabricante da câmera Modelo da câmera Posição da câmera Esta última informação, nos permite fazer um script para colocar todas a fotos em pé, já que a orientation define a orientação da câmera com relação à cena capturada. Essa orientação dá-se de acordo com a tabela a seguir: Pag: 39/47 Valor Linha zero Coluna zero 1 Topo Lado esquerdo 2 Topo Lado direito 3 Embaixo Lado direito 4 Embaixo Lado esquerdo 5 Lado esquerdo Topo 6 Lado direito Topo 7 Lado direito Embaixo 8 Lado esquerdo Embaixo O macete é ler a tabela assim: para o valor 1, a linha zero (a parte superior da imagem) é o topo da cena capturada e a coluna zero (a mais a esquerda na imagem) é a esquerda da cena capturada, isto é, a posição normal de tirarmos foto de uma paisagem (landscape). Se pegarmos o valor 6, veremos que a linha zero da imagem corresponde ao lado direito da cena e a coluna zero é a parte de cima da cena. Esse tipo de imagem é comum quando fazemos uma fotografia de uma pessoa em pé (portrait). Repare que no valor 8 temos também um portrait, mas com a câmera ao contrário e, no valor 3 a câmera está de cabeça para baixo. Uma outra forma de explicação bacana que achei na internet, mostra a posição que a imagem da letra F teria em cada uma das orientações. 1 2 3 4 5 6 7 8 Entendido isso, fica fácil montar o tal script (usando bash e zenity) para girar as imagens. Olha só: A opção format, serve para selecionarmos os formatos sobre os quais desejamos informações. Pesquisando na tabela de formatos que está na seção "Usando Texto" descobrimos que o formato %w devolve a largura em pixels, %x a resolução horizontal e %y a resolução vertical, então podemos pegar estes dados diretamente fazendo: Pag: 40/47 $ identify format 'Largura=%w pxs\nResolução \ Horizontal=%x\nResolução Vertical=%y' \ CachoeiraFlorestaDaTijuca2.JPG Largura=768 px s Resolução Horizontal=96 PixelsPerInch Resolução Vertical=96 PixelsPerInch Repare que um monte de texto, inclusive \n para quebrar linha, foi adicionado ao comando sem problema algum, pois o format atua quase como o echo do bash e por isso mesmo a indentação do comando ficou prejudicada. Mogrify Muito semelhante ao convert, porém não gera arquivo de saída, já que a saída é feita no mesmo arquivo de entrada. Você já viu que isso é perigoso e deve ser usado com muita cautela, né? No entanto, o script a seguir serve para girar aquelas fotos que você tirou com a sua câmera na posição vertical, pois estava fotografando uma girafa. ;) Pag: 41/47 $ cat RodaFoto.sh #!/bin/bash # Esse script gira um arquivos de imagem. # Versão para zenity # # Lendo os arquivos que serão girados Arq=$(zenity fileselection multiple separator '^') || exit 1 # Tenho uma lista de arquivos separados por circunflexo (^) #+ Vamos "escapar" os espaços em branco dos nomes dos arquivos #+ e substituir os circunflexos por espaços em branco para #+ criar uma lista para o mogrify rodar todos de uma vez. Arq=$(sed 's/ /\\ /g;s/\^/ /g' <<< "$Arq") # Montando uma radio list para capturar o ângulo de rotação Ang=$(zenity list radiolist height 240 title "Ângulo de rotação" \ text "Escolha o ângulo que sua\n imagem será girada" \ column Marque column ângulo true 90 false 180 false 270 false "Outro valor") || exit 1 [ "$Ang" = "Outro valor" ] && { Ang=$(zenity entry title "Ângulo especial" text "Informe o ângulo entre 1° e 359°") || exit 1 (($Ang < 1 || $Ang > 359)) && { zenity error title "Erro" text "O ângulo deveria ser entre 1° e 359°" exit 1 } } mogrify rotate $Ang "$Arq" display "$Arq" Executando o script: Antes Após girar 90° Composite Sobrepõe uma imagem sobre a outra, fazendo isso de muitas formas diferentes, usando procedimentos distintos; Sua utilização mais simples é simplesmente jogando uma imagem com fundo transparente sobre outra. Vamos então botar o Tux no "bem bom": Pag: 42/47 $ composite gravity south Tux.gif Camafeu.jpg \ CamafeuTux.png Tux.gif Camafeu.jpg CamafeuTux.png Como você viu o Tux ficou na pole position. ;) Neste exemplo usamos o opção -compose, que por ter diversos operadores, serve para atribuir o tipo de composição de imagens que será feito. Para ver todos os operadores, use: $ convert list compose Nestas composições, cada pixel pode opcionalmente (se o canal de opacidade (matte) estiver habilitado) ter um nível de opacidade associado, que varia de opaco a transparente, que pode ser usado para determinar a influência do da cor do pixel no pixel correspondente na imagem com a qual se está compondo Se o canal de opacidade estiver desabilitado, então todos os pixels da imagem são tratados como opacos. Vamos ver um exemplo mais parrudo, onde tenho uma foto de Arraial do Cabo, que quero rotular. Mas Arraial é tão lindo que não merece que se "polua" a foto rotulando sobre ela. Então usei um macete: criar um quadro ligeiramente maior que a foto, e rotular este quadro. Olha só: $ identify ArraialDoCabo.jpg AC5.jpg JPEG 192x144 192x144+0+0 DirectClass 8bit 20.6152kb $ convert size 192x174 xc:blue canvas.jpg $ composite gravity south compose copy \ ArraialDoCabo.jpg canvas.jpg composto.jpg $ convert font PurisaMedium pointsize 18 fill gold \ background blue label:'Arraial do Cabo' miff: | \ composite gravity north composto.jpg rotulada.jpg Primeiramente peguei o tamanho da foto com o comando identify, em seguida, com o comando convert, criei um quadro azul (canvas.jpg) com 30 pixels a mais na altura. O composite executado em seguida, colocou a foto na parte inferior do Pag: 43/47 quadro (gravity south), criando o arquivo composto1.jpg. Agora só falta adicionar o rótulo. Isso foi feito pelo convert que gerou a frase e passou-a via pipe (|) para outro composite. Repare que este último recebeu a entrada do pipe em um arquivo emulado pelo hífen () e que antes do pipe, temos um miff:. Pois é, esta é a sintaxe requerida para usarmos pipe dentro do ImageMagick. Veja os arquivos que foram gerados passo a passo: Arraial do Cabo.jpg canvas.jpg Composto.jpg rotulada.jpg Montage Na sua forma básica este utilitário combina diversas imagens criando uma nova, com as imagens lado a lado, formando um mosaico. Veja seu emprego básico: $ identify ArraialDoCabo1.jpg ArraialDoCabo2.jpg \ ArraialDoCabo3.jpg ArraialDoCabo4.jpg ArraialDoCabo1.jpg JPEG 640x480 640x480+0+0 DirectClass 8bit 25.666kb ArraialDoCabo2.jpg JPEG 400x300 400x300+0+0 DirectClass 8bit 26.5625kb ArraialDoCabo3.jpg JPEG 500x375 500x375+0+0 DirectClass 8bit 15.7715kb ArraialDoCabo4.jpg JPEG 300x225 300x225+0+0 DirectClass 8bit 16.9883kb $ montage ArraialDoCabo1.jpg ArraialDoCabo2.jpg \ ArraialDoCabo3.jpg ArraialDoCabo4.jpg ACMontado.jpg $ identify ACMontado.jpg AC.jpg JPEG 256x252 256x252+0+0 DirectClass 8bit 11.9004kb Como você viu, originariamente as imagens tinham tamanhos diferentes, mas após a aplicação do montage, elas ficaram do mesmo tamanho e com a seguinte aparência: Pag: 44/47 ACMontado.jpg Então você já percebeu que o montage é o pulo do gato para fazermos miniaturização de imagens (thumbnails), não é? Vamos então ver um outro exemplo sobre isso: $ montage ArraialDoCabo[14].jpg tile x1 frame 5 \ shadow geometry 50x50+5+5 ACthumb.jpg Neste exemplo vemos quatro novas opções: 1. tile (azulejo em inglês), que especifica a matriz COxLI onde CO é a quantidade de colunas e LI a de linhas. Como a quantidade de colunas não foi especificada, o montage só se preocupará com o número de linhas (no caso 1). 2. frame (moldura em inglês) que coloca uma moldura em torno de cada azulejo. No caso, frame 5, cria uma moldura de 5 pixels. 3. shadow (sombra em inglês) que informa que os azulejos terão sombra, dando idéia de volume; 4. geometry que define LAxAL+X+Y, onde LA é a largura de cada azulejo, AL a altura X e Y são os deslocamentos horizontais e verticais respectivamente. Então neste caso cada miniatura tem 50x50 pixels e estão deslocadas umas das outras e das bordas 5 pixels. Veja o efeito final: ACthumb.jpg Como fizemos antes, podíamos rotular a foto de Arraial do Cabo sem "poluir" a linda imagem usando também o montage que, com a opção de usar molduras, fica com um acabamento melhor. Vejamos: $ montage frame 5 geometry +0+0 label "Arraial do Cabo" \ font ImpactNormal pointsize 25 fill Blue \ stroke orange background none \ mattecolor DodgerBlue ArraialDoCabo.jpg montage.png Pag: 45/47 montage.png Vamos a um exemplo bastante completo para que possamos usar diversas opções do montage e analisá-las: $ montage title "Arraial do Cabo" label '' fill blue \ ArraialDoCabo[16].jpg tile x1 bordercolor none \ frame 5 mattecolor DodgerBlue texture mar.gif \ geometry 70x70+2+3 ACMontageCompleta.png ACMontageCompleta.png Repare que neste exemplo a opção texture usa uma imagem copiada de parte do último azulejo. Isso foi feito com o utilitário import (que também faz parte da suíte ImageMagick e que veremos mais à frente). Note ainda que usei a opção label '', somente para poder estipular a cor do título, já que as definições de label são herdadas por title, e este que queria colorir de azul. Veja estas opções e outras que usamos nos exemplos de montage, resumidos nas tabelas a seguir (adaptadas do site oficial do ImageMagick). Pag: 46/47 Principais opções do montage quanto ao tratamento de cores Opção Define background A cor por fora da imagem. Frequentemente a escolha é por none ou transparent para uso nas páginas web. bordercolor A cor por dentro da moldura de imagens que não preenchem a moldura totalmente, isto é, têm fundo transparente. mattecolor A cor da moldura. Note que esta cor é formada por tons claros e escuros para dar à moldura uma aparência de 3D. Então cada cor escolhida, efetivamente, é formada por 5 matizes fill A cor usada por label e title no montage stroke A cor da borda de cada letra nos label Principais opções de controle do montage Opção Define tile A matriz de linhas e colunas que serão preenchidas pelas imagens do montage. Se a matriz for menor que a quantidade de imagens, serão gerados tantos arquivos na saída quanto a quantidade de matrizes necessárias para abrigar todas as imagens title Coloca um título sobre a montage, usando a mesma fonte, porém maior, que a usada para rotular (label) as imagens. frame Cria uma moldura em volta da caixa contendo a imagem com a largura estipulada (deve ter no mínimo 2 pixels, mas 5 e 6 são excelentes valores) shadow gera uma sombra na moldura e/ou na imagem. Note que nenhum argumento é requerido, apesar de ser o indicado nos manuais texture Usa uma textura ao invés de uma cor de fundo (que seria definida por background). geometry Redimensiona as imagens. Também define o espaçamento horizontal e vertical entre os azulejos (tile Pag: 47/47