Esempio n. 1
0
    }

    ## GimpPlugIn virtual methods ##
    def do_query_procedures(self):
        self.set_translation_domain(
            "gimp30-python", Gio.file_new_for_path(Gimp.locale_directory()))
        return ['gradient-save-as-css']

    def do_create_procedure(self, name):
        procedure = None
        if name == 'gradient-save-as-css':
            procedure = Gimp.Procedure.new(self, name, Gimp.PDBProcType.PLUGIN,
                                           gradient_css_save, None)
            procedure.set_image_types("*")
            procedure.set_documentation(
                "Creates a new palette from a given gradient",
                "palette_from_gradient (gradient, number, segment_colors) -> None",
                name)
            procedure.set_menu_label("Save as CSS...")
            procedure.set_attribution("Joao S. O. Bueno",
                                      "(c) GPL V3.0 or later", "2011")
            procedure.add_menu_path('<Gradients>')

            procedure.add_argument_from_property(self, "run-mode")
            procedure.add_argument_from_property(self, "gradient")
            procedure.add_argument_from_property(self, "file")
        return procedure


Gimp.main(GradientsSaveAsCSS.__gtype__, sys.argv)
Esempio n. 2
0
                Gimp.PDBStatusType.CALLING_ERROR, GLib.Error(error))
        runmode = args.index(0)
        # Handle args here on a plug-in that takes them.

        # Gimp.image_list()

        # Make a new image:
        img = Gimp.image_new(400, 400, 0)

        # Make a new layer:
        layer = Gimp.layer_new(img, "newlayer", Gimp.image_width(img),
                               Gimp.image_height(img),
                               Gimp.ImageType.RGBA_IMAGE, 100.0,
                               Gimp.LayerMode.NORMAL)

        # Add the layer to the image:
        Gimp.image_insert_layer(img, layer, 0, -1)

        # Fill the layer:
        Gimp.drawable_fill(layer, Gimp.FillType.PATTERN)

        # Finally, display the image:
        Gimp.display_new(img)

        retval = procedure.new_return_values(Gimp.PDBStatusType.SUCCESS,
                                             GLib.Error())
        return retval


Gimp.main(TestPlugin.__gtype__, sys.argv)
Esempio n. 3
0
            procedure.set_image_types("*")
            procedure.set_documentation('save an OpenRaster (.ora) file',
                                        'save an OpenRaster (.ora) file', name)
            procedure.set_menu_label('OpenRaster')
            procedure.set_extensions("ora")
        elif name == 'file-openraster-load':
            procedure = Gimp.LoadProcedure.new(self, name,
                                               Gimp.PDBProcType.PLUGIN,
                                               load_ora, None)
            procedure.set_menu_label('OpenRaster')
            procedure.set_documentation('load an OpenRaster (.ora) file',
                                        'load an OpenRaster (.ora) file', name)
            procedure.set_mime_types("image/openraster")
            procedure.set_extensions("ora")
            procedure.set_thumbnail_loader('file-openraster-load-thumb')
        else:  # 'file-openraster-load-thumb'
            procedure = Gimp.ThumbnailProcedure.new(self, name,
                                                    Gimp.PDBProcType.PLUGIN,
                                                    thumbnail_ora, None)
            procedure.set_documentation(
                'loads a thumbnail from an OpenRaster (.ora) file',
                'loads a thumbnail from an OpenRaster (.ora) file', name)
        procedure.set_attribution(
            'Jon Nordby',  #author
            'Jon Nordby',  #copyright
            '2009')  #year
        return procedure


Gimp.main(FileOpenRaster.__gtype__, sys.argv)
gi.require_version('Gegl', '0.4')
from gi.repository import Gegl
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gio

import gettext
import os
import sys

# Set-up localization for your plug-in with your own text domain.
# This is complementary to the gimp_plug_in_set_translation_domain()
# which is only useful for the menu entries inside GIMP interface,
# whereas the below calls are used for localization within the plug-in.
textdomain = 'gimp30-std-plug-ins'
gettext.bindtextdomain(textdomain, Gimp.locale_directory())
gettext.bind_textdomain_codeset(textdomain, 'UTF-8')
gettext.textdomain(textdomain)
_ = gettext.gettext


def N_(message):
    return message


class Goat(Gimp.PlugIn):
    ## GimpPlugIn virtual methods ##
    def do_query_procedures(self):
        # Localization for the menu entries. It has to be called in the
        # query function only.
        self.set_translation_domain(
Esempio n. 5
0
            Gegl.init(None)

            buffer = drawable.get_buffer()
            shadow_buffer = drawable.get_shadow_buffer()

            graph = Gegl.Node()
            input = graph.create_child("gegl:buffer-source")
            input.set_property("buffer", buffer)
            invert = graph.create_child("gegl:invert")
            output = graph.create_child("gegl:write-buffer")
            output.set_property("buffer", shadow_buffer)
            input.link(invert)
            invert.link(output)
            output.process()

            # This is extremely important in bindings, since we don't
            # unref buffers. If we don't explicitly flush a buffer, we
            # may left hanging forever. This step is usually done
            # during an unref().
            shadow_buffer.flush()

            drawable.merge_shadow(True)
            drawable.update(x, y, width, height)
            Gimp.displays_flush()

        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS,
                                           GLib.Error())


Gimp.main(Goat.__gtype__, sys.argv)
Esempio n. 6
0
def make_gradient(palette, num_segments, num_colors):
    gradient = Gimp.gradient_new(palette)

    if (num_segments > 1):
        Gimp.gradient_segment_range_split_uniform(gradient, 0, -1,
                                                  num_segments)

    for color_number in range(0, num_segments):
        if color_number == num_colors - 1:
            color_number_next = 0
        else:
            color_number_next = color_number + 1
        _, color_left = Gimp.palette_entry_get_color(palette, color_number)
        _, color_right = Gimp.palette_entry_get_color(palette,
                                                      color_number_next)
        Gimp.gradient_segment_set_left_color(gradient, color_number,
                                             color_left, 100.0)
        Gimp.gradient_segment_set_right_color(gradient, color_number,
                                              color_right, 100.0)
    Gimp.context_set_gradient(gradient)
    return gradient
Esempio n. 7
0
    def do_query_procedures(self):
        self.set_translation_domain(
            textdomain, Gio.file_new_for_path(Gimp.locale_directory()))

        return ["plug-in-add-balloon"]
