Dica do Linux: Criando uma Régua de Pixels a partir da Linha de Comandos

Como desenhar linhas e texto em imagens com script Bash, aritmética shell e ImageMagick

Aprenda como usar a linha de comandos do Linux® e algumas técnicas básicas de script Bash para desenhar linhas e texto em imagens usando ImageMagick. E crie uma régua de pixels ao longo da imagem.

Ian Shields, Senior Programmer, IBM

Ian ShieldsIan Shields trabalha em vários dos projetos Linux para a zona Linux do developerWorks. Ele é um programador senior da IBM em Research Triangle Park, NC. Ele iniciou na IBM em Canberra, Austrália, como um Engenheiro de Sistemas em 1973 e, desde então, trabalhou em sistemas de comunicações e computação disseminada em Montreal, no Canadá, e em RTP na Carolina do Norte, nos Estados Unidos. Ele possui diversas patentes. Sua graduação é em matemática pura e filosofia na Australian National University. Ele possui mestrado em ciências e é doutor em ciências da computação na Universidade do Estado da Carolina do Norte.


nível de autor Contribuidor do
        developerWorks

23/Jul/2009

Às vezes preciso desenhar algumas linhas ou algum texto em uma imagem ou em uma tela em branco. Recentemente, precisei incluir uma imagem simples de uma régua de pixels em um artigo do developerWorks. Eu desejava que a imagem tivesse 572 pixels de amplitude para corresponder o máximo recomendado atual para imagens de artigos do developerWorks, conforme descrito em "Ilustrando seu artigo ou tutorial para o developerWorks." Várias réguas de pixels de tela estão disponíveis para Linux e para Windows (consulte Recursos), mas apenas desejo uma imagem GIF, JPEG ou PNG simples. Esta dica mostra como usar o script Bash, a aritmética shell e o ImageMagick para criar uma régua de pixels.

Criar uma Tela

A primeira coisa que qualquer artista precisa é uma tela, portanto, vamos criar uma usando o tipo de pseudo-imagem XC no ImageMagick. Também precisamos de uma cor, uma das muitas cores denominadas no ImageMagick, ou uma cor customizada. (Consulte Recursos para um link para a documentação do ImageMagick, onde você pode localizar uma lista completa de tipos de pseudo-imagem e nomes de cores.) A Lista 1 mostra como criar uma tela de 572x100 em azul claro usando o comando convert . (O comando convert é geralmente usado para converter para um formato de imagem diferente ou alterar uma imagem.)

Lista 1. Criando uma tela
convert -size 572x100 xc:lightblue ruler1.gif

A Figura 1 mostra nossa nova tela.

Figura 1. Uma tela de 572x100 pixels azul clara para nossa régua
Uma tela de 572x100 pixels azul clara para nossa régua

Incluir Algumas Linhas

Agora que temos uma tela, vamos desenhar marcas para mostrar os vários pontos ao longo da régua. O valor de 72 ppp (pixels por polegada) é o padrão para gráficos com base na Web, portanto, vamos colocar nossa primeira marca em 72 pixels e fazê-la estender 30 pixels a partir da parte inferior da imagem. Vamos criar também a cor de preenchimento para a linha em preto e especificar os dois terminais da linha.

Lista 2. Incluindo uma linha na tela
convert  -fill black -draw "line 72,70 72,100" ruler1.gif ruler2.gif

A Figura 2 mostra nossa nova imagem com uma única linha desenha nela.

Figura 2. A tela com uma única linha vertical de 72 pixels a partir da esquerda
A tela com uma única linha vertical de 72 pixels a partir da esquerda

Fazendo isso, individualmente para cada linha, queremos que a régua não seja tão atraente. Assim, vamos usar o comando seq para gerar uma lista de deslocamentos horizontais com 72 pixels de separação e um loop for para desenhar nossas linhas principais na régua, conforme mostrado na Lista 3.

Lista 3. Incluindo linhas na tela a cada 72 pixels
convert  -fill black -draw "$(for n in $(seq 0 72 572) ;\
 do echo line $n,70 $n,100 ; done)" ruler1.gif ruler3.gif

Observe que usamos duas substituições de comandos para gerar as especificações de linhas individuais para a operação de desenho. Também colocamos uma marca em 0, a extremidade esquerda. A Figura 3 agora está começando a parecer mais com uma régua.

Figura 3. A tela com linhas verticais a cada 72 pixels a partir da esquerda
A tela com linhas verticais a cada 72 pixels a partir da esquerda

Script para mais linhas

Neste ponto, nossa linha de comando está ficando um pouco complexa, e ainda temos as marcas principais em nossa régua. Hora de começar o script. Na Lista 4, usamos a aritmética shell e loops for para colocar uma marca de 20 pixels na metade entre as marcas que já temos, e para colocar marcas de 10 pixels a cada 6 pixels entre as marcas mais longas. Chamamos o script buildruler.sh e o colocamos em nosso diretório de trabalho para os propósitos deste artigo.

Lista 4. Incluindo um conjunto completo de marcas para a régua
#!/bin/bash
# Take user parameters or set defaults
rulername="$1"
rulerlength="$2"
rulername="${rulername:=ruler.gif}"
rulerlength="${rulerlength:=572}"
drawstring=""
#Build the line definitions for the ruler marks
for x1 in `seq 0 72 $rulerlength`; do
  drawstring="$drawstring line $x1,70 $x1,100"
  for x2 in 0 36; do
    (( offset = $x1 + $x2 ))
    drawstring="$drawstring line $offset,80 $offset,100"
    for x3 in `seq 6 6 30`; do
      (( offset2 = $offset + $x3 ))
      drawstring="$drawstring line $offset2,90 $offset2,100"
    done
  done
done
#Create the ruler
convert -size "${rulerlength}x100" xc:lightblue -fill black \
 -draw "$drawstring" "$rulername"

Observe que incluímos alguns parâmetros para permitir que um usuário altere o nome da régua e especificar o comprimento. Agora, nossa régua se parece com a Figura 4. Usamos o comando ./buildruler.sh ruler4.gif para gerar esta régua.

Figura 4. Nossa régua com um conjunto completo de marcas com 6 pixels de separação
Nossa régua com um conjunto completo de marcas com 6 pixels de separação

Incluindo Texto

Citando

Uma das coisas complicadas com script é saber quando citações são necessárias e quando elas não são, e como passar cadeias citadas como parâmetros. Preste atenção particular para a citação usada nesses scripts.

Agora, vamos rotular as marcas maiores em nossa régua com os números 0, 72, 144 e assim por diante. Precisamos informar ao ImageMagick qual fonte usar e qual tamanho e cor elas devem ter. Obviamente, o 0 deve estar na extremidade esquerda da régua, mas se colocarmos os números de dois e três dígitos nos pontos de 72 pixels, eles parecerão desorganizados. Para corrigir isso, deslocaremos os números um pouco para a esquerda para que pareçam mais centrados sobre a marca. Nosso script expandido é mostrado na Lista 5.

Lista 5. Incluindo rótulos na régua
#!/bin/bash
# Take user parameters or set defaults
rulername="$1"
rulerlength="$2"
rulername="${rulername:=ruler.gif}"
rulerlength="${rulerlength:=572}"
drawstring=""
#Build the line definitions for the ruler marks
for x1 in `seq 0 72 $rulerlength`; do
  drawstring="$drawstring line $x1,70 $x1,100"
  for x2 in 0 36; do
    (( offset = $x1 + $x2 ))
    drawstring="$drawstring line $offset,80 $offset,100"
    for x3 in `seq 6 6 30`; do
      (( offset2 = $offset + $x3 ))
      drawstring="$drawstring line $offset2,90 $offset2,100"
    done
  done
done
#Add the labels
labelfont="-fill black -font helvetica -pointsize 24  -draw"
labelstring="text 0,60 \"0\" "
for x1 in 72; do
  (( offset = $x1 - 12 ))
  labelstring="$labelstring text $offset,60 \"$x1\" "
done
for x1 in `seq 144 72 $rulerlength`; do
  (( offset = $x1 - 18 ))
  labelstring="$labelstring text $offset,60 \"$x1\" "
done

#Create the ruler
convert -size "${rulerlength}x100" xc:lightblue -fill black \
 -draw "$drawstring" $labelfont "$labelstring" "$rulername"

Agora nossa régua se parece com a Figura 5.

Figura 5. Nossa régua com rótulos e conjunto completo de marcas
Nossa régua com rótulos e conjunto completo de marcas

Posicionando Texto

Como sabemos quanto deslocar o texto ou a distância a partir da parte superior colocá-lo? A resposta curta é que experimentei e presumi! Não é uma solução ideal.

Para fazer um trabalho melhor na colocação do texto, precisamos saber qual será o tamanho do retângulo contendo o texto. Mas isso depende da fonte e se a fonte é proporcional e outras coisas que não são tão fáceis de calcular. Felizmente, da mesma forma que podemos criar uma tela com o ImageMagick, podemos criar um rótulo. Criaremos um título de Régua de Pixels e o colocaremos em uma fonte de 36 pontos. O rótulo é criado como uma imagem, e podemos usar o comando identify para determinar seu tamanho, conforme mostrado na Lista 6.

Lista 6. Criando um título e medindo seu tamanho
$ convert -fill NavyBlue -background Lavender -font helvetica -pointsize 36 \
 label:"Pixel Ruler" label.gif
$ identify "label.gif"
label.gif GIF 175x36 175x36+0+0 8-bit PseudoClass 256c 1.98kb

Tornamos o texto azul marinho e incluímos lavanda como cor do plano de fundo para ajudar a imagem se destacar do plano de fundo desta página, mas você obtém o mesmo tamanho de imagem com ou sem a cor do plano de fundo. A imagem do rótulo resultante é mostrada na Figura 6.

Figura 6. O rótulo como uma imagem
O rótulo como uma imagem

Ainda melhor que escrever um arquivo, podemos usar a classe INFO do ImageMagick para determinar ainda mais informações sobre o texto, incluindo onde está a linha de base. Escreveremos o texto em uma tela grande o suficiente e, então, ajustaremos a tela para a extremidade do texto, conforme mostrado na Lista 7.

Lista 7. Usando a classe de imagem INFO para determinar informações de fonte
$ convert -size 572x100 xc:lightblue -font helvetica -pointsize 36 \
  -fill black -undercolor lavender  -annotate +40+50 'Pixel Ruler' -trim info:
xc:lightblue XC 174x36 572x100+40+23 16-bit DirectClass

O texto anotado é iniciado em um ponto cuja coordenada y representa a linha de base do texto. A saída acima mostra que o texto serve em uma caixa com 174x36 pixels de tamanho. A discrepância de 1 pixel entre este e nosso resultado anterior é insignificante. A parte superior da caixa está posicionada 23 pixels abaixo da parte superior de nossa tela original. Com a linha de base estava 50 pixels abaixo da tela original, isso significa que a linha de base está, na realidade, 27 pixels (50 menos 23) abaixo da parte superior do texto, deixando 9 pixels para descendentes. A Figura 7 ilustra o relacionamento usando uma imagem colocada na tela não-ajustada.

Figura 7. As métricas do rótulo
As métricas do rótulo

Agora que temos as dimensões do rótulo, vamos colocar a linha de base 40 pixels a partir da parte superior da imagem e centrá-la horizontalmente. Nosso script final é mostrado na Lista 8 e também está disponível para download.

Lista 8. Nosso script final
#!/bin/bash
# Take user parameters or set defaults
rulername="$1"
rulerlength="$2"
rulername="${rulername:=ruler.gif}"
rulerlength="${rulerlength:=572}"
drawstring=""
#Build the line definitions for the ruler marks
for x1 in `seq 0 72 $rulerlength`; do
  drawstring="$drawstring line $x1,70 $x1,100"
  for x2 in 0 36; do
    (( offset = $x1 + $x2 ))
    drawstring="$drawstring line $offset,80 $offset,100"
    for x3 in `seq 6 6 30`; do
      (( offset2 = $offset + $x3 ))
      drawstring="$drawstring line $offset2,90 $offset2,100"
    done
  done
done
#Add the labels
labelfont="-fill black -font helvetica -pointsize 24  -draw"
labelstring="text 0,60 '0' "
for x3 in 72; do
  offset3=$(($x3 - 12 ))
  labelstring="$labelstring text $offset3,60 '$x3' "
done
for x4 in `seq 144 72 $rulerlength`; do
  offset4=$(( $x4 - 18 ))
  labelstring="$labelstring text $offset4,60 '$x4' "
done
#Add a title
titledimension=$(convert -size 572x100 xc:lightblue -font helvetica \
  -pointsize 36  -fill black -undercolor lavender\
  -annotate +40+50 'Pixel Ruler' -trim info: | awk ' {print $3 } ')
titlewidth=${titledimension%x*}
titlefont="-fill NavyBlue -font helvetica -pointsize 36"
titlepos=$(( (($rulerlength - $titlewidth)) / 2 ))
titletext="text $titlepos,30 'Pixel Ruler' "
#Create the ruler
convert -size "${rulerlength}x100" xc:lightblue \
 -fill black  -draw "$drawstring" $labelfont "$labelstring" \
 $titlefont -draw "$titletext" "$rulername"

A régua final é mostrada na Figura 8.

Figura 8. A régua final, completa com título
A régua final, completa com título

Não muito ruim para alguém com nenhuma habilidade artística!


Um exemplo semiprático

Quando as imagens são indentadas—como em listas, por exemplo—a largura máxima permitida no developerWorks é reduzida de forma adequada. Portanto, você pode usar essas réguas manuais como uma verificação para quaisquer imagens enviadas com um artigo.

  • Esta é uma régua curta em uma lista sem classificação que foi criada com o comando ./buildruler.sh ruler9.gif 400.
    Figura 9. Uma régua com 400 pixels
    Uma régua com 400 pixels
    • E esta é uma régua mais curta ainda que é indentada posteriormente. Ela foi criada com o comando ./buildruler.sh ruler10.gif 300.
      Figura 10. Uma régua com 300 pixels
      Uma régua com 300 pixels

Conclusão

Neste curto exercício, você acompanhou algumas técnicas básicas para o script de imagens contendo linhas e texto usando o ImageMagick. Você encontrará mais técnicas em nossos artigos "Gráficos a partir da linha de comando" e "Mais gráficos a partir da linha de comando." Você localizará um host de outros exemplos na página inicial do ImageMagick. Consulte Recursos para obter links.

Os scripts aqui não são a prova de balas. Por exemplo, não validamos se o comprimento é um número positivo e grande o suficiente para uma régua considerável ou se o arquivo especificado é um tipo de arquivo de imagem válido para o ImageMagick. Você encontrará outras questões também. Por exemplo, os rótulos da régua podem ser truncados como na Figura 10 acima, uma possibilidade que nosso script não considerou.

Você também pode parametrizar quantos aspectos desejar. Tente incluir cor ou altura da régua como parâmetros, por exemplo.

Enquanto esta dica tem o foco no uso do ImageMagick com Linux, o ImageMagick está disponível para outras plataformas, incluindo Windows. Tente usar essas técnicas com suas ferramentas de script favorito em sua plataforma favorita.


Download

DescriçãoNomeTamanho
Script to build your own pixel rulerbuildruler.zip1KB

Recursos

Aprender

Obter produtos e tecnologias

Discutir

  • Envolva-se com a comunidade My developerWorks; com seu perfil pessoal e página inicial customizada, é possível padronizar o developerWorks para seus interesses e interagir com outros usuários do developerWorks.

Comentários

developerWorks: Conecte-se

Los campos obligatorios están marcados con un asterisco (*).


Precisa de um ID IBM?
Esqueceu seu ID IBM?


Esqueceu sua senha?
Alterar sua senha

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


A primeira vez que você entrar no developerWorks, um perfil é criado para você. Informações no seu perfil (seu nome, país / região, e nome da empresa) é apresentado ao público e vai acompanhar qualquer conteúdo que você postar, a menos que você opte por esconder o nome da empresa. Você pode atualizar sua conta IBM a qualquer momento.

Todas as informações enviadas são seguras.

Elija su nombre para mostrar



Ao se conectar ao developerWorks pela primeira vez, é criado um perfil para você e é necessário selecionar um nome de exibição. O nome de exibição acompanhará o conteúdo que você postar no developerWorks.

Escolha um nome de exibição de 3 - 31 caracteres. Seu nome de exibição deve ser exclusivo na comunidade do developerWorks e não deve ser o seu endereço de email por motivo de privacidade.

Los campos obligatorios están marcados con un asterisco (*).

(Escolha um nome de exibição de 3 - 31 caracteres.)

Ao clicar em Enviar, você concorda com os termos e condições do developerWorks.

 


Todas as informações enviadas são seguras.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=80
Zone=Linux
ArticleID=422908
ArticleTitle=Dica do Linux: Criando uma Régua de Pixels a partir da Linha de Comandos
publish-date=07232009