<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title><![CDATA[Gimp-Forum.net - Scripting questions]]></title>
		<link>https://www.gimp-forum.net/</link>
		<description><![CDATA[Gimp-Forum.net - https://www.gimp-forum.net]]></description>
		<pubDate>Sun, 19 Apr 2026 05:02:50 +0000</pubDate>
		<generator>MyBB</generator>
		<item>
			<title><![CDATA[Help converting a basic functional plugin]]></title>
			<link>https://www.gimp-forum.net/Thread-Help-converting-a-basic-functional-plugin</link>
			<pubDate>Thu, 12 Mar 2026 00:52:00 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Help-converting-a-basic-functional-plugin</guid>
			<description><![CDATA[<span style="color: #333333;">First off, I am not a coder, but I have been trying for the last year to convert a GIMP 2 plugin to GIMP 3, even trying AI and it simply just won't work for me. At my age (70+) I am really struggling to succeed with this task of understanding how to write a GIMP 3 plugin.  Years ago I somehow managed over several months to write a plugin in GIMP 2.10 to do some basic repetitive tasks, like adding solid color layers with masks, in groups and set other various parameters.  The first thing that happens in the plugin is the original image layer is copied and desaturated. <br />
<br />
I posted </span><span style="color: #333333;">here a year ago and Ofnuts kindly wrote an example showing how to desaturate the original layer.  That code worked perfectly.  I have tried for the last year to add to that plugin </span><span style="color: #333333;"><span style="color: #333333;">like trying to add solid color layers with masks, into groups and set other various parameters and have completely failed because of my lack of understanding and ineptness.  Even AI has not been able to come up with something that will show up in GIMP3.  I'm at the breaking point where I'm about to give up on using GIMP 3 and just go back to GIMP 2 so my basic plugin will work.  I am back here now asking if someone could point me to someone or a website or a forum, anything!, where they take requests or would rewrite a gimp2 plugin into gimp 3 format.  Any help would be appreciated.</span></span><br />
<span style="color: #333333;"><br />
I am really struggling with rewriting this simple task plug-in in GIMP 3 format...I can't even get anything to work or show up in the GIMP menus (nor can AI even write working code for GIMP3) even after copying the basic code from another GIMP 3 plugin example.  I'll upload my GIMP2 plugin so you can see what I'm trying to do, but I am really hoping there is a GIMP forum group somewhere that would specifically rewrite code for us non-coding users.  I just cannot simply understand how to write GIMP3 python code structure when I cannot understand the examples to do basic tasks like adding a new layer.  Thanks for any feedback you can provide or direction you can point me in.<br />
</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.gimp-forum.net/images/attachtypes/py.png" title="Python script" border="0" alt=".py" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=14305" target="_blank" title="">ColorPrep.py</a> (Size: 16.1 KB / Downloads: 59)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[<span style="color: #333333;">First off, I am not a coder, but I have been trying for the last year to convert a GIMP 2 plugin to GIMP 3, even trying AI and it simply just won't work for me. At my age (70+) I am really struggling to succeed with this task of understanding how to write a GIMP 3 plugin.  Years ago I somehow managed over several months to write a plugin in GIMP 2.10 to do some basic repetitive tasks, like adding solid color layers with masks, in groups and set other various parameters.  The first thing that happens in the plugin is the original image layer is copied and desaturated. <br />
<br />
I posted </span><span style="color: #333333;">here a year ago and Ofnuts kindly wrote an example showing how to desaturate the original layer.  That code worked perfectly.  I have tried for the last year to add to that plugin </span><span style="color: #333333;"><span style="color: #333333;">like trying to add solid color layers with masks, into groups and set other various parameters and have completely failed because of my lack of understanding and ineptness.  Even AI has not been able to come up with something that will show up in GIMP3.  I'm at the breaking point where I'm about to give up on using GIMP 3 and just go back to GIMP 2 so my basic plugin will work.  I am back here now asking if someone could point me to someone or a website or a forum, anything!, where they take requests or would rewrite a gimp2 plugin into gimp 3 format.  Any help would be appreciated.</span></span><br />
<span style="color: #333333;"><br />
I am really struggling with rewriting this simple task plug-in in GIMP 3 format...I can't even get anything to work or show up in the GIMP menus (nor can AI even write working code for GIMP3) even after copying the basic code from another GIMP 3 plugin example.  I'll upload my GIMP2 plugin so you can see what I'm trying to do, but I am really hoping there is a GIMP forum group somewhere that would specifically rewrite code for us non-coding users.  I just cannot simply understand how to write GIMP3 python code structure when I cannot understand the examples to do basic tasks like adding a new layer.  Thanks for any feedback you can provide or direction you can point me in.<br />
</span><br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.gimp-forum.net/images/attachtypes/py.png" title="Python script" border="0" alt=".py" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=14305" target="_blank" title="">ColorPrep.py</a> (Size: 16.1 KB / Downloads: 59)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[migrating 2.8 bash scripts to gimp 3]]></title>
			<link>https://www.gimp-forum.net/Thread-migrating-2-8-bash-scripts-to-gimp-3</link>
			<pubDate>Mon, 09 Mar 2026 11:53:32 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-migrating-2-8-bash-scripts-to-gimp-3</guid>
			<description><![CDATA[Hello,<br />
new to this forum I hope someone here could help me a little bit.<br />
<br />
As I upgraded from debian 12 to debian 13, gimp was upgraded to version 3.<br />
I have a set of short scripts that allowed me to invoke gimp (at least until version 2.8) from a linux bash console. Now they fail, so I have to adapt them to recent changes.<br />
<br />
The one question I still stumble on is the ability to set a drawable in my image. The former syntax does not work anymore :<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>(drawable (car(gimp-image-get-active-drawable image)))</code></div></div>
<br />
so that I can't do anything on a specific layer e.g. desaturate :<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>(gimp-drawable-desaturate drawable 0)</code></div></div>
How can I instruct gimp that, let's say, the drawable is layer [0] ?<br />
<br />
Thanks in advance,<br />
Vince.]]></description>
			<content:encoded><![CDATA[Hello,<br />
new to this forum I hope someone here could help me a little bit.<br />
<br />
As I upgraded from debian 12 to debian 13, gimp was upgraded to version 3.<br />
I have a set of short scripts that allowed me to invoke gimp (at least until version 2.8) from a linux bash console. Now they fail, so I have to adapt them to recent changes.<br />
<br />
The one question I still stumble on is the ability to set a drawable in my image. The former syntax does not work anymore :<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>(drawable (car(gimp-image-get-active-drawable image)))</code></div></div>
<br />
so that I can't do anything on a specific layer e.g. desaturate :<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>(gimp-drawable-desaturate drawable 0)</code></div></div>
How can I instruct gimp that, let's say, the drawable is layer [0] ?<br />
<br />
Thanks in advance,<br />
Vince.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Gimp 3.0 - How to draw stuff with python scripts (pixel by pixel)]]></title>
			<link>https://www.gimp-forum.net/Thread-Gimp-3-0-How-to-draw-stuff-with-python-scripts-pixel-by-pixel</link>
			<pubDate>Wed, 04 Mar 2026 17:15:02 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Gimp-3-0-How-to-draw-stuff-with-python-scripts-pixel-by-pixel</guid>
			<description><![CDATA[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 :<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/usr/bin/env python3<br />
# -*- coding: utf-8 -*-<br />
<br />
import gi<br />
gi.require_version("Gimp", "3.0")<br />
gi.require_version("GimpUi", "3.0")<br />
gi.require_version("Gegl", "0.4")<br />
from gi.repository import Gimp, GimpUi, Gegl, GObject, GLib<br />
import sys<br />
<br />
<br />
class DrawCirclePlugin(Gimp.PlugIn):<br />
<br />
    def do_set_i18n(self, name):<br />
        return False<br />
<br />
    def do_query_procedures(self):<br />
        return ["python-fu-draw-circle"]<br />
<br />
    def do_create_procedure(self, name):<br />
        Gegl.init(None)<br />
<br />
        procedure = Gimp.ImageProcedure.new(<br />
            self, name,<br />
            Gimp.PDBProcType.PLUGIN,<br />
            self.run,<br />
            None,<br />
        )<br />
<br />
        procedure.set_image_types("*")<br />
        procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.DRAWABLE)<br />
        procedure.set_menu_label("Draw Circle")<br />
        procedure.add_menu_path("&lt;Image&gt;/Filters/Draw")<br />
        procedure.set_documentation(<br />
            "Draw a filled/outlined circle of a chosen color and radius",<br />
            "Draws a circle centred at (center_x, center_y) with the given "<br />
            "radius, fill color, and optional stroke outline.",<br />
            name,<br />
        )<br />
        procedure.set_attribution("Your Name", "Your Name", "2024")<br />
<br />
        procedure.add_int_argument(<br />
            "center-x", "Center X", "X coordinate of the circle center (px)",<br />
            0, GLib.MAXINT, 100, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_int_argument(<br />
            "center-y", "Center Y", "Y coordinate of the circle center (px)",<br />
            0, GLib.MAXINT, 100, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_int_argument(<br />
            "radius", "Radius", "Radius of the circle in pixels",<br />
            1, GLib.MAXINT, 50, GObject.ParamFlags.READWRITE,<br />
        )<br />
        default_color = Gegl.Color.new("red")<br />
        procedure.add_color_argument(<br />
            "color", "Fill Color", "Color used to fill (and stroke) the circle",<br />
            True, default_color, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_boolean_argument(<br />
            "fill", "Fill circle", "Fill the interior of the circle",<br />
            True, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_boolean_argument(<br />
            "stroke", "Draw outline", "Stroke an outline around the circle",<br />
            False, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_int_argument(<br />
            "stroke-width", "Outline width", "Outline thickness in pixels",<br />
            1, 500, 2, GObject.ParamFlags.READWRITE,<br />
        )<br />
<br />
        return procedure<br />
<br />
    def run(self, procedure, run_mode, image, drawables, config, run_data):<br />
        Gimp.message("A")<br />
        if run_mode == Gimp.RunMode.INTERACTIVE:<br />
            GimpUi.init("draw_circle")<br />
            dialog = GimpUi.ProcedureDialog.new(procedure, config, "Draw Circle")<br />
            dialog.fill(None)<br />
            if not dialog.run():<br />
                dialog.destroy()<br />
                return procedure.new_return_values(<br />
                    Gimp.PDBStatusType.CANCEL, GLib.Error()<br />
                )<br />
            dialog.destroy()<br />
        drawable = drawables[0]<br />
        image.undo_group_start()<br />
<br />
<br />
        # draw stuff here<br />
<br />
<br />
        image.undo_group_end()<br />
<br />
        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())<br />
<br />
<br />
Gimp.main(DrawCirclePlugin.__gtype__, sys.argv)</code></div></div>
<br />
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 ?]]></description>
			<content:encoded><![CDATA[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 :<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/usr/bin/env python3<br />
# -*- coding: utf-8 -*-<br />
<br />
import gi<br />
gi.require_version("Gimp", "3.0")<br />
gi.require_version("GimpUi", "3.0")<br />
gi.require_version("Gegl", "0.4")<br />
from gi.repository import Gimp, GimpUi, Gegl, GObject, GLib<br />
import sys<br />
<br />
<br />
class DrawCirclePlugin(Gimp.PlugIn):<br />
<br />
    def do_set_i18n(self, name):<br />
        return False<br />
<br />
    def do_query_procedures(self):<br />
        return ["python-fu-draw-circle"]<br />
<br />
    def do_create_procedure(self, name):<br />
        Gegl.init(None)<br />
<br />
        procedure = Gimp.ImageProcedure.new(<br />
            self, name,<br />
            Gimp.PDBProcType.PLUGIN,<br />
            self.run,<br />
            None,<br />
        )<br />
<br />
        procedure.set_image_types("*")<br />
        procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.DRAWABLE)<br />
        procedure.set_menu_label("Draw Circle")<br />
        procedure.add_menu_path("&lt;Image&gt;/Filters/Draw")<br />
        procedure.set_documentation(<br />
            "Draw a filled/outlined circle of a chosen color and radius",<br />
            "Draws a circle centred at (center_x, center_y) with the given "<br />
            "radius, fill color, and optional stroke outline.",<br />
            name,<br />
        )<br />
        procedure.set_attribution("Your Name", "Your Name", "2024")<br />
<br />
        procedure.add_int_argument(<br />
            "center-x", "Center X", "X coordinate of the circle center (px)",<br />
            0, GLib.MAXINT, 100, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_int_argument(<br />
            "center-y", "Center Y", "Y coordinate of the circle center (px)",<br />
            0, GLib.MAXINT, 100, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_int_argument(<br />
            "radius", "Radius", "Radius of the circle in pixels",<br />
            1, GLib.MAXINT, 50, GObject.ParamFlags.READWRITE,<br />
        )<br />
        default_color = Gegl.Color.new("red")<br />
        procedure.add_color_argument(<br />
            "color", "Fill Color", "Color used to fill (and stroke) the circle",<br />
            True, default_color, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_boolean_argument(<br />
            "fill", "Fill circle", "Fill the interior of the circle",<br />
            True, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_boolean_argument(<br />
            "stroke", "Draw outline", "Stroke an outline around the circle",<br />
            False, GObject.ParamFlags.READWRITE,<br />
        )<br />
        procedure.add_int_argument(<br />
            "stroke-width", "Outline width", "Outline thickness in pixels",<br />
            1, 500, 2, GObject.ParamFlags.READWRITE,<br />
        )<br />
<br />
        return procedure<br />
<br />
    def run(self, procedure, run_mode, image, drawables, config, run_data):<br />
        Gimp.message("A")<br />
        if run_mode == Gimp.RunMode.INTERACTIVE:<br />
            GimpUi.init("draw_circle")<br />
            dialog = GimpUi.ProcedureDialog.new(procedure, config, "Draw Circle")<br />
            dialog.fill(None)<br />
            if not dialog.run():<br />
                dialog.destroy()<br />
                return procedure.new_return_values(<br />
                    Gimp.PDBStatusType.CANCEL, GLib.Error()<br />
                )<br />
            dialog.destroy()<br />
        drawable = drawables[0]<br />
        image.undo_group_start()<br />
<br />
<br />
        # draw stuff here<br />
<br />
<br />
        image.undo_group_end()<br />
<br />
        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, GLib.Error())<br />
<br />
<br />
Gimp.main(DrawCirclePlugin.__gtype__, sys.argv)</code></div></div>
<br />
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 ?]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Writing a simple python plugin]]></title>
			<link>https://www.gimp-forum.net/Thread-Writing-a-simple-python-plugin</link>
			<pubDate>Thu, 22 Jan 2026 02:54:45 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Writing-a-simple-python-plugin</guid>
			<description><![CDATA[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.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.gimp-forum.net/images/attachtypes/py.png" title="Python script" border="0" alt=".py" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=14207" target="_blank" title="">exportandclose.py</a> (Size: 4.07 KB / Downloads: 200)
<!-- end: postbit_attachments_attachment -->]]></description>
			<content:encoded><![CDATA[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.<br /><!-- start: postbit_attachments_attachment -->
<br /><!-- start: attachment_icon -->
<img src="https://www.gimp-forum.net/images/attachtypes/py.png" title="Python script" border="0" alt=".py" />
<!-- end: attachment_icon -->&nbsp;&nbsp;<a href="attachment.php?aid=14207" target="_blank" title="">exportandclose.py</a> (Size: 4.07 KB / Downloads: 200)
<!-- end: postbit_attachments_attachment -->]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[GIMP 3.x Python Plugin Issue: Reliable Program Exit and Image Closing]]></title>
			<link>https://www.gimp-forum.net/Thread-GIMP-3-x-Python-Plugin-Issue-Reliable-Program-Exit-and-Image-Closing</link>
			<pubDate>Fri, 12 Dec 2025 11:26:12 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-GIMP-3-x-Python-Plugin-Issue-Reliable-Program-Exit-and-Image-Closing</guid>
			<description><![CDATA[Hello GIMP Community,<br />
<br />
I am facing an issue in a GIMP 3.0 Python plugin: reliably closing the program and the last active image when the sequential workflow is finished.<br />
<br />
My script is running in the <span style="font-weight: bold;">GUI Mode</span>, and I need to perform two actions in order:<br />
<ol type="1">
<li>Close the last open image container.<br />
</li>
<li>Force GIMP to quit the application entirely.<br />
</li></ol>
The old methods from v2 do not work anymore and I am unsure if what I am trying to achieve is actually possible.<br />
<br />
Here is my script so far (German annotations):<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/usr/bin/env python3<br />
# -*- coding: utf-8 -*-<br />
<br />
import sys<br />
import gi<br />
gi.require_version('Gimp', '3.0')<br />
gi.require_version('GimpUi', '3.0')<br />
from gi.repository import Gimp, GimpUi, GObject, GLib, Gio<br />
import os<br />
import json<br />
import tempfile<br />
import traceback<br />
<br />
# Pfad für die temporäre Konfigurationsdatei<br />
CONFIG_PATH = os.path.join(tempfile.gettempdir(), 'gimp_spore_workflow_config.json')<br />
<br />
class ExportAndNextWorkflow(Gimp.PlugIn):<br />
<br />
    def do_query_procedures(self):<br />
        return ['python-fu-export-and-next']<br />
<br />
    def do_set_i18n(self, procname):<br />
        return False, 'gimp30-python', None<br />
<br />
    def do_create_procedure(self, name):<br />
        procedure = Gimp.ImageProcedure.new(<br />
            self, name,<br />
            Gimp.PDBProcType.PLUGIN,<br />
            self.run, None<br />
        )<br />
<br />
        procedure.set_image_types("*")<br />
        procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.DRAWABLE)<br />
        procedure.set_menu_label("1. Exportieren &amp; Nächstes Bild")<br />
        procedure.add_menu_path('&lt;Image&gt;/Auswahl/')<br />
<br />
        procedure.set_documentation(<br />
            "Exportiert die Auswahl, speichert W/H und lädt das nächste Bild.",<br />
            "Exportiert die aktuelle Auswahl und bereitet den nächsten Schritt vor.",<br />
            name<br />
        )<br />
        procedure.set_attribution("Author", "Author", "2024")<br />
<br />
        return procedure<br />
<br />
    # --- HILFSFUNKTIONEN ---<br />
<br />
    def load_config(self):<br />
        if os.path.exists(CONFIG_PATH):<br />
            try:<br />
                with open(CONFIG_PATH, 'r') as f:<br />
                    return json.load(f)<br />
            except:<br />
                pass<br />
        return None<br />
<br />
    def save_config(self, width, height, current_path=None):<br />
        data = {'width': int(width), 'height': int(height)}<br />
        try:<br />
            existing_data = self.load_config()<br />
            if existing_data:<br />
                data.update(existing_data)<br />
<br />
            if current_path is not None:<br />
                data['last_path'] = current_path<br />
<br />
            with open(CONFIG_PATH, 'w') as f:<br />
                json.dump(data, f, indent=4)<br />
        except Exception as e:<br />
            pass<br />
<br />
    def get_next_file(self, current_path):<br />
        directory = os.path.dirname(current_path)<br />
        basename = os.path.basename(current_path)<br />
<br />
        extensions = ('.jpg', '.jpeg', '.png', '.tif', '.tiff', '.xcf')<br />
        files = [f for f in os.listdir(directory) if f.lower().endswith(extensions)]<br />
        files.sort()<br />
<br />
        try:<br />
            index = files.index(basename)<br />
            if index + 1 &lt; len(files):<br />
                return os.path.join(directory, files[index + 1])<br />
        except ValueError:<br />
            pass<br />
<br />
        return None<br />
<br />
    # --- HAUPT-RUN-FUNKTION ---<br />
<br />
    def run(self, procedure, run_mode, image, n_drawables, drawables, config, run_data=None):<br />
<br />
        # 0. Initialisierung &amp; Auswahlprüfung<br />
        selection = image.get_selection()<br />
        success, non_empty, x1, y1, x2, y2 = selection.bounds(image)<br />
<br />
        if not non_empty:<br />
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(), "Keine Auswahl vorhanden.", 0)<br />
            return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR, error)<br />
<br />
        target_w = x2 - x1<br />
        target_h = y2 - y1<br />
<br />
        # 1. Pfad ermitteln<br />
        current_path = None<br />
        current_file = image.get_file()<br />
<br />
        if current_file is not None:<br />
            current_path = current_file.get_path()<br />
        else:<br />
            config_data = self.load_config()<br />
            if config_data and 'last_path' in config_data:<br />
                current_path = config_data['last_path']<br />
<br />
        if current_path is None:<br />
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(),<br />
                                            "Bild hat keinen Dateipfad (Konfiguration leer).", 0)<br />
            return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, error)<br />
<br />
        directory = os.path.dirname(current_path)<br />
        basename = os.path.splitext(os.path.basename(current_path))[0]<br />
<br />
        # Zielordner für Exporte definieren<br />
        target_dir = os.path.join(directory, "Auswahlen")<br />
<br />
        # --- TEIL A: EXPORTIEREN ---<br />
<br />
        try:<br />
            # 2. Zielordner erstellen (falls nicht vorhanden)<br />
            if not os.path.exists(target_dir):<br />
                os.makedirs(target_dir)<br />
<br />
            # 3. Nächste freie Export-Nummer finden (suche im Zielordner)<br />
            number = 1<br />
            while True:<br />
                new_filename = f"[{number}] {basename}.jpg"<br />
                new_filepath = os.path.join(target_dir, new_filename)<br />
                if not os.path.exists(new_filepath):<br />
                    break<br />
                number += 1<br />
<br />
            # 4. Auswahl kopieren, neues Bild erstellen, speichern<br />
            drawable = image.get_layers()[-1]<br />
            Gimp.edit_copy([drawable])<br />
            new_image = Gimp.edit_paste_as_new_image()<br />
<br />
            # Speichere direkt in den Auswahlen-Ordner<br />
            new_file = Gio.file_new_for_path(new_filepath)<br />
            Gimp.file_save(Gimp.RunMode.NONINTERACTIVE, new_image, new_file)<br />
            new_image.delete()<br />
<br />
            # 5. Auswahlgröße speichern (für Script 2)<br />
            self.save_config(target_w, target_h)<br />
<br />
        except Exception as e:<br />
            if 'new_image' in locals():<br />
                try: new_image.delete()<br />
                except: pass<br />
<br />
            error_msg = f"Fehler beim Export: {str(e)}&#92;n{traceback.format_exc()}"<br />
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(), error_msg, 0)<br />
            return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, error)<br />
<br />
        # --- TEIL B: NÄCHSTES BILD LADEN (MIT ENDPRÜFUNG) ---<br />
<br />
        # 6. Nächstes Bild ermitteln<br />
        next_path = self.get_next_file(current_path)<br />
<br />
        if not next_path:<br />
            # ENDE DER SEQUENZ ERREICHT!<br />
<br />
            # Letzten Pfad zurücksetzen.<br />
            self.save_config(target_w, target_h, current_path=None)<br />
<br />
            # Aktuelles Bild aus der Anzeige entfernen<br />
            image.delete()<br />
<br />
            # GIMP 3.0 Methode zum Aufruf der PDB-Prozedur "gimp-quit"<br />
            try:<br />
                # Korrektur: Verwendung von Gimp.TYPE_INT anstelle von GObject.TYPE_INT<br />
                Gimp.plug_in_manager_run(<br />
                    "gimp-quit",<br />
                    Gimp.RunMode.NONINTERACTIVE,<br />
                    GObject.Value.new(Gimp.TYPE_INT, 0)<br />
                )<br />
            except Exception as e:<br />
                Gimp.message(f"WARNUNG: GIMP 3.0 Quit-Aufruf fehlgeschlagen: {str(e)}")<br />
<br />
            # Korrigierter Rückgabestatus:<br />
            return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, None)<br />
<br />
        try:<br />
            # 7. Normaler Ablauf: Bild laden und Pfad speichern<br />
            new_gfile = Gio.file_new_for_path(next_path)<br />
            new_image = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE, new_gfile)<br />
<br />
            self.save_config(target_w, target_h, current_path=next_path)<br />
<br />
            # 8. Anzeige erstellen und altes Bild schließen<br />
            Gimp.Display.new(new_image)<br />
            image.delete()<br />
            Gimp.displays_flush()<br />
<br />
        except Exception as e:<br />
            error_msg = f"Fehler beim Wechseln: {str(e)}&#92;n{traceback.format_exc()}"<br />
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(), error_msg, 0)<br />
            return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, error)<br />
<br />
        # Korrigierter Rückgabestatus:<br />
        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, None)<br />
<br />
Gimp.main(ExportAndNextWorkflow.__gtype__, sys.argv)</code></div></div>
<br />
<br />
Does anyone have an idea whether what I am trying to do is possible?]]></description>
			<content:encoded><![CDATA[Hello GIMP Community,<br />
<br />
I am facing an issue in a GIMP 3.0 Python plugin: reliably closing the program and the last active image when the sequential workflow is finished.<br />
<br />
My script is running in the <span style="font-weight: bold;">GUI Mode</span>, and I need to perform two actions in order:<br />
<ol type="1">
<li>Close the last open image container.<br />
</li>
<li>Force GIMP to quit the application entirely.<br />
</li></ol>
The old methods from v2 do not work anymore and I am unsure if what I am trying to achieve is actually possible.<br />
<br />
Here is my script so far (German annotations):<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/usr/bin/env python3<br />
# -*- coding: utf-8 -*-<br />
<br />
import sys<br />
import gi<br />
gi.require_version('Gimp', '3.0')<br />
gi.require_version('GimpUi', '3.0')<br />
from gi.repository import Gimp, GimpUi, GObject, GLib, Gio<br />
import os<br />
import json<br />
import tempfile<br />
import traceback<br />
<br />
# Pfad für die temporäre Konfigurationsdatei<br />
CONFIG_PATH = os.path.join(tempfile.gettempdir(), 'gimp_spore_workflow_config.json')<br />
<br />
class ExportAndNextWorkflow(Gimp.PlugIn):<br />
<br />
    def do_query_procedures(self):<br />
        return ['python-fu-export-and-next']<br />
<br />
    def do_set_i18n(self, procname):<br />
        return False, 'gimp30-python', None<br />
<br />
    def do_create_procedure(self, name):<br />
        procedure = Gimp.ImageProcedure.new(<br />
            self, name,<br />
            Gimp.PDBProcType.PLUGIN,<br />
            self.run, None<br />
        )<br />
<br />
        procedure.set_image_types("*")<br />
        procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.DRAWABLE)<br />
        procedure.set_menu_label("1. Exportieren &amp; Nächstes Bild")<br />
        procedure.add_menu_path('&lt;Image&gt;/Auswahl/')<br />
<br />
        procedure.set_documentation(<br />
            "Exportiert die Auswahl, speichert W/H und lädt das nächste Bild.",<br />
            "Exportiert die aktuelle Auswahl und bereitet den nächsten Schritt vor.",<br />
            name<br />
        )<br />
        procedure.set_attribution("Author", "Author", "2024")<br />
<br />
        return procedure<br />
<br />
    # --- HILFSFUNKTIONEN ---<br />
<br />
    def load_config(self):<br />
        if os.path.exists(CONFIG_PATH):<br />
            try:<br />
                with open(CONFIG_PATH, 'r') as f:<br />
                    return json.load(f)<br />
            except:<br />
                pass<br />
        return None<br />
<br />
    def save_config(self, width, height, current_path=None):<br />
        data = {'width': int(width), 'height': int(height)}<br />
        try:<br />
            existing_data = self.load_config()<br />
            if existing_data:<br />
                data.update(existing_data)<br />
<br />
            if current_path is not None:<br />
                data['last_path'] = current_path<br />
<br />
            with open(CONFIG_PATH, 'w') as f:<br />
                json.dump(data, f, indent=4)<br />
        except Exception as e:<br />
            pass<br />
<br />
    def get_next_file(self, current_path):<br />
        directory = os.path.dirname(current_path)<br />
        basename = os.path.basename(current_path)<br />
<br />
        extensions = ('.jpg', '.jpeg', '.png', '.tif', '.tiff', '.xcf')<br />
        files = [f for f in os.listdir(directory) if f.lower().endswith(extensions)]<br />
        files.sort()<br />
<br />
        try:<br />
            index = files.index(basename)<br />
            if index + 1 &lt; len(files):<br />
                return os.path.join(directory, files[index + 1])<br />
        except ValueError:<br />
            pass<br />
<br />
        return None<br />
<br />
    # --- HAUPT-RUN-FUNKTION ---<br />
<br />
    def run(self, procedure, run_mode, image, n_drawables, drawables, config, run_data=None):<br />
<br />
        # 0. Initialisierung &amp; Auswahlprüfung<br />
        selection = image.get_selection()<br />
        success, non_empty, x1, y1, x2, y2 = selection.bounds(image)<br />
<br />
        if not non_empty:<br />
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(), "Keine Auswahl vorhanden.", 0)<br />
            return procedure.new_return_values(Gimp.PDBStatusType.CALLING_ERROR, error)<br />
