| 
 translating every text layer - jacques_duflos -  07-12-2023
 
 Hi there,
 I made this script that translates every text layer of the layer group selected, or the text layer selected.
 As you can see  at lines 50 to 54, I had to skip the text layers witches text are None because it generated an error and interrupted the script. But I don't understand why some of my text layers return the None value when I ask them their text. All those text layers have a text. Any clue anyone ?
 
 
 
Code:
                # lines 50 to 54# Vérifier si le texte n'est pas de type NoneType
 if text is not None:
 # Traduire le texte en utilisant la bibliothèque translate
 translated_text = translator.translate(text)
 else:
 translated_text = "ERREUR TEXTE NON TRADUIT\n{}".format(text)
 
 Another question I have is about the libraries I had to include. I added them directly next to the .py that needed them and it works. But I guess it is not the elegant way of doing so. If I do another script needing the same libraries, I would have to include them once more. Is there a way to include libraries in the gimp specific python installation ?
 the dependencies are as followed :
 traducion.py (my script) needs translate
 translate.py needs providers
 providers/mymemory_translated.py needs requests
 
 the main script is :
 
 
 
Code:
 #!/usr/bin/env python# -*- coding: utf-8 -*-
 
 from gimpfu import *
 from translate import Translator
 
 def translate_text_layers(image, drawable):
 image.undo_group_start()
 
 translator = Translator(to_lang="fr", from_lang="es")
 print("------------start--------------")
 pdb.gimp_message_set_handler(MESSAGE_BOX)
 
 # Recuperation du groupe de calques selectionne
 group = pdb.gimp_image_get_active_layer(image)
 
 # Récupération du groupe de calques "text-fr" s'il existe
 group_text = None
 for layer in image.layers:
 if pdb.gimp_item_is_group(layer) and pdb.gimp_item_get_name(layer) == "text-fr":
 group_text = layer
 break
 
 if group_text is None:
 # Créer un groupe de calques nommé "text-fr" s'il n'existe pas
 group_text = pdb.gimp_layer_group_new(image)
 pdb.gimp_item_set_name(group_text, "text-fr")
 pdb.gimp_image_insert_layer(image, group_text, None, 0)
 
 if pdb.gimp_item_is_group(group):
 print("----------layer is group-------------")
 # Creer un groupe de calques nommé "text-fr"
 group_text = pdb.gimp_layer_group_new(image)
 pdb.gimp_item_set_name(group_text, "text-fr")
 pdb.gimp_image_insert_layer(image, group_text, None, 0)
 # Parcours de tous les calques du groupe
 for layer in group.layers:
 # Vérification si le calque est de type texte
 if pdb.gimp_item_is_text_layer(layer):
 # Dupliquer le calque
 duplicate = pdb.gimp_layer_copy(layer, True)
 
 # Ajouter le calque duplique au groupe "text-fr"
 pdb.gimp_image_insert_layer(image, duplicate, group_text, 0)
 
 # Récupérer le contenu texte du calque dupliqué
 text = pdb.gimp_text_layer_get_text(duplicate)
 
 # Vérifier si le texte n'est pas de type NoneType
 if text is not None:
 # Traduire le texte en utilisant la bibliothèque translate
 translated_text = translator.translate(text)
 else:
 translated_text = "ERREUR TEXTE NON TRADUIT\n{}".format(text)
 
 
 # Mettre à jour le texte du calque dupliqué avec la traduction
 pdb.gimp_text_layer_set_text(duplicate, translated_text)
 
 # Actualisation de l'affichage de l'image
 pdb.gimp_displays_flush()
 elif pdb.gimp_item_is_text_layer(group):
 print("----------layer is text-------------")
 # Si le calque sélectionné est un calque de texte
 # Dupliquer le calque
 duplicate = pdb.gimp_layer_copy(group, True)
 
 # Ajouter le calque duplique au groupe "text-fr"
 pdb.gimp_image_insert_layer(image, duplicate, group_text, 0)
 
 # Récupérer le contenu texte du calque dupliqué
 text = pdb.gimp_text_layer_get_text(duplicate)
 
 # Traduire le texte en utilisant la bibliothèque translate
 translated_text = translator.translate(text)
 
 # Mettre à jour le texte du calque dupliqué avec la traduction
 pdb.gimp_text_layer_set_text(duplicate, translated_text)
 else:
 print("--------Veuillez sélectionner un groupe de calques ou un calque de texte.----")
 gimp.message("Veuillez sélectionner un groupe de calques ou un calque de texte.")
 
 pdb.gimp_message("fini")
 # restore stuff
 image.undo_group_end()
 
 register(
 "python-fu-translate-text-layers",
 "Translate text layers from French to English",
 "Translate text layers from French to English",
 "Your Name",
 "Your Name",
 "2023",
 "<Image>/Filters/Language/Translate Text Layers",
 "*",
 [],
 [],
 translate_text_layers)
 
 main()
 
 
 RE: translating every text layer - Ofnuts -  07-13-2023
 
 Can you share an example XCF? I can't see why/how a text layer wouldn't return text.
 
 For the modules, you can either install them in your Gimp python runtime (if you are the sole user, because it will be complicated to ask the random Gimp user to do this), or you put them in the same directory as you script file, and alter the python path  sys.path to include the path to you scripts (sys.argv[0]) before you do the import:
 
 So you have a directory in the Gimp  plug-ins directory that bears the name of your plugin (same name as the main Python file)
 
 
 
