RMagick – Usando camadas

fundo

A imagem abaixo foi criada inteiramente a partir de código escrito em Ruby ( https://github.com/troylelandshields/bigAcalendar ) com a ajuda de RMagick. RMagick é uma interface incrível em Ruby para ImageMagick.

Cenário

RMagick tem a capacidade de escrever texto em uma imagem criando um objeto de ‘desenho’ e usando o método de anotação.

Em geral, é muito fácil colocar programaticamente o texto onde você quiser, mas no meu calendário Big A eu precisava colocar o texto branco exatamente no meio dos pontos pretos. Calcular o pixel exato para colocar o texto com anotação parecia que seria uma dor de cabeça maior do que eu gostaria de lidar (especialmente porque eu poderia querer alterar o tamanho do texto, etc).

Criar uma subimagem

Minha solução foi muito simples: criar uma pequena imagem na qual eu pudesse centralizar o círculo e a data e, em seguida, adicionar no local correto do calendário.

O método a seguir cria uma pequena imagem com o gráfico circular no qual desejo colocar a data.

def createDateLabelBg 
@date_lbl_bg = Image.new(@size, @size){
self.background_color = 'transparent'
}

#This is the bigger, all-black circle that makes the black stroke
cir
= Draw.new
cir
.fill = @date_lbl_bg_color.to_s
cir
.circle(@date_lbl_bg.rows/2, @date_lbl_bg.columns/2,
2, @date_lbl_bg.columns/2)
cir
.draw(@date_lbl_bg)

cir
= Draw.new
cir
.fill='black'
cir
.stroke('white')
cir
.stroke_width(12).
cir
.circle(@date_lbl_bg.rows/2, @date_lbl_bg.columns/2,
24, @date_lbl_bg.columns/2)

cir
.draw(@date_lbl_bg)
end

Posteriormente, posso escrever a data exatamente no meio deste círculo, sem a necessidade de calcular qualquer posicionamento complicado (observe a longa lista de 0s na chamada do método de anotação):

date_lbl_bg = createDateLabelBg

date_lbl
= Draw.new
date_lbl
.gravity = CenterGravity
date_lbl
.pointsize = @lbl_size - 90
date_lbl
.fill = @date_color.to_s

#Just use 0's and it's centered perfectly!
date_lbl
.annotate(date_lbl_bg, 0, 0, 0, 0, date.to_s)

Isso também vem com a vantagem de que meu círculo e data estão agora perfeitamente ligados, e eu sou livre para colocá-los onde eu quiser como uma unidade.

Eu uso um método semelhante para colocar as letras que marcam os dias da semana porque quero que seja fácil manter essa letra centralizada nas colunas do calendário, em vez de colocá-la em um lugar específico da página.

Crie uma imagem de base

Depois de ter suas subimagens projetadas da maneira que desejar, você pode colocá-las em cima de uma imagem base onde quiser.

Crie uma imagem de base com o tamanho da imagem final desejada e adicione-a a um novo objeto ImageList.

baseImg = Image.new(14850, 10800){self.background_color = 'white'}
imgList
= ImageList.new
imgList
.push(baseImg)

Combine as Imagens

Adicione todas as suas outras imagens à sua nova ImageList. Cada imagem nesta está em sua própria camada e tem uma posição em algum lugar na imagem base. Especifique onde deseja que a imagem seja colocada com o atributo ‘página’ da imagem.

img.page = Rectangle.new(width, height, xPos, yPos) #x & y are relative to upper left corner

Finalmente, achatar e escrever a imagem para obter uma imagem agradável com tudo na posição desejada.

final = imgList.flatten_images
final.write("final.png")