It is currently Sat Jul 06, 2024 8:48 pm


All times are UTC - 5 hours [ DST ]



Post new topic Reply to topic  [ 11 posts ] 
Author Message
 Post subject: I need help with a Python script
PostPosted: Tue Apr 17, 2012 5:58 am  (#1) 
Offline
GimpChat Member
User avatar

Joined: May 16, 2010
Posts: 14709
Location: USA
This script works great in Gimp-2.6 but doesn't show in the menus for Gimp-2.7.
I am wondering if someone could tell me how to fix the script so it will work in Gimp-2.7?

# GIMPFU START #############################################
import string as _string
import math
import gimp
import gimpcolor
from gimpenums import *
pdb = gimp.pdb

import gettext
t = gettext.translation('gimp20-python', gimp.locale_directory, fallback=True)
_ = t.ugettext

class error(RuntimeError): pass
class CancelError(RuntimeError): pass

PF_INT8        = PDB_INT8
PF_INT16       = PDB_INT16
PF_INT32       = PDB_INT32
PF_INT         = PF_INT32
PF_FLOAT       = PDB_FLOAT
PF_STRING      = PDB_STRING
PF_VALUE       = PF_STRING
#PF_INT8ARRAY   = PDB_INT8ARRAY
#PF_INT16ARRAY  = PDB_INT16ARRAY
#PF_INT32ARRAY  = PDB_INT32ARRAY
#PF_INTARRAY    = PF_INT32ARRAY
#PF_FLOATARRAY  = PDB_FLOATARRAY
#PF_STRINGARRAY = PDB_STRINGARRAY
PF_COLOR       = PDB_COLOR
PF_COLOUR      = PF_COLOR
PF_REGION      = PDB_REGION
PF_DISPLAY     = PDB_DISPLAY
PF_IMAGE       = PDB_IMAGE
PF_LAYER       = PDB_LAYER
PF_CHANNEL     = PDB_CHANNEL
PF_DRAWABLE    = PDB_DRAWABLE
PF_VECTORS     = PDB_VECTORS
#PF_SELECTION   = PDB_SELECTION
#PF_BOUNDARY    = PDB_BOUNDARY
#PF_PATH        = PDB_PATH
#PF_STATUS      = PDB_STATUS

PF_TOGGLE      = 1000
PF_BOOL        = PF_TOGGLE
PF_SLIDER      = 1001
PF_SPINNER     = 1002
PF_ADJUSTMENT  = PF_SPINNER

PF_FONT        = 1003
PF_FILE        = 1004
PF_BRUSH       = 1005
PF_PATTERN     = 1006
PF_GRADIENT    = 1007
PF_RADIO       = 1008
PF_TEXT        = 1009
PF_PALETTE     = 1010
PF_FILENAME    = 1011
PF_DIRNAME     = 1012
PF_OPTION      = 1013

_type_mapping = {
    PF_INT8        : PDB_INT8,
    PF_INT16       : PDB_INT16,
    PF_INT32       : PDB_INT32,
    PF_FLOAT       : PDB_FLOAT,
    PF_STRING      : PDB_STRING,
    #PF_INT8ARRAY   : PDB_INT8ARRAY,
    #PF_INT16ARRAY  : PDB_INT16ARRAY,
    #PF_INT32ARRAY  : PDB_INT32ARRAY,
    #PF_FLOATARRAY  : PDB_FLOATARRAY,
    #PF_STRINGARRAY : PDB_STRINGARRAY,
    PF_COLOR       : PDB_COLOR,
    PF_REGION      : PDB_REGION,
    PF_DISPLAY     : PDB_DISPLAY,
    PF_IMAGE       : PDB_IMAGE,
    PF_LAYER       : PDB_LAYER,
    PF_CHANNEL     : PDB_CHANNEL,
    PF_DRAWABLE    : PDB_DRAWABLE,
    PF_VECTORS     : PDB_VECTORS,

    PF_TOGGLE      : PDB_INT32,
    PF_SLIDER      : PDB_FLOAT,
    PF_SPINNER     : PDB_INT32,

    PF_FONT        : PDB_STRING,
    PF_FILE        : PDB_STRING,
    PF_BRUSH       : PDB_STRING,
    PF_PATTERN     : PDB_STRING,
    PF_GRADIENT    : PDB_STRING,
    PF_RADIO       : PDB_STRING,
    PF_TEXT        : PDB_STRING,
    PF_PALETTE     : PDB_STRING,
    PF_FILENAME    : PDB_STRING,
    PF_DIRNAME     : PDB_STRING,
    PF_OPTION      : PDB_INT32,
}

_obj_mapping = {
    PF_INT8        : int,
    PF_INT16       : int,
    PF_INT32       : int,
    PF_FLOAT       : float,
    PF_STRING      : str,
    #PF_INT8ARRAY   : list,
    #PF_INT16ARRAY  : list,
    #PF_INT32ARRAY  : list,
    #PF_FLOATARRAY  : list,
    #PF_STRINGARRAY : list,
    PF_COLOR       : gimpcolor.RGB,
    PF_REGION      : int,
    PF_DISPLAY     : gimp.Display,
    PF_IMAGE       : gimp.Image,
    PF_LAYER       : gimp.Layer,
    PF_CHANNEL     : gimp.Channel,
    PF_DRAWABLE    : gimp.Drawable,
    PF_VECTORS     : gimp.Vectors,

    PF_TOGGLE      : bool,
    PF_SLIDER      : float,
    PF_SPINNER     : int,

    PF_FONT        : str,
    PF_FILE        : str,
    PF_BRUSH       : str,
    PF_PATTERN     : str,
    PF_GRADIENT    : str,
    PF_RADIO       : str,
    PF_TEXT        : str,
    PF_PALETTE     : str,
    PF_FILENAME    : str,
    PF_DIRNAME     : str,
    PF_OPTION      : int,
}

_registered_plugins_ = {}

def register(proc_name, blurb, help, author, copyright, date, label,
             imagetypes, params, results, function,
             menu=None, domain=None, on_query=None, on_run=None):
    '''This is called to register a new plug-in.'''

    # First perform some sanity checks on the data
    def letterCheck(str):
        allowed = _string.letters + _string.digits + '_' + '-'
        for ch in str:
            if not ch in allowed:
                return 0
            else:
                return 1

    if not letterCheck(proc_name):
        raise error, "procedure name contains illegal characters"

    for ent in params:
        if len(ent) < 4:
            raise error, ("parameter definition must contain at least 4 "
                          "elements (%s given: %s)" % (len(ent), ent))

        if type(ent[0]) != int:
            raise error, "parameter types must be integers"

        if not letterCheck(ent[1]):
            raise error, "parameter name contains illegal characters"

    for ent in results:
        if len(ent) < 3:
            raise error, ("result definition must contain at least 3 elements "
                          "(%s given: %s)" % (len(ent), ent))

        if type(ent[0]) != type(42):
            raise error, "result types must be integers"

        if not letterCheck(ent[1]):
            raise error, "result name contains illegal characters"

    plugin_type = PLUGIN

    if (not proc_name[:7] == 'python-' and
        not proc_name[:7] == 'python_' and
        not proc_name[:10] == 'extension-' and
        not proc_name[:10] == 'extension_' and
        not proc_name[:8] == 'plug-in-' and
        not proc_name[:8] == 'plug_in_' and
        not proc_name[:5] == 'file-' and
        not proc_name[:5] == 'file_'):
           proc_name = 'python-fu-' + proc_name

    # if menu is not given, derive it from label
    need_compat_params = False
    if menu is None and label:
        fields = label.split('/')
        if fields:
            label = fields.pop()
            menu = '/'.join(fields)
            need_compat_params = True

        if need_compat_params and plugin_type == PLUGIN:
            file_params = [(PDB_STRING, "filename", "The name of the file", ""),
                           (PDB_STRING, "raw-filename", "The name of the file", "")]

            if menu is None:
                pass
            elif menu[:6] == '<Load>':
                params[0:0] = file_params
            elif menu[:7] == '<Image>' or menu[:6] == '<Save>':
                params.insert(0, (PDB_IMAGE, "image", "Input image", None))
                params.insert(1, (PDB_DRAWABLE, "drawable", "Input drawable", None))
                if menu[:6] == '<Save>':
                    params[2:2] = file_params

    _registered_plugins_[proc_name] = (blurb, help, author, copyright,
                                       date, label, imagetypes,
                                       plugin_type, params, results,
                                       function, menu, domain,
                                       on_query, on_run)

def _query():
    for plugin in _registered_plugins_.keys():
        (blurb, help, author, copyright, date,
         label, imagetypes, plugin_type,
         params, results, function, menu, domain,
         on_query, on_run) = _registered_plugins_[plugin]

        def make_params(params):
            return [(_type_mapping[x[0]],
                     x[1],
                     _string.replace(x[2], "_", "")) for x in params]

        params = make_params(params)
        # add the run mode argument ...
        params.insert(0, (PDB_INT32, "run-mode",
                                     "Interactive, Non-Interactive"))

        results = make_params(results)

        if domain:
            try:
                (domain, locale_dir) = domain
                gimp.domain_register(domain, locale_dir)
            except ValueError:
                gimp.domain_register(domain)

        gimp.install_procedure(plugin, blurb, help, author, copyright,
                               date, label, imagetypes, plugin_type,
                               params, results)

        if menu:
            gimp.menu_register(plugin, menu)
        if on_query:
            on_query()

def _get_defaults(proc_name):
    import gimpshelf
    (blurb, help, author, copyright, date,
     label, imagetypes, plugin_type,
     params, results, function, menu, domain,
     on_query, on_run) = _registered_plugins_[proc_name]

    key = "python-fu-save--" + proc_name

    if gimpshelf.shelf.has_key(key):
        return gimpshelf.shelf[key]
    else:
        # return the default values
        return [x[3] for x in params]

def _set_defaults(proc_name, defaults):
    import gimpshelf

    key = "python-fu-save--" + proc_name
    gimpshelf.shelf[key] = defaults

def _run(proc_name, params):
    run_mode = params[0]
    func = _registered_plugins_[proc_name][10]

    if run_mode == RUN_NONINTERACTIVE:
        return apply(func, params[1:])

    script_params = _registered_plugins_[proc_name][8]

    min_args = 0
    if len(params) > 1:
        for i in range(1, len(params)):
            param_type = _obj_mapping[script_params[i - 1][0]]
            if not isinstance(params[i], param_type):
                break

        min_args = i

    if len(script_params) > min_args:
        start_params = params[:min_args + 1]

        if run_mode == RUN_WITH_LAST_VALS:
            default_params = _get_defaults(proc_name)
            params = start_params + default_params[min_args:]
        else:
            params = start_params
    else:
       run_mode = RUN_NONINTERACTIVE

    if run_mode == RUN_INTERACTIVE:
        try:
            res = _interact(proc_name, params[1:])
        except CancelError:
            return
    else:
        res = apply(func, params[1:])

    gimp.displays_flush()

    return res

def main():
    '''This should be called after registering the plug-in.'''
    gimp.main(None, None, _query, _run)

def fail(msg):
    '''Display and error message and quit'''
    gimp.message(msg)
    raise error, msg

def N_(message):
    return message
# GIMPFU END ###############################################

#-----------------------------------------------------------
# This is a hack for gimpfu._interact function.
# This is to accomodate custom widget placement and functinality
#
# [... Hoppefully some more advanced programmer will teach me how
# to override imported function rather than pasting the hole module here.
# ...]

def _interact(proc_name, start_params):
    (blurb, help, author, copyright, date,
     label, imagetypes, plugin_type,
     params, results, function, menu, domain,
     on_query, on_run) = _registered_plugins_[proc_name]

    def run_script(run_params):
        params = start_params + tuple(run_params)
        _set_defaults(proc_name, params)
        return apply(function, params)

    params = params[len(start_params):]

    # short circuit for no parameters ...
    if len(params) == 0:
         return run_script([])

    import pygtk
    pygtk.require('2.0')

    import gimpui
    import gtk
#    import pango

    defaults = _get_defaults(proc_name)
    defaults = defaults[len(start_params):]

    class EntryValueError(Exception):
        pass

    def warning_dialog(parent, primary, secondary=None):
        dlg = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT,
                                        gtk.MESSAGE_WARNING, gtk.BUTTONS_CLOSE,
                                        primary)
        if secondary:
            dlg.format_secondary_text(secondary)
        dlg.run()
        dlg.destroy()

    def error_dialog(parent, proc_name):
        import sys, traceback

        exc_str = exc_only_str = _('Missing exception information')

        try:
            etype, value, tb = sys.exc_info()
            exc_str = ''.join(traceback.format_exception(etype, value, tb))
            exc_only_str = ''.join(traceback.format_exception_only(etype, value))
        finally:
            etype = value = tb = None

        title = _("An error occured running %s") % proc_name
        dlg = gtk.MessageDialog(parent, gtk.DIALOG_DESTROY_WITH_PARENT,
                                        gtk.MESSAGE_ERROR, gtk.BUTTONS_CLOSE,
                                        title)
        dlg.format_secondary_text(exc_only_str)

        alignment = gtk.Alignment(0.0, 0.0, 1.0, 1.0)
        alignment.set_padding(0, 0, 12, 12)
        dlg.vbox.pack_start(alignment)
        alignment.show()

        expander = gtk.Expander(_("_More Information"));
        expander.set_use_underline(True)
        expander.set_spacing(6)
        alignment.add(expander)
        expander.show()

        scrolled = gtk.ScrolledWindow()
        scrolled.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
        scrolled.set_size_request(-1, 200)
        expander.add(scrolled)
        scrolled.show()


        label = gtk.Label(exc_str)
        label.set_alignment(0.0, 0.0)
        label.set_padding(6, 6)
        label.set_selectable(True)
        scrolled.add_with_viewport(label)
        label.show()

        def response(widget, id):
            widget.destroy()

        dlg.connect("response", response)
        dlg.set_resizable(True)
        dlg.show()

    # define a mapping of param types to edit objects ...
    class StringEntry(gtk.Entry):
        def __init__(self, default=''):
            gtk.Entry.__init__(self)
            self.set_text(str(default))

        def get_value(self):
            return self.get_text()

    class TextEntry(gtk.ScrolledWindow):
        def __init__ (self, default=''):
            gtk.ScrolledWindow.__init__(self)
            self.set_shadow_type(gtk.SHADOW_IN)

            self.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
            self.set_size_request(100, -1)

            self.view = gtk.TextView()
            self.add(self.view)
            self.view.show()

            self.buffer = self.view.get_buffer()

            self.set_value(str(default))

        def set_value(self, text):
            self.buffer.set_text(text)

        def get_value(self):
            return self.buffer.get_text(self.buffer.get_start_iter(),
                                        self.buffer.get_end_iter())

    class IntEntry(StringEntry):
        def get_value(self):
            try:
                return int(self.get_text())
            except ValueError, e:
                raise EntryValueError, e.args

    class FloatEntry(StringEntry):
            def get_value(self):
                try:
                    return float(self.get_text())
                except ValueError, e:
                    raise EntryValueError, e.args