Esempio n. 8
0
    }

    ## GimpPlugIn virtual methods ##
    def do_query_procedures(self):
        self.set_translation_domain(
            "gimp30-python", Gio.file_new_for_path(Gimp.locale_directory()))

        return ['python-fu-foggify']

    def do_create_procedure(self, name):
        procedure = Gimp.ImageProcedure.new(self, name,
                                            Gimp.PDBProcType.PLUGIN, foggify,
                                            None)
        procedure.set_image_types("RGB*, GRAY*")
        procedure.set_documentation(N_("Add a layer of fog"),
                                    "Adds a layer of fog to the image.", name)
        procedure.set_menu_label(N_("_Fog..."))
        procedure.set_attribution("James Henstridge", "James Henstridge",
                                  "1999,2007")
        procedure.add_menu_path("<Image>/Filters/Decor")

        procedure.add_argument_from_property(self, "name")
        # TODO: add support for GBoxed values.
        #procedure.add_argument_from_property(self, "color")
        procedure.add_argument_from_property(self, "turbulence")
        procedure.add_argument_from_property(self, "opacity")
        return procedure


Gimp.main(Foggify.__gtype__, sys.argv)
Esempio n. 9
0
def foggify(procedure, run_mode, image, drawable, args, data):
    name = args.index(0)
    turbulence = args.index(1)
    opacity = args.index(2)
    if run_mode == Gimp.RunMode.INTERACTIVE:
        # TODO: add a GUI. This first port works just with default
        # values.
        color = Gimp.RGB()
        color.set(240.0, 180.0, 70.0)

    Gimp.context_push()
    image.undo_group_start()

    if image.base_type() is Gimp.ImageBaseType.RGB:
        type = Gimp.ImageType.RGBA_IMAGE
    else:
        type = Gimp.ImageType.GRAYA_IMAGE
    fog = Gimp.Layer.new(image, name, drawable.width(), drawable.height(),
                         type, opacity, Gimp.LayerMode.NORMAL)
    fog.fill(Gimp.FillType.TRANSPARENT)
    image.insert_layer(fog, None, 0)

    Gimp.context_set_background(color)
    fog.edit_fill(Gimp.FillType.BACKGROUND)

    # create a layer mask for the new layer
    mask = fog.create_mask(0)
    fog.add_mask(mask)

    # add some clouds to the layer
    Gimp.get_pdb().run_procedure('plug-in-plasma', [
        GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
        GObject.Value(Gimp.Image, image),
        GObject.Value(Gimp.Drawable, mask),
        GObject.Value(GObject.TYPE_INT, int(time.time())),
        GObject.Value(GObject.TYPE_DOUBLE, turbulence),
    ])

    # apply the clouds to the layer
    fog.remove_mask(Gimp.MaskApplyMode.APPLY)
    fog.set_visible(True)
    Gimp.displays_flush()

    image.undo_group_end()
    Gimp.context_pop()

    return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS,
                                       GLib.Error())
Esempio n. 10
0
 def do_query_procedures(self):
     self.set_translation_domain("gimp30-python",
                                 Gio.file_new_for_path(Gimp.locale_directory()))
     return [ 'file-colorxhtml-save' ]
Esempio n. 11
0
def save_colorxhtml(procedure, run_mode, image, drawable, file, args, data):
    source_file = args.index(0)
    characters = args.index(1)
    size =  args.index(2)
    separate = args.index(3)

    if file is None:
        error = 'No file given'
        return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR,
                                           GLib.Error(error))

    if run_mode == Gimp.RunMode.INTERACTIVE:

        gi.require_version('Gtk', '3.0')
        from gi.repository import Gtk

        Gimp.ui_init ("colorxhtml.py")

        use_header_bar = Gtk.Settings.get_default().get_property("gtk-dialogs-use-header")
        dialog = Gtk.Dialog(use_header_bar=use_header_bar,
                            title=_("Save as colored HTML text..."))
        dialog.add_button("_Cancel", Gtk.ResponseType.CANCEL)
        dialog.add_button("_OK", Gtk.ResponseType.OK)

        choose_file_dialog = Gtk.FileChooserDialog(use_header_bar=use_header_bar,
                                       title=_("Read characters from file..."),
                                       action=Gtk.FileChooserAction.OPEN)
        choose_file_dialog.add_button("_Cancel", Gtk.ResponseType.CANCEL)
        choose_file_dialog.add_button("_OK", Gtk.ResponseType.OK)

        def choose_file(button, user_data=None):
            choose_file_dialog.show()
            if choose_file_dialog.run() == Gtk.ResponseType.OK:
                characters_entry.set_text(choose_file_dialog.get_filename())

            choose_file_dialog.hide()

        grid = Gtk.Grid()
        grid.set_column_homogeneous(False)
        grid.set_border_width(10)
        grid.set_column_spacing(10)
        grid.set_row_spacing(10)

        row = 0
        label = Gtk.Label(label=_("Characters"))
        label.set_tooltip_text(_("Characters that will be used as colored pixels. "))

        grid.attach(label, 0, row, 1 , 1)
        label.show()

        characters_entry = Gtk.Entry()
        characters_entry.set_width_chars(20)
        characters_entry.set_max_width_chars(80)
        characters_entry.set_text(characters)
        characters_entry.set_placeholder_text(_("Characters or file location"))
        grid.attach(characters_entry, 1, row, 1, 1)
        characters_entry.show()

        row += 1

        characters_checkbox = Gtk.CheckButton(label=_("Read characters from file"))
        characters_checkbox.set_active(source_file)
        characters_checkbox.set_tooltip_text(
            _("If set, the Characters text entry will be used as a file name, "
              "from which the characters will be read. Otherwise, the characters "
              "in the text entry will be used to render the image."))
        grid.attach(characters_checkbox, 0, row, 1, 1)
        characters_checkbox.show()

        choose_file_button = Gtk.Button(label=_("Choose file"))
        grid.attach(choose_file_button, 1, row, 1, 1)
        choose_file_button.connect("clicked", choose_file)
        choose_file_button.show()

        row += 1

        label = Gtk.Label(label=_("Font Size(px)"))
        grid.attach(label, 0, row, 1 , 1)
        label.show()

        font_size_adj = Gtk.Adjustment.new(size, 0.0, 100.0, 1.0, 0.0, 0.0)
        font_size_spin = Gtk.SpinButton.new(font_size_adj, climb_rate=1.0, digits=0)
        font_size_spin.set_numeric(True)
        grid.attach(font_size_spin, 1, row, 1 , 1)
        font_size_spin.show()

        row += 1

        separate_checkbox = Gtk.CheckButton(label=_("Write separate CSS file"))
        separate_checkbox.set_active(separate)
        grid.attach(separate_checkbox, 0, row, 2, 1)
        separate_checkbox.show()

        dialog.get_content_area().add(grid)
        grid.show()

        dialog.show()
        if dialog.run() == Gtk.ResponseType.OK:
            separate = separate_checkbox.get_active()
            size = font_size_spin.get_value_as_int()
            source_file = characters_checkbox.get_active()
            characters = characters_entry.get_text()
        else:
            return procedure.new_return_values(Gimp.PDBStatusType.CANCEL,
                                               GLib.Error())

    width = drawable.width()
    height = drawable.height()
    bpp = drawable.bpp()

    html = open(file.peek_path(), 'w')

    if separate:
        dirname, cssfile = os.path.split(file.peek_path())
        cssfile = os.path.splitext(cssfile)[0] + '.css'
        cssname = os.path.join(dirname, cssfile)

        css = open(cssname, 'w')

    if source_file:
        characters_file = open(characters, 'r')
        chars = characters_file.read()
        characters_file.close()
    else:
        chars = characters

    # Remove unprintable characters from "chars".
    # TODO: This only handles ascii files.  It would be nice to handle unicode
    # files, so this could work for any language.
    goodchars = string.digits + string.ascii_letters + string.punctuation
    badchars = ''.join(chr(i) for i in range(256) if chr(i) not in goodchars)
    allchars = str.maketrans('', '', badchars)
    chars = chars.translate(allchars)

    data = [escape_table.get(c, c) for c in chars]

    if data:
        data.reverse()
    else:
        data = list('X' * 80)

    Gimp.progress_init(_("Saving as colored XHTML"))

    style = style_def % size

    if separate:
        ss = '<link rel="stylesheet" type="text/css" href="%s" />' % cssfile
        css.write(style)
    else:
        ss = '<style type="text/css">\n%s</style>' % style

    html.write(preamble % ss)

    colors = {}
    chars = []

    # Constants used for formatting the pixel color. We can handle image
    # types where each color is 8 bits, 16 bits, or 32 bit integers.
    fmt = fmt_from_bpp[bpp]
    pixel_shift = 8 * (bpp//3 - 1)

    for y in range(0, height):

        # The characters in "chars" will be used to draw the next row.
        # Lets fill "chars" with data so it has at least enough characters.
        while len(chars) < width:
            chars[0:0] = data

        for x in range(0, width):
            pixel_bytes = drawable.get_pixel(x, y)
            pixel_tuple = struct.unpack(fmt, pixel_bytes)
            if bpp > 3:
                 pixel_tuple=(
                   pixel_tuple[0] >> pixel_shift,
                   pixel_tuple[1] >> pixel_shift,
                   pixel_tuple[2] >> pixel_shift,
                 )
            color = '%02x%02x%02x' % pixel_tuple
            style = 'background-color:black; color:#%s;' % color
            char = chars.pop()

            if separate:
                if color not in colors:
                    css.write('span.N%s { %s }\n' % (color, style))
                    colors[color] = 1

                html.write('<span class="N%s">%s</span>' % (color, char))

            else:
                html.write('<span style="%s">%s</span>' % (style, char))

        html.write('\n')

        Gimp.progress_update(y / float(height))

    html.write(postamble)

    html.close()
    if separate:
        css.close()

    retval = Gimp.ValueArray.new(1)
    retval.insert(0, GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS))

    return retval
