A maior rede de estudos do Brasil

Grátis
360 pág.
python-para-desenvolvedores

Pré-visualização | Página 39 de 47

Originalmente, os plugins eram criados na linguagem funcional Scheme, 
porém hoje é possível usar Python também, através de uma extensão 
chamada Gimp-Python96.
Um plugin feito em Python deve seguir os seguintes passos:
▪ Importar gimpfu: o módulo gimpfu define as funções e tipos 
necessários para o Python possa se comunicar com o GIMP.
▪ Definir função de processamento: a função que será utilizada para 
processar a imagem, usando a API do GIMP.
▪ Registrar a função: a função register() cadastra a função de 
processamento na Procedural Database (PDB), permitindo que o GIMP 
conheça as informações necessárias para executar o plugin.
▪ Executar main(): rotina principal da API.
A função de processamento terá realizar alguns passos para poder interagir 
corretamente com o GIMP:
▪ Receber variáveis: a função recebe como argumentos a imagem (image), 
a camada corrente em edição (drawable) e outros que forem definidos 
no registro da função. Os outros parâmetros serão obtidos através de 
uma caixa de dialogo apresentada ao usuário antes da execução.
▪ Iniciar transação: inicio da transação através da função 
pdb.gimp_image_undo_group_start(). A transação pode ser desfeita 
posteriormente através de undo.
▪ Processar imagem: altera a imagem ou a camada através das funções 
definidas na API.
95 Site oficial: http://www.gimp.org/ .
96 Documentação disponível em: http://www.gimp.org/docs/python/index.html.
304 GIMP
▪ Terminar transação: encerra a transação através da função 
pdb.gimp_image_undo_group_end().
Com isso, o processamento realizado pelo plugin terá um comportamento 
conforme com outras funcionalidades presentes no software, incluindo a 
capacidade de ter a operação desfeita (undo).
Exemplo:
# -*- coding: latin1 -*-
# Importa a interface para o GIMP
from gimpfu import *
def stonify(img, drawable, fracture=135, picture=135):
 """"""
 # Inicia a transação para UNDO
 pdb.gimp_image_undo_group_start(img)
 
 # Cria uma camada de lava
 pdb.script_fu_lava(img, drawable, 10, 10, 7,
 'German flag smooth', 1, 1, 0)
 lava = img.layers[0]
 w, h = img.width, img.height
 
 # Cria uma camada de ruído
 rock = gimp.Layer(img, 'Rock', w, h, RGB_IMAGE,
 100, MULTIPLY_MODE)
 pdb.gimp_image_add_layer(img, rock, 0)
 pdb.plug_in_solid_noise(img, rock, 0, 0, 0, 1, 4, 4)
 
 # Aplica relevo nas camadas
 pdb.plug_in_bump_map(img, rock, lava,
 fracture, 45, 15, 0, 0, 0, 0, 1, 0, 0)
 pdb.plug_in_bump_map(img, rock, drawable,
 picture, 45, 30, 0, 0, 0, 0, 1, 0, 0)
 lava.visible = 0
 
 # Combina as camadas da imagem em uma só
 img.flatten()
 pdb.gimp_brightness_contrast (img.layers[0], 30, 10)
 
 # Termina a transação
 pdb.gimp_image_undo_group_end(img)
GIMP 305
# Registra a função na PDB
register(
 # Identificação
 'Stonify',
 '"Stonify" the image...',
 '"Stonify" the image with some noise',
 'Luiz Eduardo Borges',
 'Luiz Eduardo Borges',
 '2008-2010',
 # Localização no menu
 '<Image>/Filters/Render/Stonify...',
 # Modos suportados (todos) 
 '*',
 # Parâmetros
 [
 (PF_INT, 'fracture', 'Fracture power', 135),
 (PF_INT, 'picture', 'Picture power', 135)
 ],
 # Resultados
 [],
 stonify)