Code:
 importModule/├── importModule.py
 └── someModule.py
 Main plugin file (importModule.py)
 
 
 
Code:
 #! /bin/env python
 import os,sys
 
 whereIAm=os.path.dirname(sys.argv[0]) # find location of executed file
 
 sys.path.append(whereIAm) # add to Python path
 import someModule         # we can now import a module that's there
 
 print(someModule.variable)
 Imported library (someModule.py):
 
 
 
Code:
 variable="imported OK"  # Just to check we access this OK, so module as imported OK
 
 
 RE: translating every text layer - jacques_duflos -  07-18-2023
 
 
  (07-13-2023, 06:51 AM)Ofnuts Wrote:  Can you share an example XCF? I can't see why/how a text layer wouldn't return text.Yes, i finally could shrink my xcf enough to insert it in this forum. 
 
 RE: translating every text layer - Ofnuts -  07-19-2023
 
 They all have text for me:
 
 
 
Now it seems this is the state of the image **after** the translation script and not before.Code:
 ➤> for l in group.layers:...     dup=pdb.gimp_layer_copy(l, True)
 ...     pdb.gimp_image_insert_layer(image, dup, group, 0)
 ...     print "%s,%r" % (dup, pdb.gimp_text_layer_get_text(dup))
 ...     gimp.delete(dup)
 ...
 ...
 <gimp.Layer 'ils le feront. Ils n'ont pas l... #1'>,"ils le feront. Ils n'ont pas le choix."
 <gimp.Layer 'j'envoie le rapport d'aujourd'... #1'>,"j'envoie le rapport d'aujourd' hui, exigeant une r\xc3\xa9ponse rapide."
 <gimp.Layer 'Et la réunion ? quand est-elle... #1'>,'Et la r\xc3\xa9union\xc2\xa0? quand est-elle reprogramm\xc3\xa9e\xc2\xa0?'
 <gimp.Layer 'nos hôtes vous proposeront dem... #1'>,'nos h\xc3\xb4tes vous proposeront demain \xc3\xa0 8h'
 <gimp.Layer 'parfait. plus vite c'est mieux #1'>,"parfait. plus vite c'est mieux"
 <gimp.Layer 'ERREUR TEXTE NON TRADUIT ... #7'>,'ERREUR TEXTE NON TRADUIT\nNone'
 <gimp.Layer 'mpfff ! #1'>,'mpfff\xc2\xa0!'
 <gimp.Layer 'ERREUR TEXTE NON TRADUIT ... #8'>,'ERREUR TEXTE NON TRADUIT\nNone'
 <gimp.Layer 'qu'on me vire #1'>,"qu'on me vire"
 <gimp.Layer 'LOL. #1'>,'LOL.'
 <gimp.Layer 'pour ce qui m'importe #1'>,"pour ce qui m'importe"
 <gimp.Layer 'ERREUR TEXTE NON TRADUIT ... #9'>,'ERREUR TEXTE NON TRADUIT\nNone'
 <gimp.Layer 'ERREUR TEXTE NON TRADUIT ... #10'>,'ERREUR TEXTE NON TRADUIT\nNone'
 <gimp.Layer 'nous avons gagné du temps. vou... #1'>,"nous avons gagn\xc3\xa9 du temps. vous l'avez dit vous-m\xc3\xaame"
 <gimp.Layer 'ERREUR TEXTE NON TRADUIT ... #11'>,'ERREUR TEXTE NON TRADUIT\nNone'
 <gimp.Layer 'ERREUR TEXTE NON TRADUIT ... #12'>,'ERREUR TEXTE NON TRADUIT\nNone'
 <gimp.Layer 'ERREUR TEXTE NON TRADUIT ... #13'>,'ERREUR TEXTE NON TRADUIT\nNone'
 <gimp.Layer 'j'essaierai de ne pas vous dér... #1'>,"j'essaierai de ne pas vous d\xc3\xa9ranger. profitez de votre promenade"
 <gimp.Layer 'merci #1'>,'merci'
 <gimp.Layer 'accompagné de Rodolphe #1'>,'accompagn\xc3\xa9 de Rodolphe'
 <gimp.Layer '-- Oui, monsieur. #1'>,'-- Oui, monsieur.'
 <gimp.Layer 'contact radio #2'>,'contact radio'
 <gimp.Layer 'le palais de justice ne peut l... #1'>,"le palais de justice ne peut l'ignorer."
 ➤>
 
 Also, the input text has "tweaks" since some letters are bigger than others (ó and í), and if I use local tweaks in the text (for instance I enlarged "gagné") then this makes the text unrecoverable:
 
 
But when the text is "complex" it can be retrieved with pdb.gimp_text_layer_get_markup():Code:
 ➤> for l in group.layers:...     print "%s,%r" % (l, pdb.gimp_text_layer_get_text(l))
 ...
 <gimp.Layer 'contact radio #2'>,'contact radio'
 <gimp.Layer 'accompagné de Rodolphe #1'>,'accompagn\xc3\xa9 de Rodolphe'
 <gimp.Layer 'merci #1'>,'merci'
 <gimp.Layer 'nous avons gagné du temps. vou...'>,None
 <gimp.Layer 'pour ce qui m'importe #1'>,"pour ce qui m'importe"
 <gimp.Layer 'LOL. #1'>,'LOL.'
 <gimp.Layer 'qu'on me vire #1'>,"qu'on me vire"
 <gimp.Layer 'mpfff ! #1'>,'mpfff\xc2\xa0!'
 
 
Code:
 ➤> for l in group.layers:...     text=pdb.gimp_text_layer_get_text(l)
 ...     if text:
 ...         print "%s,%r" % (l,text)
 ...     else:
 ...         print "%s,%r" % (l, pdb.gimp_text_layer_get_markup(l))
 ...
 <gimp.Layer 'contact radio #2'>,'contact radio'
 <gimp.Layer 'accompagné de Rodolphe #1'>,'accompagn\xc3\xa9 de Rodolphe'
 <gimp.Layer 'merci #1'>,'merci'
 <gimp.Layer 'nous avons gagné du temps. vou...'>,'<markup>nous avo<span size="7618">ns </span><span size="22609">gagn\xc3\xa9</span> du temps. vous l'avez dit vous-m\xc3\xaame</markup>'
 <gimp.Layer 'pour ce qui m'importe #1'>,"pour ce qui m'importe"
 <gimp.Layer 'LOL. #1'>,'LOL.'
 <gimp.Layer 'qu'on me vire #1'>,"qu'on me vire"
 <gimp.Layer 'mpfff ! #1'>,'mpfff\xc2\xa0!'
 ➤>
 Of course, you now have to remove the markup.... (and also decode it since it seems to be UTF-8 encoded)
 
 
 RE: translating every text layer - jacques_duflos -  07-21-2023
 
 ok, so there are two functions you can use for a text layer : gimp_text_layer_get_text and gimp_text_layer_get_markup. Either one xor the other returns a string, the other returns None. There is surely a good reason for that beyond my understanding. Now I get the text this way :
 
 
 