#    class ArrayEntry(StringEntry):
#            def get_value(self):
#                return eval(self.get_text(), {}, {})


    def precision(step):
        # calculate a reasonable precision from a given step size
        if math.fabs(step) >= 1.0 or step == 0.0:
            digits = 0
        else:
            digits = abs(math.floor(math.log10(math.fabs(step))));
        if digits > 20:
            digits = 20
        return int(digits)

    class SliderEntry(gtk.HScale):
        # bounds is (upper, lower, step)
        def __init__(self, default=0, bounds=(0, 100, 5)):
            step = bounds[2]
            self.adj = gtk.Adjustment(default, bounds[0], bounds[1],
                                      step, 10 * step, 0)
            gtk.HScale.__init__(self, self.adj)
            self.set_digits(precision(step))

        def get_value(self):
            return self.adj.value

    class SpinnerEntry(gtk.SpinButton):
        # bounds is (upper, lower, step)
        def __init__(self, default=0, bounds=(0, 100, 5)):
            step = bounds[2]
            self.adj = gtk.Adjustment(default, bounds[0], bounds[1],
                                      step, 10 * step, 0)
            gtk.SpinButton.__init__(self, self.adj, step, precision(step))

    class ToggleEntry(gtk.ToggleButton):
        def __init__(self, default=0):
            gtk.ToggleButton.__init__(self)

            self.label = gtk.Label(_("No"))
            self.add(self.label)
            self.label.show()

            self.connect("toggled", self.changed)

            self.set_active(default)

        def changed(self, tog):
            if tog.get_active():
                self.label.set_text(_("Yes"))
            else:
                self.label.set_text(_("No"))

        def get_value(self):
            return self.get_active()

    class RadioEntry(gtk.VBox):
        def __init__(self, default=0, items=((_("Yes"), 1), (_("No"), 0))):
            gtk.VBox.__init__(self, homogeneous=False, spacing=2)

            button = None

            for (label, value) in items:
                button = gtk.RadioButton(button, label)
                self.pack_start(button)
                button.show()

                button.connect("toggled", self.changed, value)

                if value == default:
                    button.set_active(True)
                    self.active_value = value

        def changed(self, radio, value):
            if radio.get_active():
                self.active_value = value

        def get_value(self):
            return self.active_value

    class ComboEntry(gtk.ComboBox):
        def __init__(self, default=0, items=()):
            store = gtk.ListStore(str)
            for item in items:
                store.append([item])

            gtk.ComboBox.__init__(self, model=store)

            cell = gtk.CellRendererText()
            self.pack_start(cell)
            self.set_attributes(cell, text=0)

            self.set_active(default)

        def get_value(self):
            return self.get_active()

    def FileSelector(default=''):
       if default and default.endswith('/'):
           selector = DirnameSelector
           if default == '/': default = ''
       else:
           selector = FilenameSelector
       return selector(default)

    class FilenameSelector(gtk.FileChooserButton):
        def __init__(self, default='', save_mode=False):
            gtk.FileChooserButton.__init__(self,
                                           _("Python-Fu File Selection"))
            self.set_action(gtk.FILE_CHOOSER_ACTION_OPEN)
            if default:
                self.set_filename(default)

        def get_value(self):
            return self.get_filename()

    class DirnameSelector(gtk.FileChooserButton):
        def __init__(self, default=''):
            gtk.FileChooserButton.__init__(self,
                                           _("Python-Fu Folder Selection"))
            self.set_action(gtk.FILE_CHOOSER_ACTION_SELECT_FOLDER)
            if default:
                self.set_filename(default)

        def get_value(self):
            return self.get_filename()

    _edit_mapping = {
            PF_INT8        : IntEntry,
            PF_INT16       : IntEntry,
            PF_INT32       : IntEntry,
            PF_FLOAT       : FloatEntry,
            PF_STRING      : StringEntry,
            #PF_INT8ARRAY   : ArrayEntry,
            #PF_INT16ARRAY  : ArrayEntry,
            #PF_INT32ARRAY  : ArrayEntry,
            #PF_FLOATARRAY  : ArrayEntry,
            #PF_STRINGARRAY : ArrayEntry,
            PF_COLOR       : gimpui.ColorSelector,
            PF_REGION      : IntEntry,  # should handle differently ...
            PF_IMAGE       : gimpui.ImageSelector,
            PF_LAYER       : gimpui.LayerSelector,
            PF_CHANNEL     : gimpui.ChannelSelector,
            PF_DRAWABLE    : gimpui.DrawableSelector,
            PF_VECTORS     : gimpui.VectorsSelector,

            PF_TOGGLE      : ToggleEntry,
            PF_SLIDER      : SliderEntry,
            PF_SPINNER     : SpinnerEntry,
            PF_RADIO       : RadioEntry,
            PF_OPTION      : ComboEntry,

            PF_FONT        : gimpui.FontSelector,
            PF_FILE        : FileSelector,
            PF_FILENAME    : FilenameSelector,
            PF_DIRNAME     : DirnameSelector,
            PF_BRUSH       : gimpui.BrushSelector,
            PF_PATTERN     : gimpui.PatternSelector,
            PF_GRADIENT    : gimpui.GradientSelector,
            PF_PALETTE     : gimpui.PaletteSelector,
            PF_TEXT        : TextEntry
    }

    if on_run:
        on_run()

    tooltips = gtk.Tooltips()

    dialog = gimpui.Dialog(proc_name, 'python-fu', None, 0, None, proc_name,
                           (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                            gtk.STOCK_OK, gtk.RESPONSE_OK))

    dialog.set_alternative_button_order((gtk.RESPONSE_OK, gtk.RESPONSE_CANCEL))

    dialog.set_transient()

    vbox = gtk.VBox(False, 12)
    vbox.set_border_width(12)
    dialog.vbox.pack_start(vbox)
    vbox.show()

    if blurb:
        if domain:
            try:
                (domain, locale_dir) = domain
                trans = gettext.translation(domain, locale_dir, fallback=True)
            except ValueError:
                trans = gettext.translation(domain, fallback=True)
            blurb = trans.ugettext(blurb)
        box = gimpui.HintBox(blurb)
        vbox.pack_start(box, expand=False)
        #box.show()

    table = gtk.Table(len(params), 8, False)
    table.set_row_spacings(6)
    table.set_col_spacings(6)
    vbox.pack_start(table, expand=False)
    table.show()

    def response(dlg, id):
        if id == gtk.RESPONSE_OK:
            dlg.set_response_sensitive(gtk.RESPONSE_OK, False)
            dlg.set_response_sensitive(gtk.RESPONSE_CANCEL, False)

            params = []

            try:
                for wid in edit_wids:
                    params.append(wid.get_value())
            except EntryValueError:
                warning_dialog(dialog, _("Invalid input for '%s'") % wid.desc)
            else:
                try:
                    dialog.res = run_script(params)
                except Exception:
                    dlg.set_response_sensitive(gtk.RESPONSE_CANCEL, True)
                    error_dialog(dialog, proc_name)
                    raise

        gtk.main_quit()

    dialog.connect("response", response)

    edit_wids = []