Esempio n. 12
0
        self.set_translation_domain("gimp30-python",
                                    Gio.file_new_for_path(Gimp.locale_directory()))
        return [ 'file-colorxhtml-save' ]

    def do_create_procedure(self, name):
        procedure = None
        if name == 'file-colorxhtml-save':
            procedure = Gimp.SaveProcedure.new(self, name,
                                           Gimp.PDBProcType.PLUGIN,
                                           save_colorxhtml, None)
            procedure.set_image_types("RGB")
            procedure.set_documentation (
                N_("Save as colored HTML text"),
                "Saves the image as colored XHTML text (based on Perl version by Marc Lehmann)",
                name)
            procedure.set_menu_label(N_("Colored HTML text"))
            procedure.set_attribution("Manish Singh and Carol Spears",
                                      "(c) GPL V3.0 or later",
                                      "2003")

            procedure.set_extensions ("html,xhtml");

            procedure.add_argument_from_property(self, "source-file")
            procedure.add_argument_from_property(self, "characters")
            procedure.add_argument_from_property(self, "font-size")
            procedure.add_argument_from_property(self, "separate")

        return procedure

Gimp.main(ColorXhtml.__gtype__, sys.argv)
Esempio n. 13
0
def gradient_css_save(procedure, args, data):
    if args.length() != 3:
        error = 'Wrong parameters given'
        return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR,
                                           GLib.Error(error))
    runmode = args.index(0)
    gradient = args.index(1)
    file = args.index(2)

    if runmode == Gimp.RunMode.INTERACTIVE:
        # Interactive mode works on active gradient.
        gradient = Gimp.context_get_gradient()

        # Pop-up a file chooser for target file.
        gi.require_version('Gtk', '3.0')
        from gi.repository import Gtk

        Gimp.init("gradients-save-as-css.py")

        use_header_bar = Gtk.Settings.get_default().get_property(
            "gtk-dialogs-use-header")
        dialog = Gtk.FileChooserDialog(use_header_bar=use_header_bar,
                                       title=_("CSS file..."),
                                       action=Gtk.FileChooserAction.SAVE)
        dialog.add_button("_Cancel", Gtk.ResponseType.CANCEL)
        dialog.add_button("_OK", Gtk.ResponseType.OK)
        dialog.show()
        if dialog.run() == Gtk.ResponseType.OK:
            file = dialog.get_file()
        else:
            return procedure.new_return_values(Gimp.PDBStatusType.CANCEL,
                                               GLib.Error())

    if file is None:
        error = 'No file given'
        return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR,
                                           GLib.Error(error))

    stops = []
    wk_stops = []
    n_segments = Gimp.gradient_get_number_of_segments(gradient)
    last_stop = None
    for index in range(n_segments):
        success, lcolor, lopacity = Gimp.gradient_segment_get_left_color(
            gradient, index)
        success, rcolor, ropacity = Gimp.gradient_segment_get_right_color(
            gradient, index)
        success, lpos = Gimp.gradient_segment_get_left_pos(gradient, index)
        success, rpos = Gimp.gradient_segment_get_right_pos(gradient, index)

        lstop = color_to_html(lcolor) + " %d%%" % int(100 * lpos)
        wk_lstop = "color-stop(%.03f, %s)" % (lpos, color_to_html(lcolor))
        if lstop != last_stop:
            stops.append(lstop)
            wk_stops.append(wk_lstop)

        rstop = color_to_html(rcolor) + " %d%%" % int(100 * rpos)
        wk_rstop = "color-stop(%.03f, %s)" % (rpos, color_to_html(rcolor))

        stops.append(rstop)
        wk_stops.append(wk_rstop)
        last_stop = rstop

    final_text = w3c_template % ", ".join(stops)
    final_text += moz_template % ",".join(stops)
    final_text += webkit_template % ",".join(wk_stops)

    success, etag = file.replace_contents(
        bytes(format_text(final_text), encoding='utf-8'),
        etag=None,
        make_backup=False,
        flags=Gio.FileCreateFlags.REPLACE_DESTINATION,
        cancellable=None)
    if success:
        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS,
                                           GLib.Error())
    else:
        return procedure.new_return_values(
            Gimp.PDBStatusType.EXECUTION_ERROR,
            GLib.Error('File saving failed: {}'.format(file.get_path())))