Code:
 import re  # Récupérer le contenu texte du calque dupliqué
 text = pdb.gimp_text_layer_get_text(layer)
 if text is None :
 print ("----------text had markup-------------")
 text = pdb.gimp_text_layer_get_markup(layer)
 # quitter les markups avec une RegEx
 text= re.sub(r"<.*?>", "", text)
 And it works ! thanks for the help.
 
 about the encoding in uft-8 I don't understand what you mean. The texts you looked up are the ones returned by the translator tool. They display normally in gimp. Is "r\xc3\xa9ponse" instead of "réponse" uft-8 ? would it be better if it were uft-16 ?
 
 
 RE: translating every text layer - Ofnuts -  07-21-2023
 
 If your text layer is  "Déjà" and you retrieve the text/markup, you get 'D\xc3\xa9j\xc3\xa0'. The len() of this is 6, when Déjà is 4 characters. This is because what you got is a sequence of bytes which is the UTF-8 encoding of the Unicode representation of "Déjà" , where the  é (U+00E9) and the à (U+00E0) are replaced by their UTF-8 encodings(*), that use two bytes.
 
 This is because in Python2 plain strings are just arrays of bytes. Since Gimp supports the whole Unicode set, when you obtain a text from the Gimp API, Gimp returns the UTF-8 encoding of the text.
 
 Python2 however supports text that uses all Unicode characters, using the  unicode type, and you can convert string to unicode and vice-versa using decode() and encode() methods.
 
 So, if we go back to the text layer, and do pdb.gimp_text_layer_get_text(layer).decode('utf-8'), we get a unicode object that has a length of 4 and is u'D\xe9j\xe0', so non ASCII characters are replaced by their Unicode encoding that fits a single element of the sequence.
 
 
 
 (*) technically,  the whole string is encoded in UTF-8, but, by design, the plain ASCII characters (up to 0x7F) are UTF-8 encoded by themselves so when you are only concerned by American English not handling UTF-8 sort of works.
 
 
 RE: translating every text layer - jacques_duflos -  07-25-2023
 
 Im not sure I got it right. The function gimp_text_layer_get_text will return a uft-8 text, and it's better to decode it before using it with the function translator.translate(text) ? According to its documentation, the translator function returns a unicode text. Should I re-code it in uft-8 before using the gimp_text_layer_set_text function ? the code for getting the text, translate it and update the layer's text would look like this :
 
 
 
 
Code:
             # Récupérer le contenu texte du calque dupliquétext = pdb.gimp_text_layer_get_text(duplicate)
 if text is None :
 print ("----------text had markup-------------")
 text = pdb.gimp_text_layer_get_markup(duplicate)
 # quitter les markups avec une RegEx
 text= re.sub(r"<.*?>", "", text)
 
 # essayer de traduir
 try:
 text = text.decode("uft-8")
 translated_text = translator.translate(text).encode("uft-8")
 except Exception as e:
 translated_text = "Erreur lors de la traduction : {}".format(e)
 
 # Mettre à jour le texte du calque dupliqué avec la traduction
 pdb.gimp_text_layer_set_text(duplicate, translated_text)
 
 
 RE: translating every text layer - Ofnuts -  07-25-2023
 
 You have to decode the values returned for both text and markup.
 
 No need to re-encode, if function to set the text will check the type of the parameter (plain string\ or \unicode and do the Right Thing.
 
 But to be correct most of your code should be unicode-aware (the parts that tread the translations from file, for instance).
 
 
 RE: translating every text layer - trandoductin -  10-18-2024
 
 Thanks for this finding. I was getting None when using pdb.gimp_text_layer_get_text (and it was driving me nuts).
 This markup is when you change the color/font/size using the floating box options.
 When you change things using the tool options on the left then everything is fine.
 
 
 
 |