# Executa o plugin
main()
Janela de opções:
Exemplo dos passos para a geração da imagem:
306 GIMP
O GIMP também permite que os plugins sejam executados através de linha de 
comando, usando os parâmetros “--no-interface --batch”.
O script precisa estar numa pasta em que o GIMP possa encontra-lo. Para o 
GIMP 2.6, a pasta de plugins do usuário fica em .gimp-2.6/plug-ins abaixo do 
diretório home do usuário. Além disso, a extensão requer que PyGTK e suas 
dependências estejam instaladas.
Relevo Relevo
Ruído
Lava
Combina
Inkscape 307
Inkscape
O editor de imagens vetoriais Inkscape97 permite o uso do Python como 
linguagem script, para a criação de extensões. O aplicativo utiliza o SVG como 
formato nativo e implementa vários recursos previstos no padrão.
As extensões para o Inkscape servem principalmente para a implementação 
de filtros e efeitos. Enquanto outros aplicativos (como o Blender) apresentam 
uma API na forma de módulos para o interpretador, o Inkscape passa 
argumentos pela linha de comando e transfere informações pela entrada e 
saída padrão do sistema operacional, de forma similar aos utilitários de 
tratamento de texto encontrados em sistemas UNIX. Com isso, a extensão tem 
acesso apenas aos elementos que fazem parte do documento, e não a interface 
gráfica do aplicativo. Qualquer interação com o usuário durante a execução 
fica por conta da extensão.
A criação e manipulação das estruturas de dados é feita usando XML, como 
prevê a especificação do formato SVG, permitindo com isso o uso de módulos 
como o ElementTree.
Para simplificar o processo, o Inkscape provê o módulo chamado inkex, que 
define estruturas básicas para extensões. Com esse módulo, novas extensões 
podem ser criadas por herança a partir de uma classe chamada Effect.
Exemplo (randomtext.py):
#! /usr/bin/env python
# -*- coding: latin1 -*-
import random
import inkex
import simplestyle
class RandomText(inkex.Effect):
 """
 Repete um texto aleatoriamente dentro de uma área.
97 Site oficial: http://www.inkscape.org/.
308 Inkscape
 """
 def __init__(self):
 # Evoca a inicialização da superclasse
 inkex.Effect.__init__(self)
 # Adiciona um parâmetro para ser recebido do Inkscape
 self.OptionParser.add_option('-t', '--texto',
 action = 'store', type = 'string',
 dest = 'texto', default = 'Python',
 help = 'Texto para ser randomizado')
 self.OptionParser.add_option('-q', '--quantidade',
 action='store', type='int',
 dest='quantidade', default=20,
 help='Quantidade de vezes que o texto irá aparecer')
 self.OptionParser.add_option('-l', '--largura',
 action='store', type='int',
 dest='largura', default=1000,
 help='Largura da área')
 self.OptionParser.add_option('-c', '--altura',
 action='store', type='int',
 dest='altura', default=1000,
 help='Altura da área')
 def effect(self):
 # Pega as variáveis que foram passadas como
 # opções de linha de comando pelo Inkscape
 texto = self.options.texto
 quantidade = self.options.quantidade
 largura = self.options.largura
 altura = self.options.altura
 # Raiz do SVG
 svg = self.document.getroot()
 # Altura e largura do documento
 doc_largura = inkex.unittouu(svg.attrib['width'])
 doc_altura = inkex.unittouu(svg.attrib['height'])
 # Cria uma camada no documento
 camada = inkex.etree.SubElement(svg, 'g')
 camada.set(inkex.addNS('label', 'inkscape'), 'randomtext')
 camada.set(inkex.addNS('groupmode', 'inkscape'), 'camada')
Inkscape 309
 for i in xrange(quantidade):
 # Cria um elemento para o texto
 xmltexto = inkex.etree.Element(inkex.addNS('text','svg'))
 xmltexto.text = texto
 # Posiciona o elemento no documento
 x = random.randint(0, largura) + (doc_largura - largura) / 2
 xmltexto.set('x', str(x))
 y = random.randint(0, altura) + (doc_altura - altura) / 2
 xmltexto.set('y', str(y))
 # Centraliza na vertical e na horizontal
 # e muda a cor de preenchimento usando CSS
 c = random.randint(100, 255)
 style = {'text-align' : 'center',