Esempio n. 14
0
 def do_query_procedures(self):
     self.set_translation_domain(
         "gimp30-python", Gio.file_new_for_path(Gimp.locale_directory()))
     return ['gradient-save-as-css']
    def run(self, procedure, args, data):
        palette = None
        amount  = 1

        # Get the parameters
        if args.length() < 1:
            error = 'No parameters given'
            return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR,
                                               GLib.Error(error))
        runmode = args.index(0)

        if args.length() > 1:
            palette = args.index(1)
        if palette == '' or palette is None:
            palette = Gimp.context_get_palette()
        (exists, num_colors) = Gimp.palette_get_info(palette)
        if not exists:
            error = 'Unknown palette: {}'.format(palette)
            return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR,
                                               GLib.Error(error))

        if args.length() > 2:
            amount = args.index(2)

        if runmode == Gimp.RunMode.INTERACTIVE:
            gi.require_version('Gtk', '3.0')
            from gi.repository import Gtk

            GimpUi.init ("palette-offset.py")

            use_header_bar = Gtk.Settings.get_default().get_property("gtk-dialogs-use-header")
            dialog = GimpUi.Dialog(use_header_bar=use_header_bar,
                                 title=_("Offset Palette..."))

            dialog.add_button("_Cancel", Gtk.ResponseType.CANCEL)
            dialog.add_button("_OK", Gtk.ResponseType.OK)

            box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL,
                          homogeneous=False, spacing=12)
            dialog.get_content_area().add(box)
            box.show()

            label = Gtk.Label.new_with_mnemonic("Off_set")
            box.pack_start(label, False, False, 1)
            label.show()

            amount = self.set_property("amount", amount)
            spin = GimpUi.prop_spin_button_new(self, "amount", 1.0, 5.0, 0)
            spin.set_activates_default(True)
            box.pack_end(spin, False, False, 1)
            spin.show()

            dialog.show()
            if dialog.run() != Gtk.ResponseType.OK:
                return procedure.new_return_values(Gimp.PDBStatusType.CANCEL,
                                                   GLib.Error())
            amount = self.get_property("amount")

        #If palette is read only, work on a copy:
        editable = Gimp.palette_is_editable(palette)
        if not editable:
            palette = Gimp.palette_duplicate (palette)

        tmp_entry_array = []
        for i in range (num_colors):
            tmp_entry_array.append  ((Gimp.palette_entry_get_name (palette, i)[1],
                                      Gimp.palette_entry_get_color (palette, i)[1]))
        for i in range (num_colors):
            target_index = i + amount
            if target_index >= num_colors:
                target_index -= num_colors
            elif target_index < 0:
                target_index += num_colors
            Gimp.palette_entry_set_name (palette, target_index, tmp_entry_array[i][0])
            Gimp.palette_entry_set_color (palette, target_index, tmp_entry_array[i][1])

        retval = procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
        value = GObject.Value(GObject.TYPE_STRING, palette)
        retval.remove(1)
        retval.insert(1, value)
        return retval
Esempio n. 16
0
                                                pyslice, None)
            procedure.set_image_types("*");
            # table snippet means a small piece of HTML code here
            procedure.set_documentation (N_("Cuts an image along its guides, creates images and a HTML table snippet"),
                                         """Add guides to an image. Then run this. It will cut along the guides,
                                         and give you the html to reassemble the resulting images. If you
                                         choose to generate javascript for onmouseover and clicked events, it
                                         will use the lower three visible layers on the image for normal,
                                         onmouseover and clicked states, in that order. If skip caps is
                                         enabled, table cells on the edge of the table won't become animated,
                                         and its images will be taken from the active layer.""",
                                         name)
            procedure.set_menu_label(_("_Slice..."))
            procedure.set_attribution("Manish Singh",
                                      "Manish Singh",
                                      "2003")
            procedure.add_menu_path ("<Image>/Filters/Web")

            procedure.add_argument_from_property(self, "save-path")
            procedure.add_argument_from_property(self, "html-filename")
            procedure.add_argument_from_property(self, "image-basename")
            procedure.add_argument_from_property(self, "image-extension")
            procedure.add_argument_from_property(self, "separate-image-dir")
            procedure.add_argument_from_property(self, "relative-image-path")
            procedure.add_argument_from_property(self, "cellspacing")
            procedure.add_argument_from_property(self, "animate")
            procedure.add_argument_from_property(self, "skip-caps")
        return procedure

Gimp.main(PySlice.__gtype__, sys.argv)
Esempio n. 17
0
            procedure.set_menu_label(_("Palette to _Gradient"))
            procedure.set_documentation(
                _("Create a gradient using colors from the palette"),
                _("Create a new gradient using colors from the palette."), "")
        elif name == 'python-fu-palette-to-gradient-repeating':
            procedure.set_menu_label(_("Palette to _Repeating Gradient"))
            procedure.set_documentation(
                _("Create a repeating gradient using colors from the palette"),
                _("Create a new repeating gradient using colors from the palette."
                  ), "")
        else:
            procedure = None

        if procedure is not None:
            procedure.set_attribution(
                "Carol Spears, reproduced from previous work by Adrian Likins and Jeff Trefftz",
                "Carol Spears", "2006")
            # We don't build a GParamSpec ourselves because passing it
            # around is apparently broken in Python. Hence this trick.
            # See pygobject#227
            procedure.add_argument_from_property(self, "run-mode")
            procedure.add_argument_from_property(self, "palette")
            procedure.add_return_value_from_property(self, "new-gradient")

            procedure.add_menu_path('<Palettes>')

        return procedure