# ADD WIDGETS MANUALLY

# Image Width ---------------------
    pf_type = params[0][0]
    name = params[0][1]
    desc = params[0][2]
    def_val = defaults[0]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 1, 2, 1, 2, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val, params[0][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 2,3, 1,2, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)
   
# Image Height ---------------------
    pf_type = params[1][0]
    name = params[1][1]
    desc = params[1][2]
    def_val = defaults[1]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 3, 4, 1, 2, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val, params[1][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 4,5, 1,2, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Font Range ---------------------
    pf_type = params[2][0]
    name = params[2][1]
    desc = params[2][2]
    def_val = defaults[2]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 1, 2, 3, 4, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val, params[2][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 2,5, 3,4, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)
# Lower Limit ---------------------
    pf_type = params[3][0]
    name = params[3][1]
    desc = params[3][2]
    def_val = defaults[3]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 1, 2, 4, 5, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val,params[3][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 2,3, 4,5, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)
# Upper Limit ---------------------
    pf_type = params[4][0]
    name = params[4][1]
    desc = params[4][2]
    def_val = defaults[4]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 3, 4, 4, 5, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val,params[4][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 4,5, 4,5, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Iterations ---------------------
    pf_type = params[5][0]
    name = params[5][1]
    desc = params[5][2]
    def_val = defaults[5]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 6, 7, 3, 4, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val, params[5][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 7,9, 3,4, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Custom -------------------------
    pf_type = params[6][0]
    name = params[6][1]
    desc = params[6][2]
    def_val = defaults[6]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 6, 7, 4, 5, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val, params[6][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 7,9, 4,5, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# BG color ---------------------
    pf_type = params[7][0]
    name = params[7][1]
    desc = params[7][2]
    def_val = defaults[7]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 6, 7, 1, 2, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val)
    label.set_mnemonic_widget(wid)
    table.attach(wid, 7,9, 1,2, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Base Text color ---------------------
    pf_type = params[8][0]
    name = params[8][1]
    desc = params[8][2]
    def_val = defaults[8]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 1, 2, 6, 7, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val)
    label.set_mnemonic_widget(wid)
    table.attach(wid, 2,4, 6,7, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Text Color Variation ---------------------
    pf_type = params[9][0]
    name = params[9][1]
    desc = params[9][2]
    def_val = defaults[9]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 1, 4, 7, 8, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val,params[9][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 1,4, 8,9, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Base Text Size ---------------------
    pf_type = params[10][0]
    name = params[10][1]
    desc = params[10][2]
    def_val = defaults[10]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 1, 2, 11, 12, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val,params[10][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 2,3, 11,12, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Text Size Variation ---------------------
    pf_type = params[11][0]
    name = params[11][1]
    desc = params[11][2]
    def_val = defaults[11]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 1, 4, 12, 13, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val,params[11][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 1,4, 13,14, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Text Rotation Note -------------------------
    label = gtk.Label("(Deafult Rotation is 0)")
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 6, 9, 11, 12, xoptions=gtk.FILL)
    label.show()
   
# Text Rotation Variation ---------------------
    pf_type = params[12][0]
    name = params[12][1]
    desc = params[12][2]
    def_val = defaults[12]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 6, 9, 12, 13, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val,params[12][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 6,9, 13,14, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Base Text Opacity ---------------------
    pf_type = params[13][0]
    name = params[13][1]
    desc = params[13][2]
    def_val = defaults[13]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 6, 7, 6, 7, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val,params[13][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 7,9, 6,7, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Text Opacity Variation ---------------------
    pf_type = params[14][0]
    name = params[14][1]
    desc = params[14][2]
    def_val = defaults[14]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 6, 9, 7, 8, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val,params[14][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 6,9, 8,9, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)


# Text Options ---------------------
    pf_type = params[15][0]
    name = params[15][1]
    desc = params[15][2]
    def_val = defaults[15]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 1, 2, 15, 16, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val,params[15][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 2,4, 15,16, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Text Input ---------------------
    pf_type = params[16][0]
    name = params[16][1]
    desc = params[16][2]
    def_val = defaults[16]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 5, 6, 15, 16, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val)
    label.set_mnemonic_widget(wid)
    table.attach(wid, 6,9, 15,16, yoptions=gtk.FILL)
    tooltips.set_tip(wid.view, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Random Seed ---------------------
    pf_type = params[17][0]
    name = params[17][1]
    desc = params[17][2]
    def_val = defaults[17]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 1, 2, 17, 18, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val, params[17][4])
    label.set_mnemonic_widget(wid)
    table.attach(wid, 2,3, 17,18, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Flatten flag ---------------------
    pf_type = params[18][0]
    name = params[18][1]
    desc = params[18][2]
    def_val = defaults[18]
   
    label = gtk.Label(desc)
    label.set_use_underline(True)
    label.set_alignment(0.0, 0.5)
    table.attach(label, 4, 5, 17, 18, xoptions=gtk.FILL)
    label.show()
   
    wid = _edit_mapping[pf_type](def_val)
    label.set_mnemonic_widget(wid)
    table.attach(wid, 5,9, 17,18, yoptions=0)
    tooltips.set_tip(wid, desc, None)
    wid.show()
    wid.desc = desc
    edit_wids.append(wid)

# Horizontal Separator 1  ---------------------
    separator = gtk.HSeparator()
    table.attach(separator, 1, 9, 2, 3, xoptions=gtk.FILL)
    separator.show()
   
# Horizontal Separator 2 ---------------------
    separator = gtk.HSeparator()
    table.attach(separator, 1, 9, 5, 6, xoptions=gtk.FILL)
    separator.show()

# Horizontal Separator 3 ---------------------
    separator = gtk.HSeparator()
    table.attach(separator, 1, 9, 10, 11, xoptions=gtk.FILL)
    separator.show()

# Horizontal Separator 4 ---------------------
    separator = gtk.HSeparator()
    table.attach(separator, 1, 9, 14, 15, xoptions=gtk.FILL)
    separator.show()

# Horizontal Separator 5 ---------------------
    separator = gtk.HSeparator()
    table.attach(separator, 1, 9, 16, 17, xoptions=gtk.FILL)
    separator.show()

# Vertical Separator 1  ---------------------
    separator = gtk.VSeparator()
    table.attach(separator, 5, 6, 3, 5, xoptions=gtk.FILL)
    separator.show()

# Vertical Separator 2  ---------------------
    separator = gtk.VSeparator()
    table.attach(separator, 5, 6, 6, 10, xoptions=gtk.FILL)
    separator.show()

# Vertical Separator 3  ---------------------
    separator = gtk.VSeparator()
    table.attach(separator, 5, 6, 11, 14, xoptions=gtk.FILL)
    separator.show()


# Widgets Interaction ---------------------------

    #get installed fonts number
    num_fonts, font_list = pdb.gimp_fonts_get_list("")

    def callback_limitsToggle(widget, data=None):
        val = edit_wids[2].get_active()
        if val==0:
            edit_wids[3].set_sensitive(0)
            edit_wids[4].set_sensitive(0)
        else:
            edit_wids[3].set_sensitive(1)
            edit_wids[4].set_sensitive(1)

    def callback_customToggle(widget, data=None):
        val = edit_wids[5].get_active()
        if val==0:
            edit_wids[6].set_sensitive(0)
        else:
            edit_wids[6].set_sensitive(1)

    def callback_setMin(widget, data=None):
        limit = edit_wids[4].get_value()
        edit_wids[3].set_range(1,limit)
        if edit_wids[3].get_value()>= limit:
            edit_wids[3].set_value(limit)

    def callback_textToggle(widget, data=None):
        val = edit_wids[15].get_active()
        if val==0:
            edit_wids[16].set_sensitive(0)
        else:
            edit_wids[16].set_sensitive(1)


    handler_1 = edit_wids[4].connect('output',callback_setMin,None)
    handler_2 = edit_wids[5].connect('changed',callback_customToggle,None)
    handler_3 = edit_wids[2].connect('changed',callback_limitsToggle,None)
    handler_4 = edit_wids[15].connect('changed',callback_textToggle,None)
   
    # Dialog DEFAULTS:
   
    #set range for font range maximum limit
    edit_wids[4].set_range(1,num_fonts+1)

    #Disable font range limit and 'custom' spinners:
    if edit_wids[2].get_active() == 0:
        edit_wids[3].set_sensitive(0)
        edit_wids[4].set_sensitive(0)       

    if edit_wids[5].get_active() == 0:
         edit_wids[6].set_sensitive(0)

    if edit_wids[15].get_active()==0:
        edit_wids[16].set_sensitive(0)

# TABLE POPULATION LOOP [from original code]
##    for i in range(len(params)):
##        pf_type = params[i][0]
##        name = params[i][1]
##        desc = params[i][2]
##        def_val = defaults[i]
##
##        label = gtk.Label(desc)
##        label.set_use_underline(True)
##        label.set_alignment(0.0, 0.5)
##        table.attach(label, 1, 2, i, i+1, xoptions=gtk.FILL)
##        label.show()
##
##        if pf_type in (PF_SPINNER, PF_SLIDER, PF_RADIO, PF_OPTION):
##            wid = _edit_mapping[pf_type](def_val, params[i][4])
##        else:
##            wid = _edit_mapping[pf_type](def_val)
##
##        label.set_mnemonic_widget(wid)
##       
##        table.attach(wid, 2,3, i,i+1, yoptions=0)
##
##        if pf_type != PF_TEXT:
##            tooltips.set_tip(wid, desc, None)
##        else:
##            #Attach tip to TextView, not to ScrolledWindow
##            tooltips.set_tip(wid.view, desc, None)
##        wid.show()
##
##        wid.desc = desc
##        edit_wids.append(wid)
##

# END OF TABLE POPULATION LOOP

    progress_vbox = gtk.VBox(False, 6)
    vbox.pack_end(progress_vbox, expand=False)
    progress_vbox.show()

    progress = gimpui.ProgressBar()
    progress_vbox.pack_start(progress)
    progress.show()

#    progress_label = gtk.Label()
#    progress_label.set_alignment(0.0, 0.5)
#    progress_label.set_ellipsize(pango.ELLIPSIZE_MIDDLE)

#    attrs = pango.AttrList()
#    attrs.insert(pango.AttrStyle(pango.STYLE_ITALIC, 0, -1))
#    progress_label.set_attributes(attrs)

#    progress_vbox.pack_start(progress_label)
#    progress_label.show()

    tooltips.enable()
    dialog.show()

    gtk.main()

    if hasattr(dialog, 'res'):
        res = dialog.res
        dialog.destroy()
        return res
    else:
        dialog.destroy()
        raise CancelError


# HERE STARTS THE PLUGIN ------------------------------------------

##Word Art v1.0 - 2011.01
##Gimp Python plugin

## Below code is
##Copyright (C) 2011 Andrei Roslovtsev ~ www.byes-and-pixels.com
##
##This program is free software; you can redistribute it and/or
##modify it under the terms of the GNU General Public License
##as published by the Free Software Foundation version 2
##of the License.
##
##This program is distributed in the hope that it will be useful,
##but WITHOUT ANY WARRANTY; without even the implied warranty of
##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##GNU General Public License for more details.
##
##You should have received a copy of the GNU General Public License
##along with this program; if not, write to the Free Software
##Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

# This plugin creates random text art based on specified parameters:
#  Iterates through installed fonts on a given machine,
#  randomizes position, color, opacity rotation of text layers,
#  Allows to use font names as strings or a user input.
#
#
# Note:
# Developed and tested with Python 2.6 only.
#
# Version:1.0
# 2011.01
# Andrei Roslovtsev
# www.bytes-and-pixels.com
# andrei@bytes-and-pixels.com


#-----------------------------------------------------------
import sys, re, random as r

def make_poster(img_w,img_h,fonts,l_limit,
                u_limit,iterations,custom,bg_col,base_tc,tc_var,base_ts,
                ts_var,tr_var,base_to,to_var,txt_mode,in_text,seed,flatten_flag):

    #set variables
    num_fonts, font_list = pdb.gimp_fonts_get_list("")
    r.seed(seed)
    txt_size = base_ts
    text_col = base_tc
   
    # randomization helpers
    ts_min,ts_max,tc_min1,tc_max1,tc_min2,tc_max2,tc_min3,tc_max3 = 0,0,0,0,0,0,0,0

    strings = []
   
    #populate strings
    if txt_mode == 1:
        strings = in_text.split('\n')
    else:
        for font in range(num_fonts):
            strings.append(font_list[font])
    #font range and iterations params
    f_start,f_end,i,i_end = 0,0,0,0
    j_end,cur_font=0,0

    if txt_mode == 1:       
        #Check strings for blanks and clean them up
        for item in strings:
            if item=='':
                strings.remove(item)
            else:
              regex = re.search('\w',item)
              if regex == None:
                  strings.remove(item)
           

    try:
        #check if strings list is empty and go to except
        if len(strings) == 0:
            raise Exception('You didn\'t provide any text')
       
        # Create new image
        image = pdb.gimp_image_new(img_w, img_h, 0)
        pdb.gimp_image_set_filename(image, "Word_art")

        layer1 = pdb.gimp_layer_new(image, img_w, img_h, 1, 'BG', 100, 0)
        pdb.gimp_image_add_layer(image, layer1, 0)
       
        display = pdb.gimp_display_new(image)
       
        pdb.gimp_context_set_background(bg_col)
       
        gimp.pdb.gimp_edit_fill(layer1, 1)

        # reset colors to B&W
        pdb.gimp_context_set_default_colors()


        # Select the range and number of iterations
           
        if fonts == 0:
            f_start = 0
            f_end = num_fonts
        if fonts == 1:
            f_start = int(l_limit-1) #adjust to zero based value
            f_end = int(u_limit-1)  #adjust to zero based value

            cur_font = f_start
           
        if iterations == 0:
            i_end = num_fonts
            if fonts == 1:
                i_end = f_end - f_start + 1
           
        if iterations == 1:
            i_end = custom


    #setup j - strings iterator------------
        if txt_mode == 0 and fonts == 1:
            j = int(l_limit-1) #adjust to zero based value
            j_end = int(u_limit-1) #adjust to zero based value
        else:
            j = 0
            j_end = len(strings)

    #setup cur_font - font iterator
        if fonts == 1:
            cur_font = f_start

        #remenber initial j value
        j_init = j

    # --------------------- Start the main loop --------------------------------
        while i < i_end:

            #setup strings iterator to loop
            if txt_mode == 1:
                if j==j_end:
                    j=j_init
            else:
                if j>j_end:
                    j=j_init

            #setup font iterator to loop
            if cur_font>f_end:
                cur_font=f_start

               
        # Text Layers --------------------------------------------
            layer_n = pdb.gimp_text_layer_new(image, strings[j], font_list[cur_font], txt_size, 0)
            pdb.gimp_image_add_layer(image, layer_n, 0)
            pdb.gimp_text_layer_set_color(layer_n, text_col)
           
            #randomize stuff:
           
            #calulate variation limits
            # text size
            ts_min=base_ts - ts_var
            if ts_min<8:
                ts_min=8
            ts_max = base_ts + ts_var
            txt_size = r.randint(ts_min,ts_max)
           
            #text color
            tc_min1 = clamp(base_tc[0] - tc_var,0,255)
            tc_min2 = clamp(base_tc[1] - tc_var,0,255)
            tc_min3 = clamp(base_tc[2] - tc_var,0,255)
            tc_max1 = clamp(base_tc[0] + tc_var,0,255)
            tc_max2 = clamp(base_tc[1] + tc_var,0,255)
            tc_max3 = clamp(base_tc[2] + tc_var,0,255)

            #rotation var
            rot = 0
            if tr_var > 0:
                rot = r.randint(tr_var*-1,tr_var)

            #opacity var
            op = base_to
            if to_var > 0:
                op = clamp(r.randint(base_to-to_var,base_to+to_var),0,100)
           
            text_col = (r.randint(tc_min1,tc_max1),r.randint(tc_min2,tc_max2),r.randint(tc_min3,tc_max3))

           
            txt_x = r.randint(-10,img_w)
            txt_y = r.randint(-10,img_h)
            layer_n.set_offsets(txt_x, txt_y-2)


            if rot <> 0:
                 layer_n = pdb.gimp_drawable_transform_rotate_default(layer_n,
                                                                      math.radians(rot), 1, 0,
                                                                      0, 1, 0)

            if op < 100:
                pdb.gimp_layer_set_opacity(layer_n, op)

            i=i+1
            j=j+1
            cur_font = cur_font + 1

    # Flatten Image routine ---------------------------------------------
        if flatten_flag == 1:
            pdb.gimp_image_flatten(image)

    except Exception as inst:
        pdb.gimp_message(inst)


def clamp(x,minimum, maximum):
    return max(minimum, min(x, maximum))
#---------------------------------------------------------------------
register(
    "Word_Art",
    N_("Create a poster art from text strings"),
    "Create a random poster art from text strings - b&p_word_art_01_v1.0.py",
    "Andrei Roslovtsev",
    "www.bytes-and-pixels.com",
    "2011",
    N_("_Word Art"),
    #"RGB*, GRAY*",
    "",
    [
        (PF_SPINNER, "img_w", "Image Width:", 640, (1, 20000, 1)),
        (PF_SPINNER, "img_h", "Image Height:", 480, (1, 20000, 1)),
        (PF_OPTION,"fonts",   "Font Range:", 0, ["All fonts","Limited fonts"]),
        (PF_SPINNER, "l_limit", "Lower Limit:", 0,(1,2000,1)),
        (PF_SPINNER, "u_limit", "Upper Limit:", 0,(1,2000,1)),
        (PF_OPTION,"iterations", "Iterations:", 0, ["Font number","Custom"]),
        (PF_SPINNER, "custom", "Custom:", 0,(0,2000,1)),
        (PF_COLOR, "bg_col", "Background Color:", (250, 250, 250) ),
        (PF_COLOR, "base_tc", "Base Text Color:", (140, 155, 175) ),
        (PF_SLIDER, "tc_var", "Text color variation:", 50, (0, 255, 1)),
        (PF_SPINNER, "base_ts", "Base Text Size (px):", 24, (1, 2000, 1)),
        (PF_SLIDER, "ts_var", "Text size variation (px):", 100, (0, 1000, 1)),
        (PF_SLIDER, "tr_var", "Text rotation variation (degrees):", 10, (0, 180, 1)),
        (PF_SPINNER, "base_to", "Base Text Opacity (%):", 80, (1, 100, 1)),
        (PF_SLIDER, "to_var", "Text opacity variation (%):", 20, (0, 100, 1)),
        (PF_OPTION,"txt_mode",   "Text Options:", 1, ["Font names","User input"]),
        (PF_TEXT, "in_text", "Text:", "Python\nGimp\nPyGTK\nCool Plugins"),
        (PF_SPINNER, "seed", "Random Seed:", 1000, (1, 2000, 1)),
        (PF_TOGGLE, "flatten_flag", "Flatten Image", 0)
    ],
    [],
    make_poster,
    #menu="<Image>/File/Create/Buttons",
    menu="<Image>/Filters/Word Art",
    domain=("gimp20-python", gimp.locale_directory)
    )

main()

_________________
Image
Edmund Burke nailed it when he said, "The only thing necessary for the triumph of evil is for good men to do nothing."


Share on Facebook Share on Twitter Share on Orkut Share on Digg Share on MySpace Share on Delicious Share on Technorati
Top
 Post subject: Re: I need help with a Python script
PostPosted: Tue Apr 17, 2012 7:27 am  (#2) 
Offline
Script Coder
User avatar

Joined: Jun 22, 2010
Posts: 1171
Location: Here and there
Have you tried contacting the original author:

http://www.bytes-and-pixels.com/2011/01 ... -word-art/

http://registry.gimp.org/node/24974

As their responses to some of the original comments refer to having hacked in a modified version of the Python gimpfu module, which almost certainly needs re-hacking to cope with the changes introduced by layer-groups etc.

Kevin


Top
 Post subject: Re: I need help with a Python script
PostPosted: Tue Apr 17, 2012 2:34 pm  (#3) 
Offline
GimpChat Member
User avatar

Joined: May 16, 2010
Posts: 14709
Location: USA
Thanks Kevin, i will look into contacting the author next. :)
It just seems it would at least show in the menus.Then throw a error on start.

_________________
Image
Edmund Burke nailed it when he said, "The only thing necessary for the triumph of evil is for good men to do nothing."


Top
 Post subject: Re: I need help with a Python script
PostPosted: Wed Apr 18, 2012 8:16 am  (#4) 
Offline
GimpChat Member
User avatar

Joined: May 16, 2010
Posts: 14709
Location: USA
Here it is if you want a working version for Gimp-2.8-RC-1 :) (special thanks for Sams help).
You will find it in "Filters/Render/Word Art"
#!/usr/bin/env python

'''
HERE STARTS THE PLUGIN
Updated to work in Gimp-2.8-RC1

Word Art v2.0 - 2011.01
Gimp Python plugin

Below code is
Copyright (C) 2011 Andrei Roslovtsev ~ www.byes-and-pixels.com

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation version 2
of the License.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA

This plugin creates random text art based on specified parameters:
Iterates through installed fonts on a given machine,
randomizes position, color, opacity rotation of text layers,
Allows to use font names as strings or a user input.


Note:
Developed and tested with Python 2.8 RC1 only.

Version:2.0 (updated to work in Gimp-2.8-RC1)
2011.01
Andrei Roslovtsev
www.bytes-and-pixels.com
andrei@bytes-and-pixels.com

'''

from gimpfu import *
import string as _string
import math
import gimp
import gimpcolor
from gimpenums import *
pdb = gimp.pdb

import gettext
t = gettext.translation('gimp20-python', gimp.locale_directory, fallback=True)
_ = t.ugettext
import sys, re, random as r

def make_poster(img_w,img_h,fonts,l_limit,
                u_limit,iterations,custom,bg_col,base_tc,tc_var,base_ts,
                ts_var,tr_var,base_to,to_var,txt_mode,in_text,seed,flatten_flag):

    #set variables
    num_fonts, font_list = pdb.gimp_fonts_get_list("")
    r.seed(seed)
    txt_size = base_ts
    text_col = base_tc
   
    # randomization helpers
    ts_min,ts_max,tc_min1,tc_max1,tc_min2,tc_max2,tc_min3,tc_max3 = 0,0,0,0,0,0,0,0

    strings = []
   
    #populate strings
    if txt_mode == 1:
        strings = in_text.split('\n')
    else:
        for font in range(num_fonts):
            strings.append(font_list[font])
    #font range and iterations params
    f_start,f_end,i,i_end = 0,0,0,0
    j_end,cur_font=0,0

    if txt_mode == 1:       
        #Check strings for blanks and clean them up
        for item in strings:
            if item=='':
                strings.remove(item)
            else:
              regex = re.search('\w',item)
              if regex == None:
                  strings.remove(item)
           

    try:
        #check if strings list is empty and go to except
        if len(strings) == 0:
            raise Exception('You didn\'t provide any text')
       
        # Create new image
        image = pdb.gimp_image_new(img_w, img_h, 0)
        pdb.gimp_image_set_filename(image, "Word_art")

        layer1 = pdb.gimp_layer_new(image, img_w, img_h, 1, 'BG', 100, 0)
        pdb.gimp_image_add_layer(image, layer1, 0)
       
        display = pdb.gimp_display_new(image)
       
        pdb.gimp_context_set_background(bg_col)
       
        gimp.pdb.gimp_edit_fill(layer1, 1)

        # reset colors to B&W
        pdb.gimp_context_set_default_colors()


        # Select the range and number of iterations
           
        if fonts == 0:
            f_start = 0
            f_end = num_fonts
        if fonts == 1:
            f_start = int(l_limit-1) #adjust to zero based value
            f_end = int(u_limit-1)  #adjust to zero based value

            cur_font = f_start
           
        if iterations == 0:
            i_end = num_fonts
            if fonts == 1:
                i_end = f_end - f_start + 1
           
        if iterations == 1:
            i_end = custom


    #setup j - strings iterator------------
        if txt_mode == 0 and fonts == 1:
            j = int(l_limit-1) #adjust to zero based value
            j_end = int(u_limit-1) #adjust to zero based value
        else:
            j = 0
            j_end = len(strings)

    #setup cur_font - font iterator
        if fonts == 1:
            cur_font = f_start

        #remenber initial j value
        j_init = j

    # --------------------- Start the main loop --------------------------------
        while i < i_end:

            #setup strings iterator to loop
            if txt_mode == 1:
                if j==j_end:
                    j=j_init
            else:
                if j>j_end:
                    j=j_init

            #setup font iterator to loop
            if cur_font>f_end:
                cur_font=f_start

               
        # Text Layers --------------------------------------------
            layer_n = pdb.gimp_text_layer_new(image, strings[j], font_list[cur_font], txt_size, 0)
            pdb.gimp_image_add_layer(image, layer_n, 0)
            pdb.gimp_text_layer_set_color(layer_n, text_col)
           
            #randomize stuff:
           
            #calulate variation limits
            # text size
            ts_min=base_ts - ts_var
            if ts_min<8:
                ts_min=8
            ts_max = base_ts + ts_var
            txt_size = r.randint(ts_min,ts_max)
           
            #text color
            tc_min1 = clamp(base_tc[0] - tc_var,0,255)
            tc_min2 = clamp(base_tc[1] - tc_var,0,255)
            tc_min3 = clamp(base_tc[2] - tc_var,0,255)
            tc_max1 = clamp(base_tc[0] + tc_var,0,255)
            tc_max2 = clamp(base_tc[1] + tc_var,0,255)
            tc_max3 = clamp(base_tc[2] + tc_var,0,255)

            #rotation var
            rot = 0
            if tr_var > 0:
                rot = r.randint(tr_var*-1,tr_var)

            #opacity var
            op = base_to
            if to_var > 0:
                op = clamp(r.randint(base_to-to_var,base_to+to_var),0,100)
           
            text_col = (r.randint(tc_min1,tc_max1),r.randint(tc_min2,tc_max2),r.randint(tc_min3,tc_max3))

           
            txt_x = r.randint(-10,img_w)
            txt_y = r.randint(-10,img_h)
            layer_n.set_offsets(txt_x, txt_y-2)


            if rot <> 0:
                 layer_n = pdb.gimp_drawable_transform_rotate_default(layer_n,
                                                                      math.radians(rot), 1, 0,
                                                                      0, 1, 0)

            if op < 100:
                pdb.gimp_layer_set_opacity(layer_n, op)

            i=i+1
            j=j+1
            cur_font = cur_font + 1

    # Flatten Image routine ---------------------------------------------
        if flatten_flag == 1:
            pdb.gimp_image_flatten(image)

    except Exception as inst:
        pdb.gimp_message(inst)


def clamp(x,minimum, maximum):
    return max(minimum, min(x, maximum))
#---------------------------------------------------------------------
register(
    "Word_Art",
    N_("Create a poster art from text strings"),
    "Create a random poster art from text strings - b&p_word_art_01_v1.0.py",
    "Andrei Roslovtsev",
    "www.bytes-and-pixels.com",
    "2011",
    N_("_Word Art"),
    #"RGB*, GRAY*",
    "",
    [
        (PF_SPINNER, "img_w", "Image Width:", 640, (1, 20000, 1)),
        (PF_SPINNER, "img_h", "Image Height:", 480, (1, 20000, 1)),
        (PF_OPTION,"fonts",   "Font Range:", 0, ["All fonts","Limited fonts"]),
        (PF_SPINNER, "l_limit", "Lower Limit:", 0,(1,2000,1)),
        (PF_SPINNER, "u_limit", "Upper Limit:", 0,(1,2000,1)),
        (PF_OPTION,"iterations", "Iterations:", 0, ["Font number","Custom"]),
        (PF_SPINNER, "custom", "Custom:", 0,(0,2000,1)),
        (PF_COLOR, "bg_col", "Background Color:", (250, 250, 250) ),
        (PF_COLOR, "base_tc", "Base Text Color:", (140, 155, 175) ),
        (PF_SLIDER, "tc_var", "Text color variation:", 50, (0, 255, 1)),
        (PF_SPINNER, "base_ts", "Base Text Size (px):", 24, (1, 2000, 1)),
        (PF_SLIDER, "ts_var", "Text size variation (px):", 100, (0, 1000, 1)),
        (PF_SLIDER, "tr_var", "Text rotation variation (degrees):", 10, (0, 180, 1)),
        (PF_SPINNER, "base_to", "Base Text Opacity (%):", 80, (1, 100, 1)),
        (PF_SLIDER, "to_var", "Text opacity variation (%):", 20, (0, 100, 1)),
        (PF_OPTION,"txt_mode",   "Text Options:", 1, ["Font names","User input"]),
        (PF_TEXT, "in_text", "Text:", "Python\nGimp"),
        (PF_SPINNER, "seed", "Random Seed:", 1000, (1, 2000, 1)),
        (PF_TOGGLE, "flatten_flag", "Flatten Image", 0)
    ],
    [],
    make_poster,
    #menu="<Image>/File/Create/Buttons",
    menu="<Image>/Filters/Render/Word Art",
    domain=("gimp20-python", gimp.locale_directory)
    )

main()


_________________
Image
Edmund Burke nailed it when he said, "The only thing necessary for the triumph of evil is for good men to do nothing."


Top
 Post subject: Re: I need help with a Python script
PostPosted: Wed Apr 18, 2012 8:18 am  (#5) 
Offline
GimpChat Member
User avatar

Joined: May 16, 2010
Posts: 14709
Location: USA
What you can do with it? :)
Image

_________________
Image
Edmund Burke nailed it when he said, "The only thing necessary for the triumph of evil is for good men to do nothing."


Top
 Post subject: Re: I need help with a Python script
PostPosted: Wed Apr 18, 2012 8:22 am  (#6) 
Offline
GimpChat Member
User avatar

Joined: May 16, 2010
Posts: 14709
Location: USA
I did have one small problem with my wide screen - The dialog has alot in it so the dialog is very tall. :lol
With windows just select the window hit alt +space (or right click on the window and click move)
now use the arrow keys to see the rest of the dialog.
To make it run just select a slider and hit enter.

Be forewarned if you have many fonts installed use the limited fonts value!
Or you are gonna be there a long time :lol

_________________
Image
Edmund Burke nailed it when he said, "The only thing necessary for the triumph of evil is for good men to do nothing."


Top
 Post subject: Re: I need help with a Python script
PostPosted: Sun Apr 29, 2012 3:23 am  (#7) 
Offline
GimpChat Member

Joined: Apr 29, 2012
Posts: 44
I am the author of this plug. Glad to hear people find it useful.
The fix above indeed does work, but it kills the custom dialog I've built.

For those interested, there is an updated version of the script on my home page. It is v1.2 (updated for Giimp 2.7+)

Cheers.


Top
 Post subject: Re: I need help with a Python script
PostPosted: Sun Apr 29, 2012 3:25 pm  (#8) 
Offline
GimpChat Member
User avatar

Joined: May 16, 2010
Posts: 14709
Location: USA
Thanks B and P! :)

_________________
Image
Edmund Burke nailed it when he said, "The only thing necessary for the triumph of evil is for good men to do nothing."


Top
 Post subject: Re: I need help with a Python script
PostPosted: Sun Apr 29, 2012 4:01 pm  (#9) 
Offline
Global Moderator
User avatar

Joined: Nov 16, 2011
Posts: 5128
Location: Metro Vancouver, BC
B-and-P,
On your web site you wrote:
Once installed, you will find the plugin under:
File > Create > Web Page Themes > http://www.bytes-and-pixels.com

In Windows, Gimp 2.8.0-RC1 it's, Filters > Word Art. With the [PSPI] PS filters.

_________________
Image
Gimp 2.8.18, Linux, median user
Gimp Chat Tutorials Index
Spirit Bear (Kermode)


Top
 Post subject: Re: I need help with a Python script
PostPosted: Mon Apr 30, 2012 12:37 am  (#10) 
Offline
GimpChat Member

Joined: Apr 29, 2012
Posts: 44
@Odinbc:
Yes, thanks. I corrected it.


Top
 Post subject: Re: I need help with a Python script
PostPosted: Mon Apr 30, 2012 10:42 am  (#11) 
Offline
GimpChat Member
User avatar

Joined: May 16, 2010
Posts: 14709
Location: USA
The dialog works much better thank you. :)

_________________
Image
Edmund Burke nailed it when he said, "The only thing necessary for the triumph of evil is for good men to do nothing."


Top
Post new topic Reply to topic  [ 11 posts ] 

All times are UTC - 5 hours [ DST ]


   Similar Topics   Replies 
No new posts Attachment(s) Learning to do first Python script

6

No new posts .py script not showing under Python-Fu

3

No new posts Attachment(s) My first Python Script for Gimp

7

No new posts Does anyone have script fu and python plugins that work on 2.99.19?

1

No new posts Can a python script use gimpfu, run from terminal, and create new img?

2



* Login  



Powered by phpBB3 © phpBB Group