Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Writing a simple python plugin
#1
Brick 
Why is it so hard to create a plugin. I am trying to write a simple plugin to export the current image to a PNG file and then close the view. I am stuck at the save the image. Plugin attached.


Attached Files
.py   exportandclose.py (Size: 4.07 KB / Downloads: 9)
Reply
#2
Can't see your plug-in
Reply
#3
(Today, 08:13 AM)MrsP-from-C Wrote: Can't see your plug-in

scripts/plugins can now be attached with extension, for a .py maybe your browser is security blocking the attachment.

However it is a subject close to my heart, Gimp 3 python is complicated for the average user and any explanations are welcome.

To me the attachment looks AI generated. (I have my own script-fu (as a plugin) for exporting webp and it is a quarter the size. )

I will attach the plugin zipped in-case of a security block and in its own folder as required by Gimp 3.

Fails on the first line, the shebang is incorrect. Fix that and it does register but there are hard coded paths (specific to user)

Attached: 
.zip   exportandclose.zip (Size: 1.8 KB / Downloads: 5)
Reply
#4
Bug 
Thanks6 for the upload- it should have had the extension. Yes it is ai generated - Google does well most of the time when writing python script but has fallen completely flat on gimp plugins(He likes to think gimp2 is still a thing). Documentation seem very sparse for this. Yes the paths are hardcoded - easier than figure out what gimp can or can't do when it took hours for me to figure out how to get it to even show up. I'm trying to fixup a lot of images and the export process is so long - complicated by something has taken hold of the keyboard shortcut for export. I finally changed it. Then it comes up with a name dialog where I sometimes have to change from jpg to PNG then another dialog comes up with no buttons (weird) and I have to move this dialog slightly and the final parameter dialog comes up. Tedious.
Reply
#5
Hi,

I went through code and made a working version. I believe there's no way to close the image with Python after saving it as a PNG.

Code:
#!/usr/bin/env python3
import gi
import os
import sys
gi.require_version('Gimp', '3.0')
from gi.repository import Gio, Gimp, GLib   # noqa

HARD_CODED_PATH = 'e:\\scans\\inpic\\puzzle\\done\\new'


def export_png_file(image, gio_file, properties):
   """
   Export an image with a 'Gio.File' as a png file-type.

   image: Gimp.Image
   gio_file: Gio.File
   properties: list
       [(property str, property value)]

       from Gimp's Python Procedure Browser
       Properties (property str, property value):
       ('run-mode', Gimp.RunMode.NONINTERACTIVE)
       ('options', options)
       ('interlaced', interlaced)
       ('compression', compression)
       ('bkgd', bkgd)
       ('offs', offs)
       ('phys', phys)
       ('time', time)
       ('save-transparent', save_transparent)
       ('optimize-palette', optimize_palette)
       ('format', format)
       ('include-exif', include_exif)
       ('include-iptc', include_iptc)
       ('include-xmp', include_xmp)
       ('include-color-profile', include_color_profile)
       ('include-thumbnail', include_thumbnail)
       ('include-comment', include_comment)
   Return:
       Gimp.PDBStatusType
   """
   procedure = Gimp.get_pdb().lookup_procedure('file-png-export')
   config = procedure.create_config()

   config.set_property('image', image)
   config.set_property('file', gio_file)

   for q in properties:
       config.set_property(*q)

   result = procedure.run(config)
   return result.index(0)


def failed(procedure):
   return procedure.new_return_values(
       Gimp.PDBStatusType.CALLING_ERROR, GLib.Error()
   )


class ExportPng(Gimp.PlugIn):

   def do_query_procedures(self):
       return ['python-fu-exportPng']

   def do_create_procedure(self, name):
       procedure = Gimp.ImageProcedure.new(
           self, name, Gimp.PDBProcType.PLUGIN, self.run, None
       )
       procedure.set_image_types('*')
       procedure.set_documentation(
         'Saves file to e:/scans/inpic/puzzle/done/new/#.png\n'
         'It then closes the image.',
       )
       procedure.set_menu_label('_ExportPngClose...')
       procedure.add_menu_path('<Image>/File')
       procedure.set_attribution('Leonard', 'Leonard', '2026')
       return procedure

   def run(self, procedure, run_mode, image, n_drawables, drawables, args):
       """
       Commented-out but save for future use.
       I find this easier to use than the console.

       Pipe print statements to an error file.

       import time
       error_file = sys.stderr = sys.stdout = open("D:\\error.txt", 'a')
       _start = f"\nExportPng, {time.ctime()}"
       _end = "_" * (80 - len(_start))
       print(f"{_start}{_end}")
       """

       if image is None:
           Gimp.message('This plug-in requires an opened image.')
           return failed(procedure)

       # Get the original image filename
       image_file = image.get_file()

       if image_file:
           original_file_path = image_file.get_path()

       else:
           # Handle images that haven't been saved yet.
           Gimp.message(
               "Image has no filename.\n"
               "Please save the original file first."
           )
           return failed(procedure)

       # Use pathlib to easily handle path components.
       original_path, file_name = os.path.split(original_file_path)
       new_file_name = os.path.splitext(file_name)[0] + '.png'

       full_export_path = os.path.join(HARD_CODED_PATH, new_file_name)

       Gimp.message(f'full export path: {full_export_path}')

       # file_png_save requires a Gio.File object for GIMP 3.x
       gio_file = Gio.file_new_for_path(full_export_path)

       Gimp.message('Export file initialized.')

       # Export the visible image data.
       result = export_png_file(
               image,
               gio_file,
               [
                   ('format', 'rgba8'),
                   ('interlaced', False),
                   ('save-transparent', True),
                   ('time', False)
               ]
           )

       if result != Gimp.PDBStatusType.SUCCESS:
           return failed(procedure)

       Gimp.message('The png file was saved.')

       # error_file.close()   # Commented-out but save for future use.
       return Gimp.ValueArray.new(
           GLib.Value(Gimp.PDBStatusType.SUCCESS, None)
       )


Gimp.main(ExportPng.__gtype__, sys.argv)


Attached Files
.zip   exportpng.zip (Size: 1.95 KB / Downloads: 2)
Reply
#6
Star 
Well I got past the save file. but the close image is not working. appending fixed program


Attached Files
.zip   exportandclose.zip (Size: 1.12 KB / Downloads: 1)
Reply
#7
Heart 
Thanks - I will try it out. Close while helpful isn't too bad as you can close all images and tell it not to save any. Still would be nice. Ok tried it out - export takes some time so if you don't wait you might get an incomplete image. Image close would help here a lot, surprised there is no option for this (I found some documentation but I can't find that feature either. Thanks - It has speed-ed up my work considerably.
Reply


Forum Jump: