Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Gimp 3.0 - How to draw stuff with python scripts (pixel by pixel)
#1
I need help writing some basic script that will draw, for example, a circle, or a rectangle of randomly colored pixels, at a specified X and Y on the selected layer. For now I got this :

Code:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import gi
gi.require_version("Gimp", "3.0")
gi.require_version("GimpUi", "3.0")
gi.require_version("Gegl", "0.4")
from gi.repository import Gimp, GimpUi, Gegl, GObject, GLib
import sys


class DrawCirclePlugin(Gimp.PlugIn):

   def do_set_i18n(self, name):
       return False

   def do_query_procedures(self):
       return ["python-fu-draw-circle"]

   def do_create_procedure(self, name):
       Gegl.init(None)

       procedure = Gimp.ImageProcedure.new(
           self, name,
           Gimp.PDBProcType.PLUGIN,
           self.run,
           None,
       )

       procedure.set_image_types("*")
       procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.DRAWABLE)
       procedure.set_menu_label("Draw Circle")
       procedure.add_menu_path("<Image>/Filters/Draw")
       procedure.set_documentation(
           "Draw a filled/outlined circle of a chosen color and radius",
           "Draws a circle centred at (center_x, center_y) with the given "
           "radius, fill color, and optional stroke outline.",
           name,
       )
       procedure.set_attribution("Your Name", "Your Name", "2024")

       procedure.add_int_argument(
           "center-x", "Center X", "X coordinate of the circle center (px)",
           0, GLib.MAXINT, 100, GObject.ParamFlags.READWRITE,
       )
       procedure.add_int_argument(
           "center-y", "Center Y", "Y coordinate of the circle center (px)",
           0, GLib.MAXINT, 100, GObject.ParamFlags.READWRITE,
       )
       procedure.add_int_argument(
           "radius", "Radius", "Radius of the circle in pixels",
           1, GLib.MAXINT, 50, GObject.ParamFlags.READWRITE,
       )
       default_color = Gegl.Color.new("red")
       procedure.add_color_argument(
           "color", "Fill Color", "Color used to fill (and stroke) the circle",
           True, default_color, GObject.ParamFlags.READWRITE,
       )
       procedure.add_boolean_argument(
           "fill", "Fill circle", "Fill the interior of the circle",
           True, GObject.ParamFlags.READWRITE,
       )
       procedure.add_boolean_argument(
           "stroke", "Draw outline", "Stroke an outline around the circle",
           False, GObject.ParamFlags.READWRITE,
       )
       procedure.add_int_argument(
           "stroke-width", "Outline width", "Outline thickness in pixels",
           1, 500, 2, GObject.ParamFlags.READWRITE,
       )

       return procedure

   def run(self, procedure, run_mode, image, drawables, config, run_data):
       Gimp.message("A")
       if run_mode == Gimp.RunMode.INTERACTIVE:
           GimpUi.init("draw_circle")
           dialog = GimpUi.ProcedureDialog.new(procedure, config, "Draw Circle")
           dialog.fill(None)
           if not dialog.run():
               dialog.destroy()
               return procedure.new_return_values(
                   Gimp.PDBStatusType.CANCEL, GLib.Error()
               )
           dialog.destroy()
       drawable = drawables[0]
       image.undo_group_start()


       # draw stuff here


       image.undo_group_end()

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


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

I see that Drawable class have a method SetPixel, but in the docs it says that undo doesn't work on that. So, how to modify drawable pixels so that undo works ?
Reply


Forum Jump: