Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Photobooth "look" - python script
#3
Hi,
The code is very rough. It's output isn't very useful as is, but it runs now. I had some help with Google AI and and ChatGPT.

Code:
#!/usr/bin/env python3
import sys
import gi
import datetime

"""
# I use this when debugging. Any 'print()' statements get sent to 'file'.

# Trace errors by recording them to a file.
# If the file doesn't exist, create it.
import time
file = sys.stderr = sys.stdout = open("D:\\error.txt", 'a')
_start = f"\nPhotoBoothPro, {time.ctime()}"
_end = "_" * (80 - len(_start))
print(f"{_start}{_end}")
"""

gi.require_version('Gimp', '3.0')
gi.require_version('Gegl', '0.4')
from gi.repository import Gegl, Gimp, GLib   # noqa

STRIP_W, STRIP_H = 600, 1800
MARGIN, FRAME_H = 40, 400


def run_filter(layer, filter_, q, mode, opacity):
   """
   layer: Gimp.Layer
       Receive filter output.
   filter_: Gimp.DrawableFilter
   q: iterable
       [(property str, property value)]
   mode: Gimp.LayerMode
       Identify the layer blend mode with an enum (int).
   opacity: float
       .0 to 100.
   """
   config = filter_.get_config()

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

   filter_.set_blend_mode(mode)
   filter_.set_opacity(opacity)
   filter_.update()
   layer.append_filter(filter_)
   return filter_


def make_filter(layer, s):
   """
   Create a "Gimp.DrawableFilter" by string.

   layer: Gimp.Layer
       The filter name, e.g. 'oil-paint'.
   """
   print(f"Making filter: {s}")
   return Gimp.DrawableFilter.new(layer, f'gegl:{s}', "")


def do_color_balance(
   drawable,
   transfer_mode,
   preserve_lum,
   cyan_red,
   magenta_green,
   yellow_blue
):
   """Adjust color balance of a drawable."""
   procedure = Gimp.get_pdb().lookup_procedure('gimp-drawable-color-balance')
   config = procedure.create_config()
   config.set_property('drawable', drawable)
   config.set_property('transfer-mode', transfer_mode)
   config.set_property('preserve-lum', preserve_lum)
   config.set_property('cyan-red', cyan_red)
   config.set_property('magenta-green', magenta_green)
   config.set_property('yellow-blue', yellow_blue)
   result = procedure.run(config)
   success = result.index(0)
   return success


def apply_schneider_look(image, drawable):
   """Applies optical and chemical effects."""
   # 1. Mirror
   drawable.transform_flip_simple(Gimp.OrientationType.HORIZONTAL, True, 0)

   # Prepare arguments for Lens Distortion.
   filter_ = make_filter(drawable, 'lens-distortion')

   # 2. Schneider Optical Effects
   # Use the default filter settings, '[]', for Lens Distortion.
   run_filter(
       drawable,
       filter_,
       [],
       Gimp.LayerMode.NORMAL,
       100.
   )

   filter_ = make_filter(drawable, 'bloom')

   # Use the default filter settings, '[]', for Bloom.
   run_filter(
       drawable,
       filter_,
       [],
       Gimp.LayerMode.NORMAL,
       100.
   )

   # 3. Chemical Color Balance
   preserve_lum = True
   cyan_red = -0.15
   magenta_green = 0.10
   yellow_blue = -0.25

   do_color_balance(
       drawable,
       Gimp.TransferMode.SHADOWS,
       preserve_lum,
       cyan_red, magenta_green, yellow_blue
   )
   do_color_balance(
       drawable,
       Gimp.TransferMode.HIGHLIGHTS,
       preserve_lum,
       cyan_red, magenta_green, yellow_blue
   )
   do_color_balance(
       drawable,
       Gimp.TransferMode.MIDTONES,
       preserve_lum,
       cyan_red, magenta_green, yellow_blue
   )

   # 4. Silver Halide Grain
   filter_ = make_filter(drawable, 'noise-rgb')
   run_filter(
       drawable,
       filter_,
       [],
       Gimp.LayerMode.NORMAL,
       100.
   )


def photobooth_main_proc(
   procedure,
   run_mode,
   image,
   drawables,
   args,
   data,
):
   Gimp.context_push()
   image.undo_group_start()

   new_image = Gimp.Image.new(STRIP_W, STRIP_H, Gimp.ImageBaseType.RGB)

   Gimp.Display.new(new_image)     #

   bg_color = Gegl.Color.new('#F9F7F2')
   bg_layer = Gimp.Layer.new(
       new_image,
       'Paper Base',
       STRIP_W,
       STRIP_H,
       Gimp.ImageType.RGBA_IMAGE,
       100.,
       Gimp.LayerMode.NORMAL,
   )
   new_image.insert_layer(bg_layer, None, 0)
   Gimp.context_set_background(bg_color)
   bg_layer.fill(Gimp.FillType.BACKGROUND)

   y_offset = MARGIN

   for i in range(min(len(drawables), 4)):
       source_layer = drawables[i]
       new_frame = Gimp.Layer.new_from_drawable(source_layer, new_image)

       new_image.insert_layer(new_frame, None, -1)
       apply_schneider_look(new_image, new_frame)

       target_w = STRIP_W - MARGIN * 2
       scale_ratio = target_w / new_frame.get_width()

       new_frame.scale(
           target_w, int(new_frame.get_height() * scale_ratio), True
       )
       new_frame.set_offsets(MARGIN, y_offset)
       y_offset += FRAME_H + 15

   # Mechanical Date Stamp
   stamp_color = Gegl.Color.new('#B22222')
   date_str = datetime.datetime.now().strftime('PHOTO-ME - %d %b %Y').upper()
   Gimp.context_set_foreground(stamp_color)

   # This should work but doesn't.
   font = Gimp.Font.get_by_name('Sans-serif')

   # Text Layer logic for GIMP 3
   stamp_layer = Gimp.TextLayer.new(
       new_image,
       date_str,
       font,
       18.0,
       Gimp.Unit.pixel()
   )
   new_image.insert_layer(stamp_layer, None, 0)

   if stamp_layer:
       stamp_layer.transform_rotate_simple(
           Gimp.OrientationType.VERTICAL, True, 0, 0
       )
       # stamp_layer.set_offsets(STRIP_W - 35, STRIP_H - 450)  Needs work.
       stamp_layer.set_opacity(70.)

   Gimp.Display.new(new_image)
   image.undo_group_end()
   Gimp.context_pop()
   Gimp.displays_flush()
   return procedure.new_return_values(
       Gimp.PDBStatusType.SUCCESS, GLib.Error()
   )


class PhotoboothPro(Gimp.PlugIn):

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

   def do_create_procedure(self, name):
       procedure = Gimp.ImageProcedure.new(
           self, name, Gimp.PDBProcType.PLUGIN, photobooth_main_proc, None
       )
       procedure.set_image_types('RGB*')
       procedure.set_documentation(
           'Schneider Photobooth Pro',
           'Full analog strip recreation',
           name
       )
       procedure.set_menu_label('Schneider Photobooth Pro...')
       procedure.add_menu_path('<Image>/Filters/Artistic')
       procedure.set_attribution('Gemini', 'Gemini', '2026')
       return procedure


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


Attached Files
.zip   PhotoboothPro.zip (Size: 3.01 KB / Downloads: 3)
Reply


Messages In This Thread
RE: Photobooth "look" - python script - by gasMask - Yesterday, 02:45 PM

Forum Jump: