zoukankan      html  css  js  c++  java
  • [翻译]如何编写GIMP插件(一)

    近期想尝试编写gimp插件,在gimp官网看到了三篇简明教程,顺便翻译了下,由于本人英文,计算机知识有限,文中难免有warning,error出现,欢迎指正。

    《How to write a GIMP plug-in》

    原文:http://developer.gimp.org/writing-a-plug-in/1/index.html

    作者:Dave Neary

    在这篇文章中,我将介绍GIMP插件基础和libgimp库的API。并且演示如何使用PDB使其他脚本作者获得我们的插件

    介绍

    新的开发者经常会被GIMP的大小和声誉所吓到,他们认为编写一个插件会是一个困难的任务,本系列文章的目标就是要消除这种感觉,展示如何简单的编写C插件

    在这部分,我将介绍插件的基本元素。我们将看到如何去安装一个插件、从图片中获取数据并且直接进行操作

    结构

    GIMP脚本接口集中在程序数据库中(PDB)。在程序启动的时候,GIMP在预先定义的位置去寻找插件和脚本,并且要求每个新脚本去识别自身。

    插件在这个时候向PDB声明它自己,并且通过信息来确定自己在菜单中的层次结构,输入参数,输出参数。

    当一个脚本或插件想要使用我们的插件,它会通过PDB获取,PDB通过透明的方式管理着参数通信的方向。

    要接触插件的内部功能必须先打包在核心内,将会注册到PDB。第二点,这个功能才能在libgimp里正常执行。

    这些就是介绍,现在,我们将会看见一个更接近我们第一个插件的东东——“Hello world!”

    编译插件

    为了编译简单的GIMP插件,你需要libgimp头文件,以及相关的工具——gimptool

    使用这个工具,你可以安装插件到用户目录(~/.gimp-2.0/plug-ins),或是全局插件的目录

    语法是:

    gimptool-2.0 --install plugin.c or gimptool-2.0 --install-admin plugin.c

    使用这个工具的其它选项,还可以进行脚本的安装和卸载插件

    行为

    一个gimp插件典型行为可以分为3种。(1)它可以获取图像数据,修改并返回修改后的图像,比如边缘检测。(2)它可以生成图像并返回生成的图像,像script-fus脚本或是jpeg文件读取插件。(3)或者它能获取图像,处理它而不是修改它的数据,像文件保存插件。

    要点

    #include <libgimp/gimp.h>

    这个头文件可以使我们获取所有基本插件所需的元素

    GimpPlugInInfo PLUG_IN_INFO = {
        init,
        quit,
        query,
        run
    };

    这个结构体正如它的名字一样,它包含四个函数指针,它们将会在插件的生存期内被调用,init和quit是可选的,因此我们可以为他们设置空值(NULL),但是其余的两个函数,query和run,是强制性的

    GIMP启动的时侯会调用init()函数,这个函数并不是典型的插件必须函数,一些插件使用它来进行二次搜索,这并不是由内核来执行的,这个函数没有被标准的gimp插件使用,不过,在某个文件存在的境况下,一个插件去注册一些步骤会更有用。
    quit()函数也不常被使用,当GIMP即将被关闭的时候会被调用,在script-fu插件中被用来释放资源

    query()函数当插件启动运行?时被第一次调用,并且每次当插件改变时被调用

    run()函数是插件的中心,当插件运行时被调用,它获取插件的名称(一个插件可以注册几个程序),输入参数,一个指向输出参数的指针,然后决定是交互方式还是脚本方式去开始,然后完成所有插件的处理,它的原型是:

    void run (  const gchar *name,
                gint nparams,
                const GimpParam *param,
                gint *nreturn_vals,
                GimpParam **return_vals);

    MAIN()

    MAIN是一个C的宏,它拥有一点黑暗魔法去初始化参数。它也调用适当的PLUG_IN_INFO函数,这取决于时间,你的插件需要它。

    query()函数

    query()函数处理程序登记和输入的参数定义。这些信息保存起来用于加速程序启动的时间,并且只有在插件被修改后会刷新
    我们的“Hello world!”插件的query函数如下所示:

    static void
    query (void)
    {
        static GimpParamDef args[] =
        {
            {
                GIMP_PDB_INT32,
                "run-mode",
                "Run mode"
            },
            {
                GIMP_PDB_IMAGE,
                "image",
                "Input image"
            },
            {
                GIMP_PDB_DRAWABLE,
                "drawable",
                "Input drawable"
            }
        };
     
        gimp_install_procedure (
            "plug-in-hello",
            "Hello, world!",
            "Displays "Hello, world!" in a dialog",
            "David Neary",
            "Copyright David Neary",
            "2004",
            "_Hello world...",
            "RGB*, GRAY*",
            GIMP_PLUGIN,
            G_N_ELEMENTS (args), 0,
            args, NULL);
     
        gimp_plugin_menu_register ("plug-in-hello",
                                   "/Filters/Misc");
    }

    GimpParamDef包含三个数据——参数类型,参数名,一个描述参数的字符串

    gimp_install_procedure声明了程序名,一些描述和帮助字符串,插件所在菜单路径,插件处理的图像类型,在结尾,输入输出参数的个数,以及参数的描述符。

    “RGB*, GRAY*” 声明了处理图像的类型。它可以是RGB,INDEXED或是GRAY,透明或是不透明。所以”RGB*, GRAY*”用于描述RGB,RGBA,GRAY图像类型

    GIMP_PLUGIN声明这个是外部程序,不在GIMP内核中执行。

    为了添加一个存根,我们运行函数,我们可以检验我们的插件具有必不可少的元素,可以测试它已经在PDB中为自己注册。使用”Xtns->Plug-in Details”插件。

     

    Plug-in details

    Our plug-in is in the menus

    run() 函数

    另一个请求PLUG_IN_INFO的函数是run。插件的核心就在这里。

    输出值(原型中的返回值)必须拥有至少一个相关的值,典型的就是插件的状态,这个参数值如”GIMP_PDB_SUCCESS”

    运行模式

    我们可以通过不同方式的运行插件,可以在GIMP运行时在菜单交互运行,或是脚本或批处理,或者通过“滤镜 – 重复上次操作”快捷方式。

    “run_mode”输入的参数可以是以下三个中的一个”GIMP_RUN_INTERACTIVE”,”GIMP_RUN_NONINTERACTIVE”或是”GIMP_RUN_WITH_LAST_VALS”

    “GIMP_RUN_INTERACTIVE”是典型的仅有的可以创建选项对话框的选项。否则,直接进行处理输入的参数或是内存中的参数。

    为了我们的测试插件,我们使用一个简单的显示“Hello world!”的对话框,幸运的,这个使用GTK+实现非常的简单,我们的run函数如下:

    static void
    run (const gchar *name,
         gint nparams,
         const GimpParam *param,
         gint *nreturn_vals,
         GimpParam **return_vals)
    {
        static GimpParam values[1];
        GimpPDBStatusType status = GIMP_PDB_SUCCESS;
        GimpRunMode run_mode;
     
        /* Setting mandatory output values */
        *nreturn_vals = 1;
        *return_vals = values;
     
        values[0].type = GIMP_PDB_STATUS;
        values[0].data.d_status = status;
     
        /* Getting run_mode - we won't display a dialog if
        * we are in NONINTERACTIVE mode */
        run_mode = param[0].data.d_int32;
     
        if (run_mode != GIMP_RUN_NONINTERACTIVE)
            g_message("Hello, world!
    ");
    }

    现在,当我们运行我们的插件,有如下动作:

    可以点击查看完整的hello.c插件代码

    下一部分

    在下一部分我们将继续,制作一个更有用的插件,能够自己获取图像数据,我们将会看到如何使用GIMP图像结构,使插件工作的更好,一点点的处理图像。

  • 相关阅读:
    一些用位运算解决的方法
    代码之美中的二分搜索算法Java版
    Connection listeners: accepting TCP connections 翻译
    Android网络编程1
    HelloWorldForU 九度Online Judge
    Ubuntu下设置默认java
    分享一个libevent server——cliserver
    编程原则
    hive迁移hadoop namenode时遇到的问题
    python for语句
  • 原文地址:https://www.cnblogs.com/ishell/p/4240172.html
Copyright © 2011-2022 走看看