<br />
        target_w = x2 - x1<br />
        target_h = y2 - y1<br />
<br />
        # 1. Pfad ermitteln<br />
        current_path = None<br />
        current_file = image.get_file()<br />
<br />
        if current_file is not None:<br />
            current_path = current_file.get_path()<br />
        else:<br />
            config_data = self.load_config()<br />
            if config_data and 'last_path' in config_data:<br />
                current_path = config_data['last_path']<br />
<br />
        if current_path is None:<br />
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(),<br />
                                            "Bild hat keinen Dateipfad (Konfiguration leer).", 0)<br />
            return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, error)<br />
<br />
        directory = os.path.dirname(current_path)<br />
        basename = os.path.splitext(os.path.basename(current_path))[0]<br />
<br />
        # Zielordner für Exporte definieren<br />
        target_dir = os.path.join(directory, "Auswahlen")<br />
<br />
        # --- TEIL A: EXPORTIEREN ---<br />
<br />
        try:<br />
            # 2. Zielordner erstellen (falls nicht vorhanden)<br />
            if not os.path.exists(target_dir):<br />
                os.makedirs(target_dir)<br />
<br />
            # 3. Nächste freie Export-Nummer finden (suche im Zielordner)<br />
            number = 1<br />
            while True:<br />
                new_filename = f"[{number}] {basename}.jpg"<br />
                new_filepath = os.path.join(target_dir, new_filename)<br />
                if not os.path.exists(new_filepath):<br />
                    break<br />
                number += 1<br />
<br />
            # 4. Auswahl kopieren, neues Bild erstellen, speichern<br />
            drawable = image.get_layers()[-1]<br />
            Gimp.edit_copy([drawable])<br />
            new_image = Gimp.edit_paste_as_new_image()<br />
<br />
            # Speichere direkt in den Auswahlen-Ordner<br />
            new_file = Gio.file_new_for_path(new_filepath)<br />
            Gimp.file_save(Gimp.RunMode.NONINTERACTIVE, new_image, new_file)<br />
            new_image.delete()<br />
<br />
            # 5. Auswahlgröße speichern (für Script 2)<br />
            self.save_config(target_w, target_h)<br />
<br />
        except Exception as e:<br />
            if 'new_image' in locals():<br />
                try: new_image.delete()<br />
                except: pass<br />
<br />
            error_msg = f"Fehler beim Export: {str(e)}&#92;n{traceback.format_exc()}"<br />
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(), error_msg, 0)<br />
            return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, error)<br />
<br />
        # --- TEIL B: NÄCHSTES BILD LADEN (MIT ENDPRÜFUNG) ---<br />
<br />
        # 6. Nächstes Bild ermitteln<br />
        next_path = self.get_next_file(current_path)<br />
<br />
        if not next_path:<br />
            # ENDE DER SEQUENZ ERREICHT!<br />
<br />
            # Letzten Pfad zurücksetzen.<br />
            self.save_config(target_w, target_h, current_path=None)<br />
<br />
            # Aktuelles Bild aus der Anzeige entfernen<br />
            image.delete()<br />
<br />
            # GIMP 3.0 Methode zum Aufruf der PDB-Prozedur "gimp-quit"<br />
            try:<br />
                # Korrektur: Verwendung von Gimp.TYPE_INT anstelle von GObject.TYPE_INT<br />
                Gimp.plug_in_manager_run(<br />
                    "gimp-quit",<br />
                    Gimp.RunMode.NONINTERACTIVE,<br />
                    GObject.Value.new(Gimp.TYPE_INT, 0)<br />
                )<br />
            except Exception as e:<br />
                Gimp.message(f"WARNUNG: GIMP 3.0 Quit-Aufruf fehlgeschlagen: {str(e)}")<br />
<br />
            # Korrigierter Rückgabestatus:<br />
            return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, None)<br />
<br />
        try:<br />
            # 7. Normaler Ablauf: Bild laden und Pfad speichern<br />
            new_gfile = Gio.file_new_for_path(next_path)<br />
            new_image = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE, new_gfile)<br />
<br />
            self.save_config(target_w, target_h, current_path=next_path)<br />
<br />
            # 8. Anzeige erstellen und altes Bild schließen<br />
            Gimp.Display.new(new_image)<br />
            image.delete()<br />
            Gimp.displays_flush()<br />
<br />
        except Exception as e:<br />
            error_msg = f"Fehler beim Wechseln: {str(e)}&#92;n{traceback.format_exc()}"<br />
            error = GLib.Error.new_literal(Gimp.PlugIn.error_quark(), error_msg, 0)<br />
            return procedure.new_return_values(Gimp.PDBStatusType.EXECUTION_ERROR, error)<br />
<br />
        # Korrigierter Rückgabestatus:<br />
        return procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, None)<br />