Gimp.main(PaletteToGradient.__gtype__, sys.argv)
Esempio n. 18
0
def pyslice(procedure, run_mode, image, drawable, args, data):
    save_path       = args.index(0)
    html_filename   = args.index(1)
    image_basename  = args.index(2)
    image_extension = args.index(3)
    separate        = args.index(4)
    image_path      = args.index(5)
    cellspacing     = args.index(6)
    animate         = args.index(7)
    skip_caps       = args.index(8)

    cellspacing = int (cellspacing)

    if animate:
        count = 0
        drw = []
        #image.layers is a reversed list of the layers on the image
        #so, count indexes from number of layers to 0.
        for i in xrange (len (image.layers) -1, -1, -1):
            if image.layers[i].visible:
                drw.append(image.layers[i])
                count += 1
                if count == 3:
                    break


    vert, horz = get_guides(image)

    if len(vert) == 0 and len(horz) == 0:
        return

    Gimp.progress_init(_("Slice"))
    progress_increment = 1 / ((len(horz) + 1) * (len(vert) + 1))
    progress = 0.0

    def check_path(path):
        path = os.path.abspath(path)

        if not os.path.exists(path):
            os.mkdir(path)

        return path

    save_path = check_path(save_path)

    if not os.path.isdir(save_path):
        save_path = os.path.dirname(save_path)

    if separate:
        image_relative_path = image_path
        if not image_relative_path.endswith("/"):
            image_relative_path += "/"
        image_path = check_path(os.path.join(save_path, image_path))
    else:
        image_relative_path = ''
        image_path = save_path

    tw = TableWriter(os.path.join(save_path, html_filename),
                     cellspacing=cellspacing, animate=animate)

    top = 0

    for i in range(0, len(horz) + 1):
        if i == len(horz):
            bottom = image.height()
        else:
            bottom = image.get_guide_position(horz[i])

        tw.row_start()

        left = 0

        for j in range(0, len(vert) + 1):
            if j == len(vert):
                right = image.width()
            else:
                right = image.get_guide_position(vert[j])
            if (skip_caps   and
                 (
                   (len(horz) >= 2 and (i == 0 or i == len(horz) )) or
                   (len(vert) >= 2 and (j == 0 or j == len(vert) ))
                 )
               ):
                skip_stub = True
            else:
                skip_stub = False

            if (not animate or skip_stub):
                src = (image_relative_path +
                       slice (image, None, image_path,
                              image_basename, image_extension,
                              left, right, top, bottom, i, j, ""))
            else:
                src = []
                for layer, postfix in zip (drw, ("", "hover", "clicked")):
                    src.append (image_relative_path +
                                slice(image, layer, image_path,
                                      image_basename, image_extension,
                                      left, right, top, bottom, i, j, postfix))

            tw.cell(src, right - left, bottom - top, i, j, skip_stub)

            left = right + cellspacing

            progress += progress_increment
            Gimp.progress_update(progress)

        tw.row_end()

        top = bottom + cellspacing

    tw.close()
    return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
Esempio n. 19
0
gi.require_version('Gimp', '3.0')
from gi.repository import Gimp
gi.require_version('GimpUi', '3.0')
from gi.repository import GimpUi
gi.require_version('Gegl', '0.4')
from gi.repository import Gegl
from gi.repository import GObject
from gi.repository import GLib
from gi.repository import Gio

import gettext
import os
import sys

textdomain = 'gimp30-std-plug-ins'
gettext.bindtextdomain(textdomain, Gimp.locale_directory())
# gettext.bind_textdomain_codeset(textdomain, 'UTF-8')
gettext.textdomain(textdomain)
_ = gettext.gettext


def N_(message):
    return message


class AddBalloon(Gimp.PlugIn):
    def do_query_procedures(self):
        self.set_translation_domain(
            textdomain, Gio.file_new_for_path(Gimp.locale_directory()))

        return ["plug-in-add-balloon"]
Esempio n. 20
0
    def do_query_procedures(self):
        self.set_translation_domain("gimp30-python",
                                    Gio.file_new_for_path(Gimp.locale_directory()))

        return [ 'python-fu-slice' ]
Esempio n. 21
0
    def run(self, procedure, run_mode, image, n_drawables, drawables, args,
            run_data):
        if n_drawables != 1:
            msg = _(
                f"Procedure '{procedure.get_name()}' only works with one drawable."
            )
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(), msg, 0)
            return procedure.new_return_values(
                Gimp.PDBStatusType.CALLING_ERROR, error)
        else:
            drawable = drawables[0]

        # check if selection exist
        selection = image.get_selection()
        flag, non_empty, x1, y1, x2, y2 = selection.bounds(image)
        if not non_empty:
            msg = _(
                f"The selection is empty, create a selection box and precede with the use of this plugin."
            )
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(), msg, 0)
            return procedure.new_return_values(
                Gimp.PDBStatusType.CALLING_ERROR, error)

        if run_mode == Gimp.RunMode.INTERACTIVE:
            gi.require_version('Gtk', '3.0')
            from gi.repository import Gtk
            gi.require_version('Gdk', '3.0')
            from gi.repository import Gdk

            GimpUi.init("add_balloon.py")

            dialog = GimpUi.Dialog(use_header_bar=True,
                                   title=_("Add Balloon)"),
                                   role="add_balloon-Python3")
            dialog.add_button(_("_Cancel"), Gtk.ResponseType.CANCEL)
            dialog.add_button(_("_OK"), Gtk.ResponseType.OK)

            geometry = Gdk.Geometry()
            geometry.min_aspect = 0.5
            geometry.max_aspect = 1.0
            dialog.set_geometry_hints(None, geometry, Gdk.WindowHints.ASPECT)

            box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
            dialog.get_content_area().add(box)
            box.show()

            # Label text content
            label = Gtk.Label(label='Text:')
            box.pack_start(label, False, False, 1)
            label.show()

            # scroll area for text
            scrolled = Gtk.ScrolledWindow()
            scrolled.set_vexpand(True)
            box.pack_start(scrolled, True, True, 1)
            scrolled.show()

            # text content box
            text_content = Gtk.TextView()
            contents = 'text'
            buffer = text_content.get_buffer()
            buffer.set_text(contents, -1)
            scrolled.add(text_content)
            text_content.show()

            # Improve UI
            font_chooser = Gtk.FontChooserWidget()
            box.pack_start(font_chooser, False, False, 1)
            font_chooser.show()

            # TODO add spinner for waiting

            while (True):
                response = dialog.run()
                if response == Gtk.ResponseType.OK:
                    # TODO enable spinner and lock all other values

                    # layer position
                    position = Gimp.get_pdb().run_procedure(
                        'gimp-image-get-item-position',
                        [image, drawable]).index(1)
                    # Create group
                    layer_group = Gimp.get_pdb().run_procedure(
                        'gimp-layer-group-new', [image]).index(1)
                    image.insert_layer(layer_group, None, position)

                    # add new trasparent layer
                    overlay_layer = Gimp.Layer.new(image, 'hide_background',
                                                   drawable.get_width(),
                                                   drawable.get_height(),
                                                   Gimp.ImageType.RGBA_IMAGE,
                                                   100.0,
                                                   Gimp.LayerMode.NORMAL)
                    image.insert_layer(overlay_layer, layer_group, position)
                    overlay_layer.fill(Gimp.FillType.TRANSPARENT)

                    # add white fill the selection
                    Gimp.get_pdb().run_procedure(
                        'gimp-drawable-edit-fill',
                        [overlay_layer, Gimp.FillType.WHITE])

                    # add text layer
                    buffer = text_content.get_buffer()
                    text = buffer.get_text(buffer.get_start_iter(),
                                           buffer.get_end_iter(), True)

                    font_str = font_chooser.get_font()
                    font_size = float(font_str.split(' ')[-1])
                    font_name = ' '.join(font_str.split(' ')[0:-2])

                    text_layer = Gimp.get_pdb().run_procedure(
                        'gimp-text-layer-new',
                        [image, text, font_name, font_size, 3]).index(1)
                    image.insert_layer(text_layer, layer_group, position - 1)

                    # center text layer
                    Gimp.get_pdb().run_procedure(
                        'gimp-text-layer-set-justification', [text_layer, 2])
                    cx = (x1 + x2) / 2 - text_layer.get_width() / 2
                    cy = (y1 + y2) / 2 - text_layer.get_height() / 2
                    Gimp.get_pdb().run_procedure(
                        'gimp-item-transform-translate', [text_layer, cx, cy])

                    # set selected layer
                    image.set_selected_layers([layer_group])

                    dialog.destroy()
                    break
                else:
                    dialog.destroy()
                    return procedure.new_return_values(
                        Gimp.PDBStatusType.CANCEL, GLib.Error())

        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS,
                                           GLib.Error())
Esempio n. 22
0
    def run_mode(self, runmode):
        self.runmode = runmode

    ## GimpPlugIn virtual methods ##
    def do_query_procedures(self):
        # Localization
        self.set_translation_domain ("gimp30-python",
                                     Gio.file_new_for_path(Gimp.locale_directory()))

        return [ PROC_NAME ]

    def do_create_procedure(self, name):
        if name == PROC_NAME:
            procedure = Gimp.Procedure.new(self, name,
                                           Gimp.PDBProcType.PLUGIN,
                                           run, None)
            procedure.set_menu_label(N_("Python _Console"))
            procedure.set_documentation(N_("Interactive GIMP Python interpreter"),
                                        "Type in commands and see results",
                                        "")
            procedure.set_attribution("James Henstridge",
                                      "James Henstridge",
                                      "1997-1999")
            procedure.add_argument_from_property(self, "run-mode")
            procedure.add_menu_path ("<Image>/Filters/Development/Python-Fu")

            return procedure
        return None

Gimp.main(PythonConsole.__gtype__, sys.argv)
Esempio n. 23
0
def load_ora(procedure, run_mode, file, args, data):
    tempdir = tempfile.mkdtemp('gimp-plugin-file-openraster')
    orafile = zipfile.ZipFile(file.peek_path())
    stack, w, h = get_image_attributes(orafile)

    img = Gimp.Image.new(w, h, Gimp.ImageBaseType.RGB)
    img.set_filename(file.peek_path())

    def get_layers(root):
        """iterates over layers and nested stacks"""
        for item in root:
            if item.tag == 'layer':
                yield item
            elif item.tag == 'stack':
                yield item
                for subitem in get_layers(item):
                    yield subitem
                yield NESTED_STACK_END

    parent_groups = []

    layer_no = 0
    for item in get_layers(stack):

        if item is NESTED_STACK_END:
            parent_groups.pop()
            continue

        if item.tag == 'stack':
            name, x, y, opac, visible, layer_mode = get_group_layer_attributes(
                item)
            gimp_layer = img.layer_group_new()

        else:
            path, name, x, y, opac, visible, layer_mode = get_layer_attributes(
                item)

            if not path.lower().endswith('.png'):
                continue
            if not name:
                # use the filename without extension as name
                n = os.path.basename(path)
                name = os.path.splitext(n)[0]

            # create temp file. Needed because gimp cannot load files from inside a zip file
            tmp = os.path.join(tempdir, 'tmp.png')
            with open(tmp, 'wb') as fid:
                try:
                    data = orafile.read(path)
                except KeyError:
                    # support for bad zip files (saved by old versions of this plugin)
                    data = orafile.read(path.encode('utf-8'))
                    print(
                        'WARNING: bad OpenRaster ZIP file. There is an utf-8 encoded filename that does not have the utf-8 flag set:',
                        repr(path))
                fid.write(data)

            # import layer, set attributes and add to image
            gimp_layer = Gimp.get_pdb().run_procedure('gimp-file-load-layer', [
                GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
                GObject.Value(Gimp.Image, img),
                GObject.Value(GObject.TYPE_STRING, tmp),
            ])
            gimp_layer = gimp_layer.index(1)
            gimp_layer = Gimp.Item.get_by_id(gimp_layer)
            os.remove(tmp)
        gimp_layer.set_name(name)
        gimp_layer.set_mode(layer_mode)
        gimp_layer.set_offsets(x, y)  # move to correct position
        gimp_layer.set_opacity(opac * 100)  # a float between 0 and 100
        gimp_layer.set_visible(visible)

        img.insert_layer(gimp_layer,
                         parent_groups[-1][0] if parent_groups else None,
                         parent_groups[-1][1] if parent_groups else layer_no)
        if parent_groups:
            parent_groups[-1][1] += 1
        else:
            layer_no += 1

        if gimp_layer.is_group():
            parent_groups.append([gimp_layer, 0])

    os.rmdir(tempdir)

    return Gimp.ValueArray.new_from_values([
        GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS),
        GObject.Value(Gimp.Image, img),
    ])
Esempio n. 24
0
 def __init__(self, quit_func=None):
     banner = ('GIMP %s Python Console\nPython %s\n' %
               (Gimp.version(), sys.version))
     pyconsole.Console.__init__(self,
                                locals=namespace, banner=banner,
                                quit_func=quit_func)
