{ "metadata": { "name": "" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "[Python para Desenvolvedores](http://ricardoduarte.github.io/python-para-desenvolvedores/#conteudo)\n", "===================================\n", "2ª edi\u00e7\u00e3o, revisada e ampliada\n", "-----------------------------------\n", "\n", "Ap\u00eandice C: GIMP\n", "=============================\n", "_____________________________\n", "[GIMP](http://www.gimp.org/) (GNU Image Manipulation Program) \u00e9 um software de c\u00f3digo aberto bastante conhecido, que implementa v\u00e1rias ferramentas para processamento e edi\u00e7\u00e3o de imagens *raster* (com alguns recursos vetoriais, para lidar com texto, por exemplo), al\u00e9m de algoritmos de convers\u00e3o para diversos formatos. Permite a manipula\u00e7\u00e3o de imagens compostas de m\u00faltiplas camadas e possui uma arquitetura baseada em *plugins* que permite implementar novas funcionalidades.\n", "\n", "Originalmente, os *plugins* eram criados na linguagem funcional Scheme, por\u00e9m hoje \u00e9 poss\u00edvel usar Python tamb\u00e9m, atrav\u00e9s de uma extens\u00e3o chamada [Gimp-Python](http://www.gimp.org/docs/python/index.html).\n", "\n", "Um *plugin* feito em Python deve seguir os seguintes passos:\n", "\n", "+ Importar *gimpfu*: o m\u00f3dulo *gimpfu* define as fun\u00e7\u00f5es e tipos necess\u00e1rios para o Python + possa se comunicar com o GIMP.\n", "+ Definir fun\u00e7\u00e3o de processamento: a fun\u00e7\u00e3o que ser\u00e1 utilizada para processar a imagem, usando a API do GIMP.\n", "+ Registrar a fun\u00e7\u00e3o: a fun\u00e7\u00e3o `register()` cadastra a fun\u00e7\u00e3o de processamento na *Procedural Database* (PDB), permitindo que o GIMP conhe\u00e7a as informa\u00e7\u00f5es necess\u00e1rias para executar o *plugin*.\n", "+ Executar `main()`: rotina principal da API.\n", "\n", "A fun\u00e7\u00e3o de processamento ter\u00e1 realizar alguns passos para poder interagir corretamente com o GIMP:\n", "\n", "+ Receber vari\u00e1veis: a fun\u00e7\u00e3o recebe como argumentos a imagem (*image*), a camada corrente em edi\u00e7\u00e3o (*drawable*) e outros que forem definidos no registro da fun\u00e7\u00e3o. Os outros par\u00e2metros ser\u00e3o obtidos atrav\u00e9s de uma caixa de dialogo apresentada ao usu\u00e1rio antes da execu\u00e7\u00e3o.\n", "+ Iniciar transa\u00e7\u00e3o: inicio da transa\u00e7\u00e3o atrav\u00e9s da fun\u00e7\u00e3o `pdb.gimp_image_undo_group_start()`. A transa\u00e7\u00e3o pode ser desfeita posteriormente atrav\u00e9s de *undo*.\n", "+ Processar imagem: altera a imagem ou a camada atrav\u00e9s das fun\u00e7\u00f5es definidas na API.\n", "+ Terminar transa\u00e7\u00e3o: encerra a transa\u00e7\u00e3o atrav\u00e9s da fun\u00e7\u00e3o `pdb.gimp_image_undo_group_end()`.\n", "\n", "Com isso, o processamento realizado pelo *plugin* ter\u00e1 um comportamento conforme com outras funcionalidades presentes no software, incluindo a capacidade de ter a opera\u00e7\u00e3o desfeita (*undo*).\n", "\n", "Exemplo:" ] }, { "cell_type": "code", "collapsed": false, "input": [ "# Importa a interface para o GIMP\n", "from gimpfu import *\n", "\n", "def stonify(img, drawable, fracture=135, picture=135):\n", " \"\"\"\"\"\"\n", " # Inicia a transa\u00e7\u00e3o para UNDO\n", " pdb.gimp_image_undo_group_start(img)\n", " \n", " # Cria uma camada de lava\n", " pdb.script_fu_lava(img, drawable, 10, 10, 7,\n", " 'German flag smooth', 1, 1, 0)\n", " lava = img.layers[0]\n", " w, h = img.width, img.height\n", " \n", " # Cria uma camada de ru\u00eddo\n", " rock = gimp.Layer(img, 'Rock', w, h, RGB_IMAGE,\n", " 100, MULTIPLY_MODE)\n", " pdb.gimp_image_add_layer(img, rock, 0)\n", " pdb.plug_in_solid_noise(img, rock, 0, 0, 0, 1, 4, 4)\n", " \n", " # Aplica relevo nas camadas\n", " pdb.plug_in_bump_map(img, rock, lava,\n", " fracture, 45, 15, 0, 0, 0, 0, 1, 0, 0)\n", " pdb.plug_in_bump_map(img, rock, drawable,\n", " picture, 45, 30, 0, 0, 0, 0, 1, 0, 0)\n", " lava.visible = 0\n", " \n", " # Combina as camadas da imagem em uma s\u00f3\n", " img.flatten()\n", " pdb.gimp_brightness_contrast (img.layers[0], 30, 10)\n", " \n", " # Termina a transa\u00e7\u00e3o\n", " pdb.gimp_image_undo_group_end(img)\n", "\n", "# Registra a fun\u00e7\u00e3o na PDB\n", "register(\n", " # Identifica\u00e7\u00e3o\n", " 'Stonify',\n", " '\"Stonify\" the image...',\n", " '\"Stonify\" the image with some noise',\n", " 'Luiz Eduardo Borges',\n", " 'Luiz Eduardo Borges',\n", " '2008-2010',\n", " # Localiza\u00e7\u00e3o no menu\n", " '/Filters/Render/Stonify...',\n", " # Modos suportados (todos) \n", " '*',\n", " # Par\u00e2metros\n", " [\n", " (PF_INT, 'fracture', 'Fracture power', 135),\n", " (PF_INT, 'picture', 'Picture power', 135)\n", " ],\n", " # Resultados\n", " [],\n", " stonify)\n", "\n", "# Executa o plugin\n", "main()" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Janela de op\u00e7\u00f5es:\n", "\n", "![Gimp](files/gimp1.png)\n", "\n", "Exemplo dos passos para a gera\u00e7\u00e3o da imagem:\n", "\n", "![Diagrama Gimp](files/bpypd_diags38.png)\n", "\n", "O GIMP tamb\u00e9m permite que os plugins sejam executados atrav\u00e9s de linha de comando, usando os par\u00e2metros `--no-interface --batch`.\n", "\n", "O *script* precisa estar numa pasta em que o GIMP possa encontr\u00e1-lo. Para o GIMP 2.6, a pasta de *plugins* do usu\u00e1rio fica em `.gimp-2.6/plug-ins` abaixo do diret\u00f3rio `home` do usu\u00e1rio. Al\u00e9m disso, a extens\u00e3o requer que PyGTK e suas depend\u00eancias estejam instaladas." ] }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [ { "html": [ "\n", "" ], "output_type": "pyout", "prompt_number": 1, "text": [ "" ] } ], "prompt_number": 1 } ], "metadata": {} } ] }