<br />
Gimp.main(ExportAndNextWorkflow.__gtype__, sys.argv)</code></div></div>
<br />
<br />
Does anyone have an idea whether what I am trying to do is possible?]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[help with running an scm script as batch from bash]]></title>
			<link>https://www.gimp-forum.net/Thread-help-with-running-an-scm-script-as-batch-from-bash</link>
			<pubDate>Wed, 10 Dec 2025 15:15:21 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-help-with-running-an-scm-script-as-batch-from-bash</guid>
			<description><![CDATA[Hello, <br />
<br />
with Gimp 2.8 I have an scm script (I found somewhere) that runs perfect on one image when called from the menu within gimp. Now I'd like to run it for a whole directory and wrote a bash script for this.<br />
<br />
It works in general, but when running the script on a single image within the Gimp, it creates a group with two layers and places this group above the original image layer. But when running it as a batch with my bash script, the original image layer is inserted within the new group.<br />
<br />
Neither grok nor chat gpt could help me successfully :-)<br />
<br />
Can you hint me what to change, so that the original image layer stays as a separate layer outside (below) the new layer-group?<br />
<br />
(B.t.w., I have literally no idea of Gimp scripting, am just capable to use and adapt a little scripts I find somewhere :-) )<br />
<br />
This is my bash script:<br />
<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/bin/bash<br />
<br />
INPUT_DIR="..."<br />
OUTPUT_SUFFIX=".xcf"<br />
BLUR=15<br />
VISIBLE="FALSE"<br />
<br />
for file in "&#36;INPUT_DIR"/*.{jpg,png,tif,bmp}; do<br />
  if [ -f "&#36;file" ]; then<br />
    output_file="&#36;{file%.*}&#36;{OUTPUT_SUFFIX}"<br />
<br />
gimp -i -b "<br />
  (let*<br />
  (<br />
    (filename &#92;"&#36;file&#92;")<br />
    (image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))<br />
<br />
    ;; Bottom layer = original image<br />
    (layer-info (gimp-image-get-layers image))<br />
    (drawable (vector-ref (cadr layer-info) 0))<br />
<br />
    ;; Extract name<br />
    (fname (car (reverse (strbreakup filename &#92;"/&#92;"))))<br />
    (basename (car (strbreakup fname &#92;".&#92;")))<br />
  )<br />
<br />
  ;; Rename to match GUI<br />
  (gimp-item-set-name drawable basename)<br />
<br />
  ;; select this layer before FS script<br />
  (gimp-image-set-active-layer image drawable)<br />
<br />
  ;; Run FS<br />
  (script-fu-hk-frequency-separation image drawable &#36;BLUR &#36;VISIBLE)<br />
<br />
  ;; Save<br />
  (gimp-xcf-save RUN-NONINTERACTIVE image drawable &#92;"&#36;output_file&#92;" &#92;"&#36;output_file&#92;")<br />
  (gimp-image-delete image)<br />
)<br />
" -b '(gimp-quit 0)'<br />
<br />
    echo "Processed: &#36;file -&gt; &#36;output_file"<br />
  fi<br />
done  </code></div></div>
<br />
This is the scm script:<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>; This plugin was tested with Gimp 2.8.3<br />
; This plugin will not work for Gimp 2.6.x because of the unknown layer group<br />
;<br />
; frequency-separartion.scm<br />
; seperates a layer or the whole visible into a<br />
; layer group with high- and low frequency parts<br />
;<br />
; This program is free software; you can redistribute it and/or modify<br />
; it under the terms of the GNU General Public License as published by<br />
; the Free Software Foundation; either version 2 of the License, or<br />
; (at your option) any later version.<br />
;<br />
; This program is distributed in the hope that it will be useful,<br />
; but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
; GNU General Public License for more details.<br />
;<br />
; You should have received a copy of the GNU General Public License<br />
; along with this program; if not, write to the Free Software<br />
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br />
;<br />
<br />
(define LList '())<br />
<br />
(define (makelist E) (list E))<br />
(define (isempty L) (null? L))<br />
(define (add E L) (cons E L))<br />
<br />
(define (Ith i L)<br />
  (if (= i 1)<br />
    (car L)<br />
    (Ith (- i 1) (cdr L))))<br />
<br />
<br />
(define (fs-set-layers-visible inImage)<br />
        (let*<br />
          (<br />
            (num-layers (length LList))<br />
            (theLayer 0)<br />
          )<br />
          (while (&gt; num-layers 0)<br />
            (set! theLayer (Ith num-layers LList))<br />
            (gimp-drawable-set-visible theLayer TRUE)<br />
            (set! num-layers (- num-layers 1))<br />
          )<br />
<br />
;          (gimp-displays-flush)<br />
          (set! LList (list))<br />
        )<br />
)<br />
<br />
(define (fs-set-layers-invisible inImage inLayer)<br />
        (let*<br />
          (<br />
            (layers (gimp-image-get-layers inImage))<br />
            (num-layers (car layers))<br />
            (layer-array (cadr layers))<br />
            (theLayer 0)<br />
          )<br />
<br />
        (while (&gt; num-layers 0)<br />
           (set! num-layers (- num-layers 1))<br />
           (set! theLayer (vector-ref layer-array num-layers))<br />
           (if (= (car (gimp-drawable-get-visible theLayer) ) TRUE)<br />
              (if (&lt;&gt; theLayer inLayer)<br />
                 (begin<br />
                   (gimp-drawable-set-visible theLayer FALSE)<br />
                   (set! LList (cons theLayer LList))<br />
                 )<br />
              )<br />
           )<br />
        )<br />
;        (gimp-displays-flush)<br />
        )<br />
)<br />
<br />
(define (script-fu-hk-frequency-separation image layer blur visible)<br />
&nbsp;&nbsp;&nbsp;&nbsp;(let*<br />
      (<br />
        ; test, whether seperating a layer group<br />
        (isgroup (car (gimp-item-is-group layer)))<br />
        ; get parent, maybe layer group<br />
        (parent (car (gimp-item-get-parent layer)))<br />
        ; get layername<br />
        (layername (car (gimp-item-get-name layer)))<br />
        ; gets position of layer<br />
        (position (car (gimp-image-get-item-position image layer)))<br />
        ; creates layergroup<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fs-layergroup (car (gimp-layer-group-new image)))<br />
        ; variables<br />
        (helplayer 0)<br />
        (lowlayer 0)<br />
        (highlayer 0)<br />
        (forceVisible 0)<br />
        (viewmode 0)<br />
        (opacity 0)<br />
      )<br />
<br />
      ; FALSE=freqsep just the layer<br />
      ; TRUE=freqsep from new visible<br />
      (if (= visible FALSE)<br />
        (begin<br />
          (if (= isgroup 1)<br />
             (begin<br />
               (set! forceVisible 1)<br />
             )<br />
             (begin<br />
               (set! forceVisible 0)<br />
             )<br />
          )<br />
        )<br />
        (begin<br />
           (set! forceVisible 1)<br />
        )<br />
      )<br />
<br />
      (gimp-image-undo-group-start image)<br />
      (if (= forceVisible 0)<br />
        (begin<br />
          (fs-set-layers-invisible image layer)<br />
        )<br />
      )<br />
      ;rename layergroup<br />
      (gimp-item-set-name fs-layergroup "frequency separation")<br />
      ;add layergroup as first to the image layer-stack<br />
&nbsp;&nbsp;&nbsp;&nbsp;  (gimp-image-insert-layer image fs-layergroup 0 0)<br />
<br />
      ; 0=freqsep just the layer<br />
      ; 1=freqsep from new visible<br />
      (if (= forceVisible 0)<br />
        (begin<br />
          (set! viewmode (car (gimp-layer-get-mode layer)))<br />
          (set! opacity (car (gimp-layer-get-opacity layer)))<br />
          (gimp-image-reorder-item image layer fs-layergroup -1)<br />
          (gimp-layer-set-mode layer NORMAL-MODE)<br />
          (gimp-layer-set-opacity layer 100)<br />
          (set! helplayer (car (gimp-layer-copy layer 1)))<br />
          (set! lowlayer (car (gimp-layer-copy layer 1)))<br />
          (gimp-drawable-set-name helplayer (string-append "help-" layername))<br />
          (gimp-drawable-set-name lowlayer (string-append "low-" layername))<br />
        )<br />
        (begin<br />
          (set! helplayer (car (gimp-layer-new-from-visible image image "helplayer")))<br />
          (set! lowlayer (car (gimp-layer-new-from-visible image image "low")))<br />
        )<br />
      )<br />
      ; adding layers to layergroup<br />
      (gimp-image-insert-layer image helplayer fs-layergroup -1)<br />
      (gimp-image-insert-layer image lowlayer fs-layergroup -1)<br />
<br />
      ; despeckle the low frequency layer<br />
      (plug-in-gauss 1 image lowlayer blur blur 1)<br />
      ; setting layer mode to get the high frequency layer<br />
      (gimp-layer-set-mode lowlayer GRAIN-EXTRACT-MODE)<br />
      ; getting the high frequency layer. that works, because the lauergroup is topmost<br />
      (set! highlayer (car (gimp-layer-new-from-visible image image (string-append "high-" layername))))<br />
      ; add it it to the layergroup<br />
      (gimp-image-insert-layer image highlayer fs-layergroup -1)<br />
      ; remove the helping layer<br />
      (gimp-image-remove-layer image helplayer)<br />
      ; make the low frequency layer normal<br />
      (gimp-layer-set-mode lowlayer NORMAL-MODE)<br />
      ; make the high frequency layer grain-merge, so the result is the image<br />
      (gimp-layer-set-mode highlayer GRAIN-MERGE-MODE)<br />
      ; put the layergroup just above the layer, that was selected<br />
      (gimp-image-reorder-item image fs-layergroup parent position)<br />
<br />
<br />
      (if (= forceVisible 0)<br />
         (begin<br />
           ; restore viewmode and opacity, now for the whole layergroup.<br />
           (gimp-layer-set-mode fs-layergroup viewmode)<br />
           (gimp-layer-set-opacity fs-layergroup opacity)<br />
           (fs-set-layers-visible image)<br />
         )<br />
      )<br />
<br />
      (gimp-image-set-active-layer image lowlayer)<br />
<br />
      (gimp-displays-flush)<br />
  &nbsp;&nbsp;&nbsp;&nbsp;  (gimp-image-undo-group-end image)<br />
  )<br />
)<br />
<br />
(script-fu-register "script-fu-hk-frequency-separation"<br />
"Frequency separation..."<br />
"frequency-separation.scm<br />
divides layer in high and low frequencies"<br />
"H.Kuhse"<br />
"H.Kuhse"<br />
"2013-01-04"<br />
"*"<br />
SF-IMAGE "Image" 0<br />
SF-DRAWABLE "Layer" 0<br />
SF-ADJUSTMENT _"Blur:" '(15 1 50 1 1 0 0)<br />
SF-TOGGLE _"from visible (instead selected layer)" 1<br />
)<br />
<br />
(script-fu-menu-register<br />
  "script-fu-hk-frequency-separation"<br />
  "&lt;Image&gt;/Filters"<br />
)</code></div></div>
]]></description>
			<content:encoded><![CDATA[Hello, <br />
<br />
with Gimp 2.8 I have an scm script (I found somewhere) that runs perfect on one image when called from the menu within gimp. Now I'd like to run it for a whole directory and wrote a bash script for this.<br />
<br />
It works in general, but when running the script on a single image within the Gimp, it creates a group with two layers and places this group above the original image layer. But when running it as a batch with my bash script, the original image layer is inserted within the new group.<br />
<br />
Neither grok nor chat gpt could help me successfully :-)<br />
<br />
Can you hint me what to change, so that the original image layer stays as a separate layer outside (below) the new layer-group?<br />
<br />
(B.t.w., I have literally no idea of Gimp scripting, am just capable to use and adapt a little scripts I find somewhere :-) )<br />
<br />
This is my bash script:<br />
<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/bin/bash<br />
<br />
INPUT_DIR="..."<br />
OUTPUT_SUFFIX=".xcf"<br />
BLUR=15<br />
VISIBLE="FALSE"<br />
<br />
for file in "&#36;INPUT_DIR"/*.{jpg,png,tif,bmp}; do<br />
  if [ -f "&#36;file" ]; then<br />
    output_file="&#36;{file%.*}&#36;{OUTPUT_SUFFIX}"<br />
<br />
gimp -i -b "<br />
  (let*<br />
  (<br />
    (filename &#92;"&#36;file&#92;")<br />
    (image (car (gimp-file-load RUN-NONINTERACTIVE filename filename)))<br />
<br />
    ;; Bottom layer = original image<br />
    (layer-info (gimp-image-get-layers image))<br />
    (drawable (vector-ref (cadr layer-info) 0))<br />
<br />
    ;; Extract name<br />
    (fname (car (reverse (strbreakup filename &#92;"/&#92;"))))<br />
    (basename (car (strbreakup fname &#92;".&#92;")))<br />
  )<br />
<br />
  ;; Rename to match GUI<br />
  (gimp-item-set-name drawable basename)<br />
<br />
  ;; select this layer before FS script<br />
  (gimp-image-set-active-layer image drawable)<br />
<br />
  ;; Run FS<br />
  (script-fu-hk-frequency-separation image drawable &#36;BLUR &#36;VISIBLE)<br />
<br />
  ;; Save<br />
  (gimp-xcf-save RUN-NONINTERACTIVE image drawable &#92;"&#36;output_file&#92;" &#92;"&#36;output_file&#92;")<br />
  (gimp-image-delete image)<br />
)<br />
" -b '(gimp-quit 0)'<br />
<br />
    echo "Processed: &#36;file -&gt; &#36;output_file"<br />
  fi<br />
done  </code></div></div>
<br />
This is the scm script:<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>; This plugin was tested with Gimp 2.8.3<br />
; This plugin will not work for Gimp 2.6.x because of the unknown layer group<br />
;<br />
; frequency-separartion.scm<br />
; seperates a layer or the whole visible into a<br />
; layer group with high- and low frequency parts<br />
;<br />
; This program is free software; you can redistribute it and/or modify<br />
; it under the terms of the GNU General Public License as published by<br />
; the Free Software Foundation; either version 2 of the License, or<br />
; (at your option) any later version.<br />
;<br />
; This program is distributed in the hope that it will be useful,<br />
; but WITHOUT ANY WARRANTY; without even the implied warranty of<br />
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the<br />
; GNU General Public License for more details.<br />
;<br />
; You should have received a copy of the GNU General Public License<br />
; along with this program; if not, write to the Free Software<br />
; Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.<br />
;<br />
<br />
(define LList '())<br />
<br />
(define (makelist E) (list E))<br />
(define (isempty L) (null? L))<br />
(define (add E L) (cons E L))<br />
<br />
(define (Ith i L)<br />
  (if (= i 1)<br />
    (car L)<br />
    (Ith (- i 1) (cdr L))))<br />
<br />
<br />
(define (fs-set-layers-visible inImage)<br />
        (let*<br />
          (<br />
            (num-layers (length LList))<br />
            (theLayer 0)<br />
          )<br />
          (while (&gt; num-layers 0)<br />
            (set! theLayer (Ith num-layers LList))<br />
            (gimp-drawable-set-visible theLayer TRUE)<br />
            (set! num-layers (- num-layers 1))<br />
          )<br />
<br />
;          (gimp-displays-flush)<br />
          (set! LList (list))<br />
        )<br />
)<br />
<br />
(define (fs-set-layers-invisible inImage inLayer)<br />
        (let*<br />
          (<br />
            (layers (gimp-image-get-layers inImage))<br />
            (num-layers (car layers))<br />
            (layer-array (cadr layers))<br />
            (theLayer 0)<br />
          )<br />
<br />
        (while (&gt; num-layers 0)<br />
           (set! num-layers (- num-layers 1))<br />
           (set! theLayer (vector-ref layer-array num-layers))<br />
           (if (= (car (gimp-drawable-get-visible theLayer) ) TRUE)<br />
              (if (&lt;&gt; theLayer inLayer)<br />
                 (begin<br />
                   (gimp-drawable-set-visible theLayer FALSE)<br />
                   (set! LList (cons theLayer LList))<br />
                 )<br />
              )<br />
           )<br />
        )<br />
;        (gimp-displays-flush)<br />
        )<br />
)<br />
<br />
(define (script-fu-hk-frequency-separation image layer blur visible)<br />
&nbsp;&nbsp;&nbsp;&nbsp;(let*<br />
      (<br />
        ; test, whether seperating a layer group<br />
        (isgroup (car (gimp-item-is-group layer)))<br />
        ; get parent, maybe layer group<br />
        (parent (car (gimp-item-get-parent layer)))<br />
        ; get layername<br />
        (layername (car (gimp-item-get-name layer)))<br />
        ; gets position of layer<br />
        (position (car (gimp-image-get-item-position image layer)))<br />
        ; creates layergroup<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(fs-layergroup (car (gimp-layer-group-new image)))<br />
        ; variables<br />
        (helplayer 0)<br />
        (lowlayer 0)<br />
        (highlayer 0)<br />
        (forceVisible 0)<br />
        (viewmode 0)<br />
        (opacity 0)<br />
      )<br />
<br />
      ; FALSE=freqsep just the layer<br />
      ; TRUE=freqsep from new visible<br />
      (if (= visible FALSE)<br />
        (begin<br />
          (if (= isgroup 1)<br />
             (begin<br />
               (set! forceVisible 1)<br />
             )<br />
             (begin<br />
               (set! forceVisible 0)<br />
             )<br />
          )<br />
        )<br />
        (begin<br />
           (set! forceVisible 1)<br />
        )<br />
      )<br />
<br />
      (gimp-image-undo-group-start image)<br />
      (if (= forceVisible 0)<br />
        (begin<br />
          (fs-set-layers-invisible image layer)<br />
        )<br />
      )<br />
      ;rename layergroup<br />
      (gimp-item-set-name fs-layergroup "frequency separation")<br />
      ;add layergroup as first to the image layer-stack<br />
&nbsp;&nbsp;&nbsp;&nbsp;  (gimp-image-insert-layer image fs-layergroup 0 0)<br />
<br />
      ; 0=freqsep just the layer<br />
      ; 1=freqsep from new visible<br />
      (if (= forceVisible 0)<br />
        (begin<br />
          (set! viewmode (car (gimp-layer-get-mode layer)))<br />
          (set! opacity (car (gimp-layer-get-opacity layer)))<br />
          (gimp-image-reorder-item image layer fs-layergroup -1)<br />
          (gimp-layer-set-mode layer NORMAL-MODE)<br />
          (gimp-layer-set-opacity layer 100)<br />
          (set! helplayer (car (gimp-layer-copy layer 1)))<br />
          (set! lowlayer (car (gimp-layer-copy layer 1)))<br />
          (gimp-drawable-set-name helplayer (string-append "help-" layername))<br />
          (gimp-drawable-set-name lowlayer (string-append "low-" layername))<br />
        )<br />
        (begin<br />
          (set! helplayer (car (gimp-layer-new-from-visible image image "helplayer")))<br />
          (set! lowlayer (car (gimp-layer-new-from-visible image image "low")))<br />
        )<br />
      )<br />
      ; adding layers to layergroup<br />
      (gimp-image-insert-layer image helplayer fs-layergroup -1)<br />
      (gimp-image-insert-layer image lowlayer fs-layergroup -1)<br />
<br />
      ; despeckle the low frequency layer<br />
      (plug-in-gauss 1 image lowlayer blur blur 1)<br />
      ; setting layer mode to get the high frequency layer<br />
      (gimp-layer-set-mode lowlayer GRAIN-EXTRACT-MODE)<br />
      ; getting the high frequency layer. that works, because the lauergroup is topmost<br />
      (set! highlayer (car (gimp-layer-new-from-visible image image (string-append "high-" layername))))<br />
      ; add it it to the layergroup<br />
      (gimp-image-insert-layer image highlayer fs-layergroup -1)<br />
      ; remove the helping layer<br />
      (gimp-image-remove-layer image helplayer)<br />
      ; make the low frequency layer normal<br />
      (gimp-layer-set-mode lowlayer NORMAL-MODE)<br />
      ; make the high frequency layer grain-merge, so the result is the image<br />
      (gimp-layer-set-mode highlayer GRAIN-MERGE-MODE)<br />
      ; put the layergroup just above the layer, that was selected<br />
      (gimp-image-reorder-item image fs-layergroup parent position)<br />
<br />
<br />
      (if (= forceVisible 0)<br />
         (begin<br />
           ; restore viewmode and opacity, now for the whole layergroup.<br />
           (gimp-layer-set-mode fs-layergroup viewmode)<br />
           (gimp-layer-set-opacity fs-layergroup opacity)<br />
           (fs-set-layers-visible image)<br />
         )<br />
      )<br />
<br />
      (gimp-image-set-active-layer image lowlayer)<br />
<br />
      (gimp-displays-flush)<br />
  &nbsp;&nbsp;&nbsp;&nbsp;  (gimp-image-undo-group-end image)<br />
  )<br />
)<br />
<br />
(script-fu-register "script-fu-hk-frequency-separation"<br />
"Frequency separation..."<br />
"frequency-separation.scm<br />
divides layer in high and low frequencies"<br />
"H.Kuhse"<br />
"H.Kuhse"<br />
"2013-01-04"<br />
"*"<br />
SF-IMAGE "Image" 0<br />
SF-DRAWABLE "Layer" 0<br />
SF-ADJUSTMENT _"Blur:" '(15 1 50 1 1 0 0)<br />
SF-TOGGLE _"from visible (instead selected layer)" 1<br />
)<br />
<br />
(script-fu-menu-register<br />
  "script-fu-hk-frequency-separation"<br />
  "&lt;Image&gt;/Filters"<br />
)</code></div></div>
]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[GIMP 3 script-fu not loading and run with error when Loaded through Console]]></title>
			<link>https://www.gimp-forum.net/Thread-GIMP-3-script-fu-not-loading-and-run-with-error-when-Loaded-through-Console</link>
			<pubDate>Thu, 04 Dec 2025 21:06:09 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-GIMP-3-script-fu-not-loading-and-run-with-error-when-Loaded-through-Console</guid>
			<description><![CDATA[new to v3 and having scripting issues.<br />
<br />
My test case is a published "hello World"script. (<a href="https://testing.developer.gimp.org/resource/writing-a-plug-in/tutorial-script-fu/" target="_blank">https://testing.developer.gimp.org/resou...script-fu/</a>)<br />
<br />
On MacOS I have given GIMP full access in system settings. I have placed this .scm in a subdirectory with the same name as the executable .scm file. In Folders, this script directory is the first listed.<br />
<br />
It does not show up when I restart GIMP.<br />
<br />
I've read that I can load it in the Console, and when I do this, I get the error:<br />
<br />
     "Error: eval: unbound variable: (/Users/mark/GIMP_scriptfu/mh_hello_world3/mh_hello_world.scm : 35)  [] "<br />
<br />
On line 35 in the script, it holds the copyright year. How is this causing this script to error out?<br />
<br />
I have tried different example scripts and am getting similar errors.<br />
<br />
I am new to this. Thanks for any help!<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/usr/bin/env gimp-script-fu-interpreter-3.0<br />
<br />
(define (script-fu-zemarmot-hello-world<br />
         image<br />
         drawables<br />
         font<br />
         compute-size<br />
         size<br />
         text)<br />
  (script-fu-use-v3)<br />
  (let* ((layer (gimp-text-layer-new image text font size UNIT-PIXEL)))<br />
<br />
    (gimp-image-undo-group-start image)<br />
<br />
    (gimp-image-insert-layer image layer -1 0)<br />
    (if (= compute-size TRUE)<br />
      (let* ((image-width (gimp-image-get-width image))<br />
             (layer-width (gimp-drawable-get-width layer)))<br />
        (begin<br />
          (set! size (* size (/ image-width layer-width)))<br />
          (gimp-text-layer-set-font-size layer size UNIT-PIXEL)<br />
        )<br />
      )<br />
    )<br />
<br />
    (gimp-image-undo-group-end image)<br />
  )<br />
)<br />
<br />
(script-fu-register-filter "script-fu-zemarmot-hello-world"<br />
  "Script-Fu v3 Hello World"<br />
  "Official Hello World Tutorial in Script-Fu v3"<br />
  "Jehan"<br />
  "Jehan, Zemarmot project"<br />
  "2025"<br />
  "*"<br />
  SF-ONE-OR-MORE-DRAWABLE<br />
  SF-FONT       "Font"               "Sans-serif"<br />
  SF-TOGGLE     "Compute Ideal Size" #f<br />
  SF-ADJUSTMENT "Font size (pixels)" '(20 1 1000 1 10 0 1)<br />
  SF-STRING     "Text"               "Hello World!"<br />
)<br />
<br />
(script-fu-menu-register "script-fu-zemarmot-hello-world" "&lt;Image&gt;/Hello W_orlds")</code></div></div>
]]></description>
			<content:encoded><![CDATA[new to v3 and having scripting issues.<br />
<br />
My test case is a published "hello World"script. (<a href="https://testing.developer.gimp.org/resource/writing-a-plug-in/tutorial-script-fu/" target="_blank">https://testing.developer.gimp.org/resou...script-fu/</a>)<br />
<br />
On MacOS I have given GIMP full access in system settings. I have placed this .scm in a subdirectory with the same name as the executable .scm file. In Folders, this script directory is the first listed.<br />
<br />
It does not show up when I restart GIMP.<br />
<br />
I've read that I can load it in the Console, and when I do this, I get the error:<br />
<br />
     "Error: eval: unbound variable: (/Users/mark/GIMP_scriptfu/mh_hello_world3/mh_hello_world.scm : 35)  [] "<br />
<br />
On line 35 in the script, it holds the copyright year. How is this causing this script to error out?<br />
<br />
I have tried different example scripts and am getting similar errors.<br />
<br />
I am new to this. Thanks for any help!<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/usr/bin/env gimp-script-fu-interpreter-3.0<br />
<br />
(define (script-fu-zemarmot-hello-world<br />
         image<br />
         drawables<br />
         font<br />
         compute-size<br />
         size<br />
         text)<br />
  (script-fu-use-v3)<br />
  (let* ((layer (gimp-text-layer-new image text font size UNIT-PIXEL)))<br />
<br />
    (gimp-image-undo-group-start image)<br />
<br />
    (gimp-image-insert-layer image layer -1 0)<br />
    (if (= compute-size TRUE)<br />
      (let* ((image-width (gimp-image-get-width image))<br />
             (layer-width (gimp-drawable-get-width layer)))<br />
        (begin<br />
          (set! size (* size (/ image-width layer-width)))<br />
          (gimp-text-layer-set-font-size layer size UNIT-PIXEL)<br />
        )<br />
      )<br />
    )<br />
<br />
    (gimp-image-undo-group-end image)<br />
  )<br />
)<br />
<br />
(script-fu-register-filter "script-fu-zemarmot-hello-world"<br />
  "Script-Fu v3 Hello World"<br />
  "Official Hello World Tutorial in Script-Fu v3"<br />
  "Jehan"<br />
  "Jehan, Zemarmot project"<br />
  "2025"<br />
  "*"<br />
  SF-ONE-OR-MORE-DRAWABLE<br />
  SF-FONT       "Font"               "Sans-serif"<br />
  SF-TOGGLE     "Compute Ideal Size" #f<br />
  SF-ADJUSTMENT "Font size (pixels)" '(20 1 1000 1 10 0 1)<br />
  SF-STRING     "Text"               "Hello World!"<br />
)<br />
<br />
(script-fu-menu-register "script-fu-zemarmot-hello-world" "&lt;Image&gt;/Hello W_orlds")</code></div></div>
]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Gimp 3.0.6 Python plug-in bug with text layer.set_color(color)?]]></title>
			<link>https://www.gimp-forum.net/Thread-Gimp-3-0-6-Python-plug-in-bug-with-text-layer-set-color-color</link>
			<pubDate>Tue, 18 Nov 2025 14:43:20 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Gimp-3-0-6-Python-plug-in-bug-with-text-layer-set-color-color</guid>
			<description><![CDATA[My environment: Apple Mac mini M2, macOS Tahoe 26.1.<br />
<br />
I want to set the color of a text layer from a Python plug-in. In Gimp 2 I used the plug-in "gimp-text-layer-set-color".<br />
<br />
In Gimp 3 I find the layer method "set_color(color)", but the color remains to be the foreground color. The same with the PDB plug-in.<br />
First try with layer method:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>textColor = Gegl.Color.new("red") # e.g.<br />
textLayer = Gimp.TextLayer.new(image, "Text", someFont, sometextSize, Gimp.Unit.pixel())<br />
textLayer.set_name("Text")<br />
textLayer.set_color(textColor)<br />
image.insert_layer(textLayer, parent, position)</code></div></div>
The text is black.<br />
Next try with pdb proc:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>textColor = Gegl.Color.new("red") # e.g.<br />
textLayer = Gimp.TextLayer.new(image, "Text", someFont, sometextSize, Gimp.Unit.pixel())<br />
textLayer.set_name("Text")<br />
pdb = Gimp.get_pdb()<br />
textLayerSetColor = pdb.lookup_procedure("gimp-text-layer-set-color")<br />
pdbConfig = textLayerSetColor.create_config()<br />
pdbConfig.set_property("layer", textLayer)<br />
pdbConfig.set_property("color", textColor)<br />
textLayerSetColor.run(pdbConfig)<br />
image.insert_layer(textLayer, parent, position)</code></div></div>
The text is black.<br />
Next try with foreground:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>textColor = Gegl.Color.new("red") # e.g.<br />
foreground = Gimp.context_get_foreground()<br />
Gimp.context_set_foreground(textColor)<br />
textLayer = Gimp.TextLayer.new(image, "Text", someFont, sometextSize, Gimp.Unit.pixel())<br />
textLayer.set_name("Text")<br />
image.insert_layer(textLayer, parent, position)<br />
Gimp.context_set_foreground(foreground)</code></div></div>
Success! The text is red.<br />
<br />
Where is the error? With my code or with Gimp?]]></description>
			<content:encoded><![CDATA[My environment: Apple Mac mini M2, macOS Tahoe 26.1.<br />
<br />
I want to set the color of a text layer from a Python plug-in. In Gimp 2 I used the plug-in "gimp-text-layer-set-color".<br />
<br />
In Gimp 3 I find the layer method "set_color(color)", but the color remains to be the foreground color. The same with the PDB plug-in.<br />
First try with layer method:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>textColor = Gegl.Color.new("red") # e.g.<br />
textLayer = Gimp.TextLayer.new(image, "Text", someFont, sometextSize, Gimp.Unit.pixel())<br />
textLayer.set_name("Text")<br />
textLayer.set_color(textColor)<br />
image.insert_layer(textLayer, parent, position)</code></div></div>
The text is black.<br />
Next try with pdb proc:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>textColor = Gegl.Color.new("red") # e.g.<br />
textLayer = Gimp.TextLayer.new(image, "Text", someFont, sometextSize, Gimp.Unit.pixel())<br />
textLayer.set_name("Text")<br />
pdb = Gimp.get_pdb()<br />
textLayerSetColor = pdb.lookup_procedure("gimp-text-layer-set-color")<br />
pdbConfig = textLayerSetColor.create_config()<br />
pdbConfig.set_property("layer", textLayer)<br />
pdbConfig.set_property("color", textColor)<br />
textLayerSetColor.run(pdbConfig)<br />
image.insert_layer(textLayer, parent, position)</code></div></div>
The text is black.<br />
Next try with foreground:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>textColor = Gegl.Color.new("red") # e.g.<br />
foreground = Gimp.context_get_foreground()<br />
Gimp.context_set_foreground(textColor)<br />
textLayer = Gimp.TextLayer.new(image, "Text", someFont, sometextSize, Gimp.Unit.pixel())<br />
textLayer.set_name("Text")<br />
image.insert_layer(textLayer, parent, position)<br />
Gimp.context_set_foreground(foreground)</code></div></div>
Success! The text is red.<br />
<br />
Where is the error? With my code or with Gimp?]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Problem with Gimp 3 Python plug-in color_argument]]></title>
			<link>https://www.gimp-forum.net/Thread-Problem-with-Gimp-3-Python-plug-in-color-argument</link>
			<pubDate>Sun, 16 Nov 2025 17:51:06 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Problem-with-Gimp-3-Python-plug-in-color-argument</guid>
			<description><![CDATA[I try to migrate my Python plug-in to decorate a jpeg photo with margin, border and description from Gimp 2 to Gimp 3.<br />
<br />
it works as intended as long as I don't add a color-argument. What is wrong with this code?<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>import sys<br />
import os<br />
from glob import glob<br />
import gi<br />
gi.require_version('Gimp', '3.0')<br />
from gi.repository import Gimp<br />
gi.require_version('GimpUi', '3.0')<br />
from gi.repository import GimpUi<br />
from gi.repository import GObject<br />
from gi.repository import GLib<br />
#from gi.repository import Gtk<br />
from gi.repository import Gio<br />
from gi.repository import Gegl<br />
<br />
...<br />
<br />
class MarginBorder(Gimp.PlugIn):<br />
  def do_query_procedures(self):<br />
    return [plugInMBProc]<br />
  def do_create_procedure(self, name):<br />
    procedure = None<br />
    if name == plugInMBProc:<br />
      procedure = Gimp.ImageProcedure.new(self, name,<br />
                                          Gimp.PDBProcType.PLUGIN,<br />
                                          margin_border_run, None)<br />
      procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.DRAWABLE |<br />
                                     Gimp.ProcedureSensitivityMask.NO_DRAWABLES)<br />
      procedure.set_menu_label("Rand und Rahmen")<br />
      procedure.set_attribution("Volker", "Volker Lenhardt", "2025")<br />
      procedure.add_menu_path("&lt;Image&gt;/Volker")<br />
      procedure.set_documentation("Volkers Rand, Rahmen und Bildtext",<br />
                                  "Fügt dem aktiven Bild die Dekorationsebenen "&#92;<br />
                                  + "Rand, Rahmen und Bildtext hinzu.",<br />
                                  None)<br />
      procedure.add_font_argument("font", # name<br />
                                  "Font", # nick<br />
                                  None, # blurb<br />
                                  True, # none_ok<br />
                                  Gimp.Font.get_by_name(<br />
                                    "URW Gothic L Book"), # default_value<br />
                                  False, # default_to_context <br />
                                  GObject.ParamFlags.READWRITE) # flags<br />
      procedure.add_string_argument("desc", # name<br />
                                    "Bildbeschreibung", # nick<br />
                                    None, # blurb<br />
                                    "Irgendwo", # value<br />
                                    GObject.ParamFlags.READWRITE) # flags<br />
      procedure.add_double_argument("marginRelation", # name<br />
                                    "Randbreite in Promille der größten Bildausdehnung", # nick<br />
                                    None, # blurb<br />
                                    0.0, # min<br />
                                    30.0, # max<br />
                                    9.0, # value<br />
                                    GObject.ParamFlags.READWRITE) # flags<br />
      procedure.add_double_argument("borderRelation", # name<br />
                                    "Rahmenbreite in Promille der größten Bildausdehnung", # nick<br />
                                    None, # blurb<br />
                                    0.0, # min<br />
                                    10.0, # max<br />
                                    1.8, # value<br />
                                    GObject.ParamFlags.READWRITE) # flags<br />
      procedure.add_color_argument("borderColor", # name<br />
                                   "Rahmenfarbe", # nick<br />
                                   None, # blurb<br />
                                   False, # has_alpha<br />
                                   Gegl.Color.new("black"), # value<br />
                                   GObject.ParamFlags.READWRITE) # flags<br />
    return procedure<br />
<br />
Gimp.main(MarginBorder.__gtype__, sys.argv)</code></div></div>
<br />
If I omit the procedure.add_color_argument all is well, but with it the plug-in doesn't even show up in Gimp.<br />
<br />
I can't find any code errors, or do you?<br />
<br />
Thanks in advance for your help.]]></description>
			<content:encoded><![CDATA[I try to migrate my Python plug-in to decorate a jpeg photo with margin, border and description from Gimp 2 to Gimp 3.<br />
<br />
it works as intended as long as I don't add a color-argument. What is wrong with this code?<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>import sys<br />
import os<br />
from glob import glob<br />
import gi<br />
gi.require_version('Gimp', '3.0')<br />
from gi.repository import Gimp<br />
gi.require_version('GimpUi', '3.0')<br />
from gi.repository import GimpUi<br />
from gi.repository import GObject<br />
from gi.repository import GLib<br />
#from gi.repository import Gtk<br />
from gi.repository import Gio<br />
from gi.repository import Gegl<br />
<br />
...<br />
<br />
class MarginBorder(Gimp.PlugIn):<br />
  def do_query_procedures(self):<br />
    return [plugInMBProc]<br />
  def do_create_procedure(self, name):<br />
    procedure = None<br />
    if name == plugInMBProc:<br />
      procedure = Gimp.ImageProcedure.new(self, name,<br />
                                          Gimp.PDBProcType.PLUGIN,<br />
                                          margin_border_run, None)<br />
      procedure.set_sensitivity_mask(Gimp.ProcedureSensitivityMask.DRAWABLE |<br />
                                     Gimp.ProcedureSensitivityMask.NO_DRAWABLES)<br />
      procedure.set_menu_label("Rand und Rahmen")<br />
      procedure.set_attribution("Volker", "Volker Lenhardt", "2025")<br />
      procedure.add_menu_path("&lt;Image&gt;/Volker")<br />
      procedure.set_documentation("Volkers Rand, Rahmen und Bildtext",<br />
                                  "Fügt dem aktiven Bild die Dekorationsebenen "&#92;<br />
                                  + "Rand, Rahmen und Bildtext hinzu.",<br />
                                  None)<br />
      procedure.add_font_argument("font", # name<br />
                                  "Font", # nick<br />
                                  None, # blurb<br />
                                  True, # none_ok<br />
                                  Gimp.Font.get_by_name(<br />
                                    "URW Gothic L Book"), # default_value<br />
                                  False, # default_to_context <br />
                                  GObject.ParamFlags.READWRITE) # flags<br />
      procedure.add_string_argument("desc", # name<br />
                                    "Bildbeschreibung", # nick<br />
                                    None, # blurb<br />
                                    "Irgendwo", # value<br />
                                    GObject.ParamFlags.READWRITE) # flags<br />
      procedure.add_double_argument("marginRelation", # name<br />
                                    "Randbreite in Promille der größten Bildausdehnung", # nick<br />
                                    None, # blurb<br />
                                    0.0, # min<br />
                                    30.0, # max<br />
                                    9.0, # value<br />
                                    GObject.ParamFlags.READWRITE) # flags<br />
      procedure.add_double_argument("borderRelation", # name<br />
                                    "Rahmenbreite in Promille der größten Bildausdehnung", # nick<br />
                                    None, # blurb<br />
                                    0.0, # min<br />
                                    10.0, # max<br />
                                    1.8, # value<br />
                                    GObject.ParamFlags.READWRITE) # flags<br />
      procedure.add_color_argument("borderColor", # name<br />
                                   "Rahmenfarbe", # nick<br />
                                   None, # blurb<br />
                                   False, # has_alpha<br />
                                   Gegl.Color.new("black"), # value<br />
                                   GObject.ParamFlags.READWRITE) # flags<br />
    return procedure<br />
<br />
Gimp.main(MarginBorder.__gtype__, sys.argv)</code></div></div>
<br />
If I omit the procedure.add_color_argument all is well, but with it the plug-in doesn't even show up in Gimp.<br />
<br />
I can't find any code errors, or do you?<br />
<br />
Thanks in advance for your help.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Gimp 3.0 get Metadata with Python]]></title>
			<link>https://www.gimp-forum.net/Thread-Gimp-3-0-get-Metadata-with-Python</link>
			<pubDate>Sat, 08 Nov 2025 17:41:14 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Gimp-3-0-get-Metadata-with-Python</guid>
			<description><![CDATA[How do I retrieve jpg metadata from a Python plug-in in Gimp 3.0?<br />
<br />
I open a jpg photo and need some metadata. With Gimp 2 and Python 2 I used the plug-in "<span style="font-size: small;"><span style="font-family: Monaco, Consolas, Courier, monospace;">gimp_image_get_metadata".</span></span><br />
My code was (abridged): <br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>import xml.etree.ElementTree as ET<br />
<br />
metadata = pdb.gimp_image_get_metadata(self.image)<br />
dateTag  = "exif.photo.datetimeoriginal"<br />
date = self.get_metadata_value(metadata, dateTag)<br />
<br />
def get_metadata_value(self, metadata,<br />
                             metadataName):<br />
  ciName = metadataName.lower()<br />
  value = ""<br />
  rootNode = ET.XML(metadata)<br />
  for tag in rootNode.findall('tag'):<br />
    if tag.attrib['name'].lower() == ciName:<br />
      value = tag.text<br />
      break<br />
  return value</code></div></div>
The plug-in isn't there any more in Gimp 3. Instead I find the class Gimp.Metadata. This class provides some methods for restricted operations, but none for my needs. I try:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>metadata = image.get_metadata()</code></div></div>
I expect to get an xml document, but I don't know how to look for it.<br />
Is there a different approach?<br />
<br />
My system: Mac mini (Apple M2), macOS Tahoe (26.0.1)<br />
My Gimp: 3.0.6<br />
My Python: 3.10<br />
<br />
<br />
<br />
<span style="font-size: small;"><span style="font-family: Arial;"> </span></span>]]></description>
			<content:encoded><![CDATA[How do I retrieve jpg metadata from a Python plug-in in Gimp 3.0?<br />
<br />
I open a jpg photo and need some metadata. With Gimp 2 and Python 2 I used the plug-in "<span style="font-size: small;"><span style="font-family: Monaco, Consolas, Courier, monospace;">gimp_image_get_metadata".</span></span><br />
My code was (abridged): <br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>import xml.etree.ElementTree as ET<br />
<br />
metadata = pdb.gimp_image_get_metadata(self.image)<br />
dateTag  = "exif.photo.datetimeoriginal"<br />
date = self.get_metadata_value(metadata, dateTag)<br />
<br />
def get_metadata_value(self, metadata,<br />
                             metadataName):<br />
  ciName = metadataName.lower()<br />
  value = ""<br />
  rootNode = ET.XML(metadata)<br />
  for tag in rootNode.findall('tag'):<br />
    if tag.attrib['name'].lower() == ciName:<br />
      value = tag.text<br />
      break<br />
  return value</code></div></div>
The plug-in isn't there any more in Gimp 3. Instead I find the class Gimp.Metadata. This class provides some methods for restricted operations, but none for my needs. I try:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>metadata = image.get_metadata()</code></div></div>
I expect to get an xml document, but I don't know how to look for it.<br />
Is there a different approach?<br />
<br />
My system: Mac mini (Apple M2), macOS Tahoe (26.0.1)<br />
My Gimp: 3.0.6<br />
My Python: 3.10<br />
<br />
<br />
<br />
<span style="font-size: small;"><span style="font-family: Arial;"> </span></span>]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Get layer by uncompressed size with script]]></title>
			<link>https://www.gimp-forum.net/Thread-Get-layer-by-uncompressed-size-with-script</link>
			<pubDate>Tue, 02 Sep 2025 16:40:48 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Get-layer-by-uncompressed-size-with-script</guid>
			<description><![CDATA[Hi all <img src="https://www.gimp-forum.net/images/smilies/smile.png" alt="Smile" title="Smile" class="smilie smilie_1" /> ! <br />
<br />
With Gimp, the most part of time I works on photos to simply add extra layers and export the result (maps, explanations, mechanisms, and so).<br />
<br />
In this case I do not alter the original and keep it.<br />
<br />
Recently I realized the most part of my XCF projects take more than 20MB per file vs the originals which take 2MB max.<br />
<br />
After digging I understood the problem : projects keep the original raw uncompressed photo on a layer which is a waste of storage as I can include again the original.<br />
<br />
In definitive I want to keep the original photo, the exported one and all that allowed to obtain the exported result.<br />
<br />
I imagined an external batch process to open the targeted files, remove the usefulness layer, archive the original with the lighted project.<br />
<br />
I discovered <span style="font-weight: bold;">script-fu</span> language (LISP scheme) and followed <a href="https://docs.gimp.org/3.0/en/gimp-using-script-fu-tutorial.html" target="_blank">tutorial script-fu</a> and experimented it with success.<br />
<br />
But I did not found a way to achieve this : <span style="font-weight: bold;">get the uncompressed layer size</span><br />
<br />
I found the following procedures which are not "size related" :<br />
- <span style="font-weight: bold;">gimp-image-get-layer-by-name</span><br />
- <span style="font-weight: bold;">gimp-image-get-layer-by-tattoo</span><br />
<br />
Is it possible to do this with script-fu ? Is it possible in another way ?<br />
<br />
Extra question, is there a way to attach a file to a XCF project (I suppose no) like we usually do it with the email attachments method ? I hoped this could be achieved with an add-on ... <br />
<br />
<br />
Thank you in advance for the time you will spend to me <img src="https://www.gimp-forum.net/images/smilies/wink.png" border="0" alt="[Image: wink.png]" /> .<br />
<br />
With adelphity<br />
lnj]]></description>
			<content:encoded><![CDATA[Hi all <img src="https://www.gimp-forum.net/images/smilies/smile.png" alt="Smile" title="Smile" class="smilie smilie_1" /> ! <br />
<br />
With Gimp, the most part of time I works on photos to simply add extra layers and export the result (maps, explanations, mechanisms, and so).<br />
<br />
In this case I do not alter the original and keep it.<br />
<br />
Recently I realized the most part of my XCF projects take more than 20MB per file vs the originals which take 2MB max.<br />
<br />
After digging I understood the problem : projects keep the original raw uncompressed photo on a layer which is a waste of storage as I can include again the original.<br />
<br />
In definitive I want to keep the original photo, the exported one and all that allowed to obtain the exported result.<br />
<br />
I imagined an external batch process to open the targeted files, remove the usefulness layer, archive the original with the lighted project.<br />
<br />
I discovered <span style="font-weight: bold;">script-fu</span> language (LISP scheme) and followed <a href="https://docs.gimp.org/3.0/en/gimp-using-script-fu-tutorial.html" target="_blank">tutorial script-fu</a> and experimented it with success.<br />
<br />
But I did not found a way to achieve this : <span style="font-weight: bold;">get the uncompressed layer size</span><br />
<br />
I found the following procedures which are not "size related" :<br />
- <span style="font-weight: bold;">gimp-image-get-layer-by-name</span><br />
- <span style="font-weight: bold;">gimp-image-get-layer-by-tattoo</span><br />
<br />
Is it possible to do this with script-fu ? Is it possible in another way ?<br />
<br />
Extra question, is there a way to attach a file to a XCF project (I suppose no) like we usually do it with the email attachments method ? I hoped this could be achieved with an add-on ... <br />
<br />
<br />
Thank you in advance for the time you will spend to me <img src="https://www.gimp-forum.net/images/smilies/wink.png" border="0" alt="[Image: wink.png]" /> .<br />
<br />
With adelphity<br />
lnj]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Bucket fill whole selection in Python-fu]]></title>
			<link>https://www.gimp-forum.net/Thread-Bucket-fill-whole-selection-in-Python-fu</link>
			<pubDate>Thu, 21 Aug 2025 21:45:03 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Bucket-fill-whole-selection-in-Python-fu</guid>
			<description><![CDATA[Hi,<br />
<br />
This is a very simple problem, but when I try a bucket fill through a Python-fu call, I always get a "Fill similar colors" result when I need "Fill whole selection". I can't seem to find the relevant setting in the listed context setters for the procedure (I'm looking <a href="https://lazka.github.io/pgi-docs/#Gimp-3.0/classes/Drawable.html#Gimp.Drawable.edit_bucket_fill" target="_blank">here</a>). What am I missing?<br />
<br />
Thank you!]]></description>
			<content:encoded><![CDATA[Hi,<br />
<br />
This is a very simple problem, but when I try a bucket fill through a Python-fu call, I always get a "Fill similar colors" result when I need "Fill whole selection". I can't seem to find the relevant setting in the listed context setters for the procedure (I'm looking <a href="https://lazka.github.io/pgi-docs/#Gimp-3.0/classes/Drawable.html#Gimp.Drawable.edit_bucket_fill" target="_blank">here</a>). What am I missing?<br />
<br />
Thank you!]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Python "no return values, shouldn't happen"]]></title>
			<link>https://www.gimp-forum.net/Thread-Python-no-return-values-shouldn-t-happen</link>
			<pubDate>Mon, 18 Aug 2025 21:55:34 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Python-no-return-values-shouldn-t-happen</guid>
			<description><![CDATA[I'm creating a python script to load a custom image format (.PRS with the magic string "YB").  But I'm having trouble getting even a skeleton file loading plugin to work.  This is what I've been able to reduce my code down to:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/usr/bin/env python3<br />
# -*- coding: utf-8 -*-<br />
<br />
import gi<br />
gi.require_version('Gimp', '3.0')<br />
from gi.repository import Gimp, GObject<br />
import sys<br />
<br />
load_proc = "file-prs-load"<br />
plugin_binary = "file-prs"<br />
<br />
class PrsLoader(Gimp.PlugIn):<br />
    def do_query_procedures(self):<br />
        return [load_proc]<br />
    <br />
    def do_create_procedure(self, name):<br />
        procedure = None<br />
        <br />
        if name == load_proc:<br />
            procedure = Gimp.LoadProcedure.new(self, name,<br />
                                                Gimp.PDBProcType.PLUGIN,<br />
                                                self.PrsLoad, None)<br />
            procedure.set_menu_label("PRS image")<br />
            procedure.set_attribution("Nathan", "Nathan", "2025")<br />
            procedure.set_menu_label("PRS image")<br />
            procedure.set_documentation("Loads files of PRS file format",<br />
                                        "Loads files of PRS file format",<br />
                                        None)<br />
            procedure.set_mime_types("image/prs")<br />
            procedure.set_extensions("prs")<br />
            procedure.set_magics("0,string,YB")<br />
        return procedure<br />
    <br />
    def PrsLoad(self, procedure, run_mode, file, metadata, flags, config, run_data):<br />
        print("PrsLoad called")<br />
<br />
        #Return dummy image for now<br />
        image = Gimp.Image.new(100, 100, Gimp.ImageBaseType.RGB)<br />
<br />
        return_vals = procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, None)<br />
        val = GObject.Value(Gimp.Image.__gtype__, image)<br />
        return_vals.append(val)<br />
<br />
        return return_vals<br />
<br />
Gimp.main(PrsLoader.__gtype__, sys.argv)</code></div></div>
<br />
When I try to open a PRS image file, I get the following errors:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>GIMP Message<br />
Opening '/home/nathan/Pictures/tree2b.prs' failed:<br />
PRS image plug-in could not open image</code></div></div>
<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>[nathan@TARDIS file-prs]&#36; gimp<br />
set device 'Wayland Pointer' to mode: disabled<br />
[file-prs-load] The catalog directory does not exist: /home/nathan/.config/GIMP/3.0/plug-ins/file-prs/locale<br />
[file-prs-load] Override method set_i18n() for the plug-in to customize or disable localization.<br />
[file-prs-load] Localization disabled<br />
env: ‘gjs’: No such file or directory<br />
gimp: LibGimpBase-WARNING: gimp: gimp_wire_read(): unexpected EOF<br />
[file-prs-load] The catalog directory does not exist: /home/nathan/.config/GIMP/3.0/plug-ins/file-prs/locale<br />
[file-prs-load] Override method set_i18n() for the plug-in to customize or disable localization.<br />
[file-prs-load] Localization disabled<br />
[file-prs-load] The catalog directory does not exist: /home/nathan/.config/GIMP/3.0/plug-ins/file-prs/locale<br />
[file-prs-load] Override method set_i18n() for the plug-in to customize or disable localization.<br />
[file-prs-load] Localization disabled<br />
PrsLoad called<br />
<br />
(file-prs.py:2595385): LibGimp-WARNING **: 17:46:44.730: _gimp_procedure_run_array: no return values, shouldn't happen<br />
/home/nathan/.config/GIMP/3.0/plug-ins/file-prs/file-prs.py:46: Warning: g_error_new: assertion 'domain != 0' failed<br />
  Gimp.main(PrsLoader.__gtype__, sys.argv)<br />
INFO: a stray image seems to have been left around by a plug-in: "[Untitled]"[nathan@TARDIS file-prs]&#36;</code></div></div>
<br />
I'm not too worried about the localization messages at this time.]]></description>
			<content:encoded><![CDATA[I'm creating a python script to load a custom image format (.PRS with the magic string "YB").  But I'm having trouble getting even a skeleton file loading plugin to work.  This is what I've been able to reduce my code down to:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>#!/usr/bin/env python3<br />
# -*- coding: utf-8 -*-<br />
<br />
import gi<br />
gi.require_version('Gimp', '3.0')<br />
from gi.repository import Gimp, GObject<br />
import sys<br />
<br />
load_proc = "file-prs-load"<br />
plugin_binary = "file-prs"<br />
<br />
class PrsLoader(Gimp.PlugIn):<br />
    def do_query_procedures(self):<br />
        return [load_proc]<br />
    <br />
    def do_create_procedure(self, name):<br />
        procedure = None<br />
        <br />
        if name == load_proc:<br />
            procedure = Gimp.LoadProcedure.new(self, name,<br />
                                                Gimp.PDBProcType.PLUGIN,<br />
                                                self.PrsLoad, None)<br />
            procedure.set_menu_label("PRS image")<br />
            procedure.set_attribution("Nathan", "Nathan", "2025")<br />
            procedure.set_menu_label("PRS image")<br />
            procedure.set_documentation("Loads files of PRS file format",<br />
                                        "Loads files of PRS file format",<br />
                                        None)<br />
            procedure.set_mime_types("image/prs")<br />
            procedure.set_extensions("prs")<br />
            procedure.set_magics("0,string,YB")<br />
        return procedure<br />
    <br />
    def PrsLoad(self, procedure, run_mode, file, metadata, flags, config, run_data):<br />
        print("PrsLoad called")<br />
<br />
        #Return dummy image for now<br />
        image = Gimp.Image.new(100, 100, Gimp.ImageBaseType.RGB)<br />
<br />
        return_vals = procedure.new_return_values(Gimp.PDBStatusType.SUCCESS, None)<br />
        val = GObject.Value(Gimp.Image.__gtype__, image)<br />
        return_vals.append(val)<br />
<br />
        return return_vals<br />
<br />
Gimp.main(PrsLoader.__gtype__, sys.argv)</code></div></div>
<br />
When I try to open a PRS image file, I get the following errors:<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>GIMP Message<br />
Opening '/home/nathan/Pictures/tree2b.prs' failed:<br />
PRS image plug-in could not open image</code></div></div>
<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>[nathan@TARDIS file-prs]&#36; gimp<br />
set device 'Wayland Pointer' to mode: disabled<br />
[file-prs-load] The catalog directory does not exist: /home/nathan/.config/GIMP/3.0/plug-ins/file-prs/locale<br />
[file-prs-load] Override method set_i18n() for the plug-in to customize or disable localization.<br />
[file-prs-load] Localization disabled<br />
env: ‘gjs’: No such file or directory<br />
gimp: LibGimpBase-WARNING: gimp: gimp_wire_read(): unexpected EOF<br />
[file-prs-load] The catalog directory does not exist: /home/nathan/.config/GIMP/3.0/plug-ins/file-prs/locale<br />
[file-prs-load] Override method set_i18n() for the plug-in to customize or disable localization.<br />
[file-prs-load] Localization disabled<br />
[file-prs-load] The catalog directory does not exist: /home/nathan/.config/GIMP/3.0/plug-ins/file-prs/locale<br />
[file-prs-load] Override method set_i18n() for the plug-in to customize or disable localization.<br />
[file-prs-load] Localization disabled<br />
PrsLoad called<br />
<br />
(file-prs.py:2595385): LibGimp-WARNING **: 17:46:44.730: _gimp_procedure_run_array: no return values, shouldn't happen<br />
/home/nathan/.config/GIMP/3.0/plug-ins/file-prs/file-prs.py:46: Warning: g_error_new: assertion 'domain != 0' failed<br />
  Gimp.main(PrsLoader.__gtype__, sys.argv)<br />
INFO: a stray image seems to have been left around by a plug-in: "[Untitled]"[nathan@TARDIS file-prs]&#36;</code></div></div>
<br />
I'm not too worried about the localization messages at this time.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[gegl filters in batch processing]]></title>
			<link>https://www.gimp-forum.net/Thread-gegl-filters-in-batch-processing</link>
			<pubDate>Sun, 10 Aug 2025 20:18:42 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-gegl-filters-in-batch-processing</guid>
			<description><![CDATA[I am trying to call a gegl edge detect filter repeatedly in a while loop as here<br />
<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>        (while (not (null? filepaths))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;some stuff&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (gimp-drawable-merge-new-filter<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2                         ; The drawable to apply the filter to<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"gegl:edge"                        ; The name of the GEGL operation<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0                                  ; The merge-mode (0 for normal)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LAYER-MODE-REPLACE                 ; The layer mode (e.g., replace, normal, etc.)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;100.0                              ; The opacity (0.0 to 100.0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"amount" 2.0                       ; Parameter: amount of edge detection<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"border-behavior" "none"           ; Parameter: how to handle image borders<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"algorithm" "sobel"                ; Parameter: the edge detection algorithm<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;some more stuff<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</code></div></div>
 it works but only on the first image in the batch. Is there something I need to do to get it to work on all the images?]]></description>
			<content:encoded><![CDATA[I am trying to call a gegl edge detect filter repeatedly in a while loop as here<br />
<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>        (while (not (null? filepaths))&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ;some stuff&nbsp;&nbsp;&nbsp;&nbsp;<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (gimp-drawable-merge-new-filter<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2                         ; The drawable to apply the filter to<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"gegl:edge"                        ; The name of the GEGL operation<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0                                  ; The merge-mode (0 for normal)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;LAYER-MODE-REPLACE                 ; The layer mode (e.g., replace, normal, etc.)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;100.0                              ; The opacity (0.0 to 100.0)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"amount" 2.0                       ; Parameter: amount of edge detection<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"border-behavior" "none"           ; Parameter: how to handle image borders<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"algorithm" "sobel"                ; Parameter: the edge detection algorithm<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;;some more stuff<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;)</code></div></div>
 it works but only on the first image in the batch. Is there something I need to do to get it to work on all the images?]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[file-glob always returns an empty list]]></title>
			<link>https://www.gimp-forum.net/Thread-file-glob-always-returns-an-empty-list</link>
			<pubDate>Sat, 09 Aug 2025 22:31:17 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-file-glob-always-returns-an-empty-list</guid>
			<description><![CDATA[Hi, I just set out to write a tinyscheme script that retrieves the list of files from a folder using file-glob and although it looks trivial I can't get it to work. <br />
<br />
the line in question is:<br />
<br />
(let* (filepaths (cadr (file-glob (string-append input-path "*.png") 0))))<br />
<br />
which always returns empty whether I place it in a script or type a version into the console. Gimp just tells me that parameter 1 to cdr needs to be a pair.<br />
Yes, I have verified that the folder pointed to by input-path exists and that there is at least one png file in it.Permissions are ok (I can load the file explicitly)<br />
I have tried unix style and windows style path separator: nothing works.<br />
<br />
I can hardly believe something this fundamental is actually broken - is there something about my setup that is wrong? I have a standard 3.04 installation using the windows installer any insights are appreciated.]]></description>
			<content:encoded><![CDATA[Hi, I just set out to write a tinyscheme script that retrieves the list of files from a folder using file-glob and although it looks trivial I can't get it to work. <br />
<br />
the line in question is:<br />
<br />
(let* (filepaths (cadr (file-glob (string-append input-path "*.png") 0))))<br />
<br />
which always returns empty whether I place it in a script or type a version into the console. Gimp just tells me that parameter 1 to cdr needs to be a pair.<br />
Yes, I have verified that the folder pointed to by input-path exists and that there is at least one png file in it.Permissions are ok (I can load the file explicitly)<br />
I have tried unix style and windows style path separator: nothing works.<br />
<br />
I can hardly believe something this fundamental is actually broken - is there something about my setup that is wrong? I have a standard 3.04 installation using the windows installer any insights are appreciated.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Gimp 3.0.4 python batch interpreter oddities]]></title>
			<link>https://www.gimp-forum.net/Thread-Gimp-3-0-4-python-batch-interpreter-oddities</link>
			<pubDate>Sat, 09 Aug 2025 11:47:12 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Gimp-3-0-4-python-batch-interpreter-oddities</guid>
			<description><![CDATA[Hi,<br />
<br />
I use the python-fu-eval batch interpreter on GIMP 3.0.4 AppImage and have noticed some unexpected behaviour. As a trivial example,<br />
<br />
<br />
User:~&#36; ~/AppImages/gimp/GIMP-3.0.4-x86_64.AppImage -i --quit --batch-interpreter=python-fu-eval -b 'if True: a="something"; print(a);'<br />
something<br />
batch command executed successfully<br />
<br />
<br />
But if the "if" statement comes after the declaration of variable "a"<br />
<br />
User:~&#36; ~/AppImages/gimp/GIMP-3.0.4-x86_64.AppImage -i --quit --batch-interpreter=python-fu-eval -b 'a="something";if True: print(a);'<br />
batch command experienced a calling error:<br />
Traceback (most recent call last):<br />
  File "/tmp/.mount_GIMP-3bPBAmP/usr/lib/x86_64-linux-gnu/gimp/3.0/plug-ins/python-eval/python-eval.py", line 42, in code_eval<br />
    exec(code, globals())<br />
  File "&lt;string&gt;", line 1<br />
    a="something";if True: print(a);<br />
                             ^^<br />
SyntaxError: invalid syntax<br />
<br />
Similar problems arise with a "with" statement. <br />
<br />
I don't understand this. Has anyone else noticed this sort of behaviour?<br />
<br />
My OS is linux 6.1.0-37-amd64<br />
<br />
Thanks.]]></description>
			<content:encoded><![CDATA[Hi,<br />
<br />
I use the python-fu-eval batch interpreter on GIMP 3.0.4 AppImage and have noticed some unexpected behaviour. As a trivial example,<br />
<br />
<br />
User:~&#36; ~/AppImages/gimp/GIMP-3.0.4-x86_64.AppImage -i --quit --batch-interpreter=python-fu-eval -b 'if True: a="something"; print(a);'<br />
something<br />
batch command executed successfully<br />
<br />
<br />
But if the "if" statement comes after the declaration of variable "a"<br />
<br />
User:~&#36; ~/AppImages/gimp/GIMP-3.0.4-x86_64.AppImage -i --quit --batch-interpreter=python-fu-eval -b 'a="something";if True: print(a);'<br />
batch command experienced a calling error:<br />
Traceback (most recent call last):<br />
  File "/tmp/.mount_GIMP-3bPBAmP/usr/lib/x86_64-linux-gnu/gimp/3.0/plug-ins/python-eval/python-eval.py", line 42, in code_eval<br />
    exec(code, globals())<br />
  File "&lt;string&gt;", line 1<br />
    a="something";if True: print(a);<br />
                             ^^<br />
SyntaxError: invalid syntax<br />
<br />
Similar problems arise with a "with" statement. <br />
<br />
I don't understand this. Has anyone else noticed this sort of behaviour?<br />
<br />
My OS is linux 6.1.0-37-amd64<br />
<br />
Thanks.]]></content:encoded>
		</item>
		<item>
			<title><![CDATA["Simple" python script in gimp 3]]></title>
			<link>https://www.gimp-forum.net/Thread-Simple-python-script-in-gimp-3</link>
			<pubDate>Mon, 28 Jul 2025 06:08:13 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Simple-python-script-in-gimp-3</guid>
			<description><![CDATA[Hello!<br />
For a game I'd like to create tiles for tileset. The task is simple: get a image with 3+ layers (colors, and heightmap), for each layer create 3 copy, rotate it 60, 180 ,270 degree and offset it 1*,2*,3* width.<br />
After get the heightmap layer duplicate it, add noise and call the normal map filter. (there are some masking, etc). Get the color layers, add some nose. Flattering down each group of layers.<br />
Because I'd like to use it many times, i created (or try to create) a plugin for it.<br />
Looks like easy.<br />
<br />
The problems: because its a python, you need to test is, for the typos too. so each iteration need to restart gimp load the image test the script.<br />
There are no usable documentation. I already found the <a href="https://lazka.github.io/pgi-docs/#Gimp-3.0" target="_blank">https://lazka.github.io/pgi-docs/#Gimp-3.0</a>, helped a lot, but lack of examples. all examples for the gimp 2.x<br />
For example, how can I do filter-&gt;generic-&gt;normal map?<br />
There are some undocumented "features": If you rename a layer, in the gimp UI the name stay the old one (its not a big problem) but after you cant export it into .ora and gimp went some unstable state. If remove a layer from image cant add it again to it, because already had.<br />
<br />
Now I have 300+ line of code for that "simple" task, about quarter are dead code ("maybe that work") and not working well:<br />
<br />
- after I call &lt;layer&gt;.transform_rotate_simple(rotate_angle,True,0,0) its stay is "floating selection transform" state and somehow need to anchor it how?<br />
- how can I proper call the filters-&gt;generic-&gt;normal map filter with preset or how set the values?<br />
- how can I proper call the filters-&gt;noise-&gt;hsv filter with preset or how set the values?<br />
- how can I invert selection?<br />
- how can I proper generate greyscale noise between color rgb(123,123,123) and rgb  (133,133,133), I tried the buffer.set(rect, "RGBA u8", bytes(pixels)) with pixels.extend([gray, gray, gray, 255]) it's worked, but not get the right color (I get lighter about  rgb(180,180,180), now I use set_pixel but its slow for 64x64 images<br />
- from where can I get some useful examples for gimp 3 python scripting?<br />
<br />
Thanx]]></description>
			<content:encoded><![CDATA[Hello!<br />
For a game I'd like to create tiles for tileset. The task is simple: get a image with 3+ layers (colors, and heightmap), for each layer create 3 copy, rotate it 60, 180 ,270 degree and offset it 1*,2*,3* width.<br />
After get the heightmap layer duplicate it, add noise and call the normal map filter. (there are some masking, etc). Get the color layers, add some nose. Flattering down each group of layers.<br />
Because I'd like to use it many times, i created (or try to create) a plugin for it.<br />
Looks like easy.<br />
<br />
The problems: because its a python, you need to test is, for the typos too. so each iteration need to restart gimp load the image test the script.<br />
There are no usable documentation. I already found the <a href="https://lazka.github.io/pgi-docs/#Gimp-3.0" target="_blank">https://lazka.github.io/pgi-docs/#Gimp-3.0</a>, helped a lot, but lack of examples. all examples for the gimp 2.x<br />
For example, how can I do filter-&gt;generic-&gt;normal map?<br />
There are some undocumented "features": If you rename a layer, in the gimp UI the name stay the old one (its not a big problem) but after you cant export it into .ora and gimp went some unstable state. If remove a layer from image cant add it again to it, because already had.<br />
<br />
Now I have 300+ line of code for that "simple" task, about quarter are dead code ("maybe that work") and not working well:<br />
<br />
- after I call &lt;layer&gt;.transform_rotate_simple(rotate_angle,True,0,0) its stay is "floating selection transform" state and somehow need to anchor it how?<br />
- how can I proper call the filters-&gt;generic-&gt;normal map filter with preset or how set the values?<br />
- how can I proper call the filters-&gt;noise-&gt;hsv filter with preset or how set the values?<br />
- how can I invert selection?<br />
- how can I proper generate greyscale noise between color rgb(123,123,123) and rgb  (133,133,133), I tried the buffer.set(rect, "RGBA u8", bytes(pixels)) with pixels.extend([gray, gray, gray, 255]) it's worked, but not get the right color (I get lighter about  rgb(180,180,180), now I use set_pixel but its slow for 64x64 images<br />
- from where can I get some useful examples for gimp 3 python scripting?<br />
<br />
Thanx]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Python Snippets for GIMP 3]]></title>
			<link>https://www.gimp-forum.net/Thread-Python-Snippets-for-GIMP-3</link>
			<pubDate>Sat, 19 Jul 2025 13:21:40 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Python-Snippets-for-GIMP-3</guid>
			<description><![CDATA[Hi all,<br />
<br />
I’m familiar with Script-Fu, but I know nothing about Python scripting. (GIMP 3)<br />
I’m testing a macro system and would really appreciate some small, self-contained Python snippets that can run with a button press, just something minimal to confirm it's working. <br />
<br />
Any suggestions or examples would be cool.<br />
<br />
Thanks!]]></description>
			<content:encoded><![CDATA[Hi all,<br />
<br />
I’m familiar with Script-Fu, but I know nothing about Python scripting. (GIMP 3)<br />
I’m testing a macro system and would really appreciate some small, self-contained Python snippets that can run with a button press, just something minimal to confirm it's working. <br />
<br />
Any suggestions or examples would be cool.<br />
<br />
Thanks!]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[edit_paste pastes at incorrect location after scaling]]></title>
			<link>https://www.gimp-forum.net/Thread-edit-paste-pastes-at-incorrect-location-after-scaling</link>
			<pubDate>Thu, 17 Jul 2025 13:41:38 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-edit-paste-pastes-at-incorrect-location-after-scaling</guid>
			<description><![CDATA[I am working on an application to scale an image, but the bottom part of the image contains a special pattern that must be copied over and repeated since it is distorted during scaling. I have the following section of code:<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>image1 = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE, Gio.file_new_for_path(image1_dir))<br />
image1_width = image1.get_width()<br />
        <br />
image1.select_rectangle(Gimp.ChannelOps.REPLACE, 0, 1479, image1_width, 57)<br />
image1_dr = image1.get_selected_drawables()<br />
Gimp.edit_copy(image1_dr)<br />
<br />
image.scale(image_new_width, image_height)<br />
<br />
image1.select_rectangle(Gimp.ChannelOps.REPLACE, 0, 1479, image1_width, 57)<br />
image1_dr = image1.get_selected_drawables()<br />
Gimp.edit_paste(image1_dr[0], True)<br />
<br />
image1.select_rectangle(Gimp.ChannelOps.REPLACE, image1_width, 1479, image1_width, 57)<br />
image1_dr = image1.get_selected_drawables()<br />
Gimp.edit_paste(image1_dr[0], True)</code></div></div>
<br />
In this code, I select and copy an area of size (width, 57) from coordinate (0,1479). Then, I scale the image to a new width. I then try and paste the selected area at coordinates (0,1479) and then at (original_width, 1479). So the whole of the bottom of the new image should have the original pattern. However, only a region on the bottom right of the image is covered, and not at the specified regions. In an example, if width was originally 25378, and then scaled to 31234, the selected area was only pasted onto the region from (15617,1479) to (31234,1479). The other area where I pasted first from (0,1479) to (15617,1479) has the distorted pattern after scaling and not the original pattern that was pasted onto it.<br />
<br />
Can you please explain why this occurs, and suggest a way to properly copy and paste the original pattern onto the scaled image?<br />
<br />
Thank you for your help!]]></description>
			<content:encoded><![CDATA[I am working on an application to scale an image, but the bottom part of the image contains a special pattern that must be copied over and repeated since it is distorted during scaling. I have the following section of code:<br />
<br />
<div class="codeblock">
<div class="title">Code:<br />
</div><div class="body" dir="ltr"><code>image1 = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE, Gio.file_new_for_path(image1_dir))<br />
image1_width = image1.get_width()<br />
        <br />
image1.select_rectangle(Gimp.ChannelOps.REPLACE, 0, 1479, image1_width, 57)<br />
image1_dr = image1.get_selected_drawables()<br />
Gimp.edit_copy(image1_dr)<br />
<br />
image.scale(image_new_width, image_height)<br />
<br />
image1.select_rectangle(Gimp.ChannelOps.REPLACE, 0, 1479, image1_width, 57)<br />
image1_dr = image1.get_selected_drawables()<br />
Gimp.edit_paste(image1_dr[0], True)<br />
<br />
image1.select_rectangle(Gimp.ChannelOps.REPLACE, image1_width, 1479, image1_width, 57)<br />
image1_dr = image1.get_selected_drawables()<br />
Gimp.edit_paste(image1_dr[0], True)</code></div></div>
<br />
In this code, I select and copy an area of size (width, 57) from coordinate (0,1479). Then, I scale the image to a new width. I then try and paste the selected area at coordinates (0,1479) and then at (original_width, 1479). So the whole of the bottom of the new image should have the original pattern. However, only a region on the bottom right of the image is covered, and not at the specified regions. In an example, if width was originally 25378, and then scaled to 31234, the selected area was only pasted onto the region from (15617,1479) to (31234,1479). The other area where I pasted first from (0,1479) to (15617,1479) has the distorted pattern after scaling and not the original pattern that was pasted onto it.<br />
<br />
Can you please explain why this occurs, and suggest a way to properly copy and paste the original pattern onto the scaled image?<br />
<br />
Thank you for your help!]]></content:encoded>
		</item>
		<item>
			<title><![CDATA[Endianess of pixel data in a Python region for gimp 2.10.]]></title>
			<link>https://www.gimp-forum.net/Thread-Endianess-of-pixel-data-in-a-Python-region-for-gimp-2-10</link>
			<pubDate>Mon, 14 Jul 2025 14:49:47 +0000</pubDate>
			<guid isPermaLink="false">https://www.gimp-forum.net/Thread-Endianess-of-pixel-data-in-a-Python-region-for-gimp-2-10</guid>
			<description><![CDATA[For gimp 2.10, is my understanding correct?<br />
<br />
Given a region's bytes from a layer ‘l’:<br />
<br />
    r = l.get_pixel_rgn(0, 0, w, h)<br />
    rb = r[:, :]<br />
<br />
I think rb will hold the bytes of the channel's values in the machine's native endianess because:<br />
<br />
- a region maps onto tiles,<br />
- getting the tile's pixels uses a simple memcpy(), and<br />
- a tile's pixels are in the native endianess.<br />
<br />
I'm aware tile data in an XCF file is big-endian from<br />
<a href="https://testing.developer.gimp.org/core/standards/xcf/#tile-data-organization" target="_blank">https://testing.developer.gimp.org/core/...ganization</a><br />
But I'm interested in what's in memory and guaranteed to be seen through slicing a Python region into a string of bytes.]]></description>
			<content:encoded><![CDATA[For gimp 2.10, is my understanding correct?<br />
<br />
Given a region's bytes from a layer ‘l’:<br />
<br />
    r = l.get_pixel_rgn(0, 0, w, h)<br />
    rb = r[:, :]<br />
<br />
I think rb will hold the bytes of the channel's values in the machine's native endianess because:<br />
<br />
- a region maps onto tiles,<br />
- getting the tile's pixels uses a simple memcpy(), and<br />
- a tile's pixels are in the native endianess.<br />
<br />
I'm aware tile data in an XCF file is big-endian from<br />
<a href="https://testing.developer.gimp.org/core/standards/xcf/#tile-data-organization" target="_blank">https://testing.developer.gimp.org/core/...ganization</a><br />
But I'm interested in what's in memory and guaranteed to be seen through slicing a Python region into a string of bytes.]]></content:encoded>
		</item>
	</channel>
</rss>