quarta-feira, 21 de janeiro de 2015

Como criar um PNG com marca d'água e texto dinâmico

A necessidade: Criar uma ferramenta para upload de uma imagem e gerar uma saída com uma marca d'água e um texto dinâmico. Saída era esperada em PNG para melhor renderização no Facebook.

Pra isso, você vai precisar de:
  • PIL==1.1.7
  • django-easy-thumbnails-watermark==0.6.7

Crie uma classe no models.py para tal:
class Visita(models.Model):
 """(Visita description)"""
 data = models.DateField(auto_now_add=True)
 linha1 = models.CharField(max_length=255)
 linha2 = models.CharField(max_length=255, null=True, blank=True,)
 imagem = models.ImageField(upload_to="uploads/visitas/imagem/%Y",help_text="800x671")

 class Meta:
  verbose_name, verbose_name_plural = u"Visita à Fábrica" , u"Visitas à Fábrica"
  ordering = ('-data',)

 def __unicode__(self):
  return u"%s" % self.data


 def gerar(self):
  return 'Gerar' % self.id
 gerar.allow_tags = True
 gerar.is_safe = True

Aqui criei um modelo que tem uma data, por questão de organização, duas linhas para texto que serão inseridas na imagem e a imagem em si.

No urls.py, crie uma entrada para chamada da view:
url(r'^visitas/(?P\d+)/$', 'imagens_facebook.views.visitas', name="visitas"),

E da view abaixo:
def visitas(request, vid):
 img_obj = get_object_or_404(Visita, id=vid)
 img = '{0}/{1}'.format(settings.MEDIA_ROOT, img_obj.imagem)
 IMAGE = Image.open('{0}/{1}'.format(settings.MEDIA_ROOT, img_obj.imagem))
 WM = {
  'image':'{0}/site/img/visita.png'.format(settings.STATIC_PATH,),
  'position': 'BL',
  'opacity': 1,
  'scale': 1,
  'tile': False,
  'greyscale': False,
  'rotation': 0,
 }
 WK_DONE = watermark_processor(IMAGE, WM )
 path = '{0}/watermarks/visitas/{1}'.format(settings.MEDIA_ROOT, 'imagem.png')
 WK_DONE.save(path, "PNG")
 img = Image.open('{0}/watermarks/visitas/{1}'.format(settings.MEDIA_ROOT, 'imagem.png'))
 draw = ImageDraw.Draw(img)
 font = ImageFont.truetype("{0}/fonts/trebuc.ttf".format(settings.STATIC_PATH),20)
 draw.text((60, 465), img_obj.linha1.upper() ,(55,185,115),font=font)
 if img_obj.linha2:
  draw.text((60, 490), img_obj.linha2.upper() ,(55,185,115),font=font)
 img.save('{0}/watermarks/visitas/{1}'.format(settings.MEDIA_ROOT, 'imagem.png'))
 return force_download(request, path)

Linha a linha temos:

  1. Definição da View "visitas" que recebe o request e o id da visita, identificado por "vid"
  2. Obtenção do objeto visita com o id informado
  3. Definição do caminho de onde está a imagem que foi feita upload
  4. Abertura da imagem como objeto da Classe Image
  5. Definição da WaterMark com o parâmetros necessários:
    1. caminho da marca d'agua
    2. Posição que será inserida, BL para bottom left
    3. Opacidade =1 para não ter transparencia, do contrario coloque valores entre 0 e 1.
    4. Escala 1 para não alterar o tamanho
    5. Tile é falso para não esticar imagem utilizada como marca d'agua em toda a imagem definida no upload.
    6. Escala de cinza falso para sair colorido
    7. Sem rotação para sair em orientação normal.
  6. Criação da imagem com marca d'agua utilizando o watermark_processor
  7. Definição de onde será gerado o arquivo
  8. Ação de salvar para gerar o arquivo em png
  9. A partir desta linha é onde será escrito o texto dinamico. Aqui abrimos a imagem gerada no passo anterior.
  10. Criação de um objeto draw da classe ImageDraw.
  11. Definição da fonte a ser utilizada. Aqui será necessário copiar o arquivo da fonte para seu projeto.
  12. A escrita do texto proprimente dita com os respectivos parâmetros: posição(left, top), texto a ser inserido, cor em RGB e caminho da font definida no passo anterior
  13. Apenas um if para testar se há uma segunda linha no texto.
  14. Se houver repete a mesma ação do passo 12, passando o texto diferente.
  15. Ação de salvar a imagem para gerar o arquivo físico.
  16. View para forçar o download do arquivo gerado. Esta view pode ser vista aqui: http://djangoweb.blogspot.com.br/2011/10/forcando-download-de-arquivos-no-django.html

hasta!


Nenhum comentário:

Postar um comentário