Module: RubySpriter::CellCleanupGimpScript

Defined in:
lib/ruby_spriter/cell_cleanup_gimp_script.rb

Class Method Summary collapse

Class Method Details

.generate_cleanup_script(input_path, output_path, dominant_colors) ⇒ Object



3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/ruby_spriter/cell_cleanup_gimp_script.rb', line 3

def self.generate_cleanup_script(input_path, output_path, dominant_colors)
  # Normalize paths for Python

  input_normalized = Utils::PathHelper.normalize_for_python(input_path)
  output_normalized = Utils::PathHelper.normalize_for_python(output_path)

  # Convert RGB strings to Python color strings

  colors_py = dominant_colors.map do |color_str|
    # Parse "rgb(255,0,0)" format

    match = color_str.match(/rgb\((\d+),(\d+),(\d+)\)/)
    r = match[1].to_i
    g = match[2].to_i
    b = match[3].to_i
    "{'r': #{r}, 'g': #{g}, 'b': #{b}}"
  end.join(', ')

  "    import sys\n    import gc\n    from gi.repository import Gimp, Gio, Gegl\n\n    img = None\n    layer = None\n\n    try:\n        print(\"Loading image...\")\n        img = Gimp.file_load(Gimp.RunMode.NONINTERACTIVE,\n                            Gio.File.new_for_path(r'\#{input_normalized}'))\n\n        w = img.get_width()\n        h = img.get_height()\n        print(f\"Image size: {w}x{h}\")\n\n        layers = img.get_layers()\n        if not layers or len(layers) == 0:\n            raise Exception(\"No layers found\")\n        layer = layers[0]\n\n        # Add alpha channel if needed\n        if not layer.has_alpha():\n            layer.add_alpha()\n            print(\"Added alpha channel\")\n\n        pdb = Gimp.get_pdb()\n\n        # Select dominant colors for removal\n        print(\"Selecting dominant colors...\")\n        select_proc = pdb.lookup_procedure('gimp-image-select-color')\n        if not select_proc:\n            raise Exception(\"Could not find gimp-image-select-color procedure\")\n\n        for i, color_dict in enumerate([\#{colors_py}]):\n            r, g, b = color_dict['r'], color_dict['g'], color_dict['b']\n            print(f\"  Selecting color {i+1}: RGB({r}, {g}, {b})\")\n\n            # Create Gegl.Color from normalized RGB values\n            color = Gegl.Color.new(f\"rgb({r/255.0}, {g/255.0}, {b/255.0})\")\n\n            config = select_proc.create_config()\n            config.set_property('image', img)\n            # Use REPLACE for first color, ADD for subsequent colors\n            if i == 0:\n                config.set_property('operation', Gimp.ChannelOps.REPLACE)\n            else:\n                config.set_property('operation', Gimp.ChannelOps.ADD)\n            config.set_property('drawable', layer)\n            config.set_property('color', color)\n            select_proc.run(config)\n\n        print(\"Colors selected\")\n\n        # Delete selection (make transparent)\n        print(\"Removing selected colors...\")\n        edit_clear = pdb.lookup_procedure('gimp-drawable-edit-clear')\n        if edit_clear:\n            config = edit_clear.create_config()\n            config.set_property('drawable', layer)\n            edit_clear.run(config)\n            print(\"Selection cleared\")\n\n        # Deselect\n        print(\"Deselecting...\")\n        select_none = pdb.lookup_procedure('gimp-selection-none')\n        if select_none:\n            config = select_none.create_config()\n            config.set_property('image', img)\n            select_none.run(config)\n\n        # Export\n        print(\"Exporting...\")\n        export_proc = pdb.lookup_procedure('file-png-export')\n        if export_proc:\n            config = export_proc.create_config()\n            config.set_property('image', img)\n            config.set_property('file', Gio.File.new_for_path(r'\#{output_normalized}'))\n            export_proc.run(config)\n            print(\"SUCCESS - Cell cleanup complete!\")\n        else:\n            raise Exception(\"Could not find file-png-export procedure\")\n\n    except Exception as e:\n        print(f\"ERROR: {e}\")\n        import traceback\n        traceback.print_exc()\n        sys.exit(1)\n    finally:\n        # Explicit cleanup to minimize GEGL warnings\n        try:\n            if layer is not None:\n                layer = None\n            if img is not None:\n                gc.collect()  # Force garbage collection\n                img.delete()\n                img = None\n                gc.collect()  # Force again after deletion\n        except Exception as cleanup_error:\n            print(f\"Cleanup warning: {cleanup_error}\")\n            pass\n  PYTHON\nend\n"