Esempio n. 25
0
    def run(self, procedure, run_mode, image, drawable, args, run_data):
        if run_mode == Gimp.RunMode.INTERACTIVE:
            gi.require_version('Gtk', '3.0')
            from gi.repository import Gtk
            gi.require_version('Gdk', '3.0')
            from gi.repository import Gdk

            GimpUi.ui_init("palette-offset.py")

            dialog = GimpUi.Dialog(use_header_bar=True,
                                   title=_("Exercise a goat (Python 3)"),
                                   role="goat-exercise-Python3")

            dialog.add_button("_Cancel", Gtk.ResponseType.CANCEL)
            dialog.add_button("_Source", Gtk.ResponseType.APPLY)
            dialog.add_button("_OK", Gtk.ResponseType.OK)

            geometry = Gdk.Geometry()
            geometry.min_aspect = 0.5
            geometry.max_aspect = 1.0
            dialog.set_geometry_hints(None, geometry, Gdk.WindowHints.ASPECT)

            box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=2)
            dialog.get_content_area().add(box)
            box.show()

            # XXX We use printf-style string for sharing the localized
            # string. You may just use recommended Python format() or
            # any style you like in your plug-ins.
            head_text = ("This plug-in is an exercise in '%s' to "
                         "demo plug-in creation.\nCheck out the last "
                         "version of the source code online by clicking "
                         "the \"Source\" button." % ("Python 3"))
            label = Gtk.Label(label=head_text)
            box.pack_start(label, False, False, 1)
            label.show()

            contents = None
            # Get the file contents Python-style instead of using
            # GLib.file_get_contents() which returns bytes result, and
            # when converting to string, get newlines as text contents.
            # Rather than wasting time to figure this out, use Python
            # core API!
            with open(os.path.realpath(__file__), 'r') as f:
                contents = f.read()

            if contents is not None:
                scrolled = Gtk.ScrolledWindow()
                scrolled.set_vexpand(True)
                box.pack_start(scrolled, True, True, 1)
                scrolled.show()

                view = Gtk.TextView()
                view.set_wrap_mode(Gtk.WrapMode.WORD)
                view.set_editable(False)
                buffer = view.get_buffer()
                buffer.set_text(contents, -1)
                scrolled.add(view)
                view.show()

            while (True):
                response = dialog.run()
                if response == Gtk.ResponseType.OK:
                    dialog.destroy()
                    break
                elif response == Gtk.ResponseType.APPLY:
                    url = "https://gitlab.gnome.org/GNOME/gimp/-/blob/master/plug-ins/goat-exercises/goat-exercise-py3.py"
                    Gio.app_info_launch_default_for_uri(url, None)
                    continue
                else:
                    dialog.destroy()
                    return procedure.new_return_values(
                        Gimp.PDBStatusType.CANCEL, GLib.Error())

        intersect, x, y, width, height = drawable.mask_intersect()
        if intersect:
            Gegl.init(None)

            buffer = drawable.get_buffer()
            shadow_buffer = drawable.get_shadow_buffer()

            graph = Gegl.Node()
            input = graph.create_child("gegl:buffer-source")
            input.set_property("buffer", buffer)
            invert = graph.create_child("gegl:invert")
            output = graph.create_child("gegl:write-buffer")
            output.set_property("buffer", shadow_buffer)
            input.link(invert)
            invert.link(output)
            output.process()

            # This is extremely important in bindings, since we don't
            # unref buffers. If we don't explicitly flush a buffer, we
            # may left hanging forever. This step is usually done
            # during an unref().
            shadow_buffer.flush()

            drawable.merge_shadow(True)
            drawable.update(x, y, width, height)
            Gimp.displays_flush()

        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS,
                                           GLib.Error())
Esempio n. 26
0
 def _commit(self):
     pyconsole.Console._commit(self)
     Gimp.displays_flush()
Esempio n. 27
0
    def do_query_procedures(self):
        # Localization
        self.set_translation_domain(
            "gimp30-python", Gio.file_new_for_path(Gimp.locale_directory()))

        return ["python-fu-gi-test"]
            if dialog.run() != Gtk.ResponseType.OK:
                return procedure.new_return_values(Gimp.PDBStatusType.CANCEL,
                                                   GLib.Error())
            amount = self.get_property("amount")

        #If palette is read only, work on a copy:
        editable = Gimp.palette_is_editable(palette)
        if not editable:
            palette = Gimp.palette_duplicate (palette)

        tmp_entry_array = []
        for i in range (num_colors):
            tmp_entry_array.append  ((Gimp.palette_entry_get_name (palette, i)[1],
                                      Gimp.palette_entry_get_color (palette, i)[1]))
        for i in range (num_colors):
            target_index = i + amount
            if target_index >= num_colors:
                target_index -= num_colors
            elif target_index < 0:
                target_index += num_colors
            Gimp.palette_entry_set_name (palette, target_index, tmp_entry_array[i][0])
            Gimp.palette_entry_set_color (palette, target_index, tmp_entry_array[i][1])

        retval = procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())
        value = GObject.Value(GObject.TYPE_STRING, palette)
        retval.remove(1)
        retval.insert(1, value)
        return retval

