argentum2f
argentum2f

Reputation: 5370

How do I change text in a python-fu gimp script without changing the font?

I have a master image which I edit in gimp to get the look and feel wanted. I then want to use a python script to produce a bunch of new images with the text (on several different layers) changed. I would like to leave the font, size, italicized or not, etc. alone.

I've successfully changed the text in my batch script with this function:

pdb.gimp_text_layer_set_text(layer, text)

The problem is this also overwrites the font and other text parameters that I had picked out in the master file. Is there a way to change just the text and leave the font alone?

Alternately, a more clunky way would be to try and save everything important about the font before the change and try to reapply it. This is what I've tried:

# Find the text layer
text1_layer = filter(lambda x: x.name == 'text1', im.layers)[0]

# Save the font                
font = pdb.gimp_text_layer_get_font(text1_layer)                              
font_size, font_unit = pdb.gimp_text_layer_get_font_size(text1_layer)

# Set the text       
pdb.gimp_text_layer_set_text(text1_layer, tex1_text)

# Restore the font                       
pdb.gimp_text_layer_set_font(text1_layer, font)                               
pdb.gimp_text_layer_set_font_size(text1_layer, font_size, font_unit)

Unfortunately, that doesn't seem to work consistently. It looks like the get_font and get_font_size commands retrieve the right font for one of the layers, but not for the others. It doesn't seem to preserve italics etc., and I wouldn't expect it to preserve whether or not text is underlined.

A third option would be to hard code in the font. I would need to go through all the text fields, figure out what the font parameters are and hard code them in for each one. Then, if I redesign the master file (which I will do a lot), I have to repeat the process. This shouldn't be necessary.

Upvotes: 4

Views: 3866

Answers (2)

xenoid
xenoid

Reputation: 8914

Not really a satisfactory answer, but too big to post as a comment.

Yes, the text layer API wasn't updated to follow the new capabilities. Actually all the info is in a gimp-text-layer "parasite":

parasites=layer.parasite_list()
if parasites and 'gimp-text-layer' in parasites:
    data=layer.parasite_find('gimp-text-layer').data
    pdb.gimp_message('Text layer "%s": %s' % (layer.name,data))

This parasite doesn't seem to exist until the image has been saved at least once.

However, even though you can replace the parasite data, it doesn't change the text layer, and to make it worse, it seems that Gimp detects the change, assumes that the layer text data is corrupt, and makes the layer a plain bitmap when saving the image.

Now, poring over the source code, there are mentions of a GDynText plugin that you can find on SourceForge and that advertizes itself as:

GIMP Dynamic Text is a GIMP plug-in that works like the text tool but allows you writing multi-line text and made you able of modifying it later as you want (text/font/font size/color/...).

So you could be lucky, or not...

Upvotes: 1

argentum2f
argentum2f

Reputation: 5370

I've done a bit more research and found a solution that works for me in gimp, however, it sounds like you should probably be using something other than gimp, such as imagemagick, if you're doing much text editing from a script.

The solution is, when you change text in the gimp editor you need to change the font in the tool dialog box, so it's set as a property of the layer, instead of just selecting the text and changing the font in the floating font box that shows up - that changes the font of the text you selected, but leaves the base font of the text layer unchanged.

In turns out that gimp text functionality is pretty poor, and there are lots of complaints surrounding issues like this online. There is some hope for the future. Apparently gimp supports a markup language for text. You can get the markup for your text this way:

pdb.gimp_text_layer_get_markup(layer)

Unfortunately, there is no set_markup function - even though it's been commented on and requested for 3-5 years now, so don't hold your breath. If such a function existed, then the get_markup and set_markup functions would give a script complete control over text. It doesn't exist, however, so if you want to change pieces of text (eg. to add italics to a word), you have to create separate layers. If all your text is to be formatted the same, you can edit it via script or editor, and as long as you set it in the text layer properties (done via the tool box in the editor, and the only way you can change font in a script), then the set_text function in a script will maintain font, etc.

https://bugzilla.gnome.org/show_bug.cgi?id=724101

http://gimpchat.com/viewtopic.php?f=9&t=10101&p=132782&hilit=change+text+markup#p132782

Upvotes: 3

Related Questions