Gimp.main(PaletteOffset.__gtype__, sys.argv)
Esempio n. 29
0
def save_ora(procedure, run_mode, image, n_drawables, drawables, file, args,
             data):
    def write_file_str(zfile, fname, data):
        # work around a permission bug in the zipfile library:
        # http://bugs.python.org/issue3394
        zi = zipfile.ZipInfo(fname)
        zi.external_attr = int("100644", 8) << 16
        zfile.writestr(zi, data)

    Gimp.progress_init("Exporting openraster image")
    tempdir = tempfile.mkdtemp('gimp-plugin-file-openraster')

    # use .tmpsave extension, so we don't overwrite a valid file if
    # there is an exception
    orafile = zipfile.ZipFile(file.peek_path() + '.tmpsave',
                              'w',
                              compression=zipfile.ZIP_STORED)

    write_file_str(orafile, 'mimetype',
                   'image/openraster')  # must be the first file written

    # build image attributes
    xml_image = ET.Element('image')
    stack = ET.SubElement(xml_image, 'stack')
    a = xml_image.attrib
    a['w'] = str(image.get_width())
    a['h'] = str(image.get_height())

    def store_layer(image, drawable, path):
        tmp = os.path.join(tempdir, 'tmp.png')
        interlace, compression = 0, 2

        Gimp.get_pdb().run_procedure(
            'file-png-save',
            [
                GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
                GObject.Value(Gimp.Image, image),
                GObject.Value(GObject.TYPE_INT, 1),
                GObject.Value(
                    Gimp.ObjectArray,
                    Gimp.ObjectArray.new(Gimp.Drawable, [drawable], False)),
                GObject.Value(Gio.File, Gio.File.new_for_path(tmp)),
                GObject.Value(GObject.TYPE_BOOLEAN, interlace),
                GObject.Value(GObject.TYPE_INT, compression),
                # write all PNG chunks except oFFs(ets)
                GObject.Value(GObject.TYPE_BOOLEAN,
                              True),  # Save background color (bKGD chunk)
                GObject.Value(GObject.TYPE_BOOLEAN,
                              False),  # Save layer offset (oFFs chunk)
                GObject.Value(GObject.TYPE_BOOLEAN,
                              True),  # Save resolution (pHYs chunk)
                GObject.Value(GObject.TYPE_BOOLEAN,
                              True),  # Save creation time (tIME chunk)
                # Other settings
                GObject.Value(
                    GObject.TYPE_BOOLEAN,
                    True),  # Save color values from transparent pixels
            ])
        if (os.path.exists(tmp)):
            orafile.write(tmp, path)
            os.remove(tmp)
        else:
            print("Error removing ", tmp)

    def add_layer(parent, x, y, opac, gimp_layer, path, visible=True):
        store_layer(image, gimp_layer, path)
        # create layer attributes
        layer = ET.Element('layer')
        parent.append(layer)
        a = layer.attrib
        a['src'] = path
        a['name'] = gimp_layer.get_name()
        a['x'] = str(x)
        a['y'] = str(y)
        a['opacity'] = str(opac)
        a['visibility'] = 'visible' if visible else 'hidden'
        a['composite-op'] = gimp_layermodes_map.get(gimp_layer.get_mode(),
                                                    'svg:src-over')
        return layer

    def add_group_layer(parent, opac, gimp_layer, visible=True):
        # create layer attributes
        group_layer = ET.Element('stack')
        parent.append(group_layer)
        a = group_layer.attrib
        a['name'] = gimp_layer.get_name()
        a['opacity'] = str(opac)
        a['visibility'] = 'visible' if visible else 'hidden'
        a['composite-op'] = gimp_layermodes_map.get(gimp_layer.get_mode(),
                                                    'svg:src-over')
        return group_layer

    def enumerate_layers(layers):
        for layer in layers:
            if not layer.is_group():
                yield layer
            else:
                yield layer
                for sublayer in enumerate_layers(layer.get_children()):
                    yield sublayer
                yield NESTED_STACK_END

    # save layers
    parent_groups = []
    i = 0

    layer_stack = image.get_layers()
    # Number of top level layers for tracking progress
    lay_cnt = len(layer_stack)

    for lay in enumerate_layers(layer_stack):
        prev_lay = i
        if lay is NESTED_STACK_END:
            parent_groups.pop()
            continue
        _, x, y = lay.get_offsets()
        opac = lay.get_opacity() / 100.0  # needs to be between 0.0 and 1.0

        if not parent_groups:
            path_name = 'data/{:03d}.png'.format(i)
            i += 1
        else:
            path_name = 'data/{}-{:03d}.png'.format(parent_groups[-1][1],
                                                    parent_groups[-1][2])
            parent_groups[-1][2] += 1

        parent = stack if not parent_groups else parent_groups[-1][0]

        if lay.is_group():
            group = add_group_layer(parent, opac, lay, lay.get_visible())
            group_path = ("{:03d}".format(i)
                          if not parent_groups else parent_groups[-1][1] +
                          "-{:03d}".format(parent_groups[-1][2]))
            parent_groups.append([group, group_path, 0])
        else:
            add_layer(parent, x, y, opac, lay, path_name, lay.get_visible())

        if (i > prev_lay):
            Gimp.progress_update(i / lay_cnt)

    # save mergedimage
    thumb = image.duplicate()
    thumb_layer = thumb.merge_visible_layers(Gimp.MergeType.CLIP_TO_IMAGE)
    store_layer(thumb, thumb_layer, 'mergedimage.png')

    # save thumbnail
    w, h = image.get_width(), image.get_height()
    if max(w, h) > 256:
        # should be at most 256x256, without changing aspect ratio
        if w > h:
            w, h = 256, max(h * 256 / w, 1)
        else:
            w, h = max(w * 256 / h, 1), 256
        thumb_layer.scale(w, h, False)
    if thumb.get_precision() != Gimp.Precision.U8_GAMMA:
        thumb.convert_precision(Gimp.Precision.U8_GAMMA)
    store_layer(thumb, thumb_layer, 'Thumbnails/thumbnail.png')
    thumb.delete()

    # write stack.xml
    xml = ET.tostring(xml_image, encoding='UTF-8')
    write_file_str(orafile, 'stack.xml', xml)

    # finish up
    orafile.close()
    os.rmdir(tempdir)
    if os.path.exists(file.peek_path()):
        os.remove(file.peek_path())  # win32 needs that
    os.rename(file.peek_path() + '.tmpsave', file.peek_path())

    Gimp.progress_end()

    return Gimp.ValueArray.new_from_values(
        [GObject.Value(Gimp.PDBStatusType, Gimp.PDBStatusType.SUCCESS)])
Esempio n. 30
0
def foggify(procedure, run_mode, image, n_drawables, drawables, args, data):
    config = procedure.create_config()
    config.begin_run(image, run_mode, args)

    if run_mode == Gimp.RunMode.INTERACTIVE:
        GimpUi.init('python-fu-foggify')
        dialog = GimpUi.ProcedureDialog(procedure=procedure, config=config)
        dialog.get_color_widget('color', True, GimpUi.ColorAreaType.FLAT)
        dialog.fill(None)
        if not dialog.run():
            dialog.destroy()
            config.end_run(Gimp.PDBStatusType.CANCEL)
            return procedure.new_return_values(Gimp.PDBStatusType.CANCEL, GLib.Error())
        else:
            dialog.destroy()

    color      = config.get_property('color')
    name       = config.get_property('name')
    turbulence = config.get_property('turbulence')
    opacity    = config.get_property('opacity')

    Gimp.context_push()
    image.undo_group_start()

    if image.get_base_type() is Gimp.ImageBaseType.RGB:
        type = Gimp.ImageType.RGBA_IMAGE
    else:
        type = Gimp.ImageType.GRAYA_IMAGE
    for drawable in drawables:
        fog = Gimp.Layer.new(image, name,
                             drawable.get_width(), drawable.get_height(),
                             type, opacity,
                             Gimp.LayerMode.NORMAL)
        fog.fill(Gimp.FillType.TRANSPARENT)
        image.insert_layer(fog, drawable.get_parent(),
                           image.get_item_position(drawable))

        Gimp.context_set_background(color)
        fog.edit_fill(Gimp.FillType.BACKGROUND)

        # create a layer mask for the new layer
        mask = fog.create_mask(0)
        fog.add_mask(mask)

        # add some clouds to the layer
        Gimp.get_pdb().run_procedure('plug-in-plasma', [
            GObject.Value(Gimp.RunMode, Gimp.RunMode.NONINTERACTIVE),
            GObject.Value(Gimp.Image, image),
            GObject.Value(Gimp.Drawable, mask),
            GObject.Value(GObject.TYPE_INT, int(time.time())),
            GObject.Value(GObject.TYPE_DOUBLE, turbulence),
        ])

        # apply the clouds to the layer
        fog.remove_mask(Gimp.MaskApplyMode.APPLY)
        fog.set_visible(True)

    Gimp.displays_flush()

    image.undo_group_end()
    Gimp.context_pop()

    config.end_run(Gimp.PDBStatusType.SUCCESS)

    return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())