ruby_spriter 0.6.7 โ 0.7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rspec +3 -3
- data/CHANGELOG.md +1035 -405
- data/Gemfile +17 -17
- data/LICENSE +21 -21
- data/README.md +183 -902
- data/bin/ruby_spriter +20 -20
- data/lib/ruby_spriter/background_sampler.rb +140 -0
- data/lib/ruby_spriter/batch_processor.rb +268 -212
- data/lib/ruby_spriter/cell_cleanup_config.rb +21 -0
- data/lib/ruby_spriter/cell_cleanup_gimp_script.rb +123 -0
- data/lib/ruby_spriter/cell_cleanup_processor.rb +230 -0
- data/lib/ruby_spriter/cli.rb +676 -612
- data/lib/ruby_spriter/compression_manager.rb +101 -101
- data/lib/ruby_spriter/consolidator.rb +179 -179
- data/lib/ruby_spriter/dependency_checker.rb +224 -174
- data/lib/ruby_spriter/ghost_edge_cleaner.rb +164 -0
- data/lib/ruby_spriter/gimp_processor.rb +1188 -667
- data/lib/ruby_spriter/metadata_manager.rb +117 -116
- data/lib/ruby_spriter/platform.rb +137 -82
- data/lib/ruby_spriter/processor.rb +1230 -886
- data/lib/ruby_spriter/smoke_detector.rb +223 -0
- data/lib/ruby_spriter/threshold_stepper.rb +227 -0
- data/lib/ruby_spriter/utils/file_helper.rb +82 -82
- data/lib/ruby_spriter/utils/image_helper.rb +16 -0
- data/lib/ruby_spriter/utils/output_formatter.rb +65 -65
- data/lib/ruby_spriter/utils/path_helper.rb +59 -59
- data/lib/ruby_spriter/utils/spritesheet_splitter.rb +86 -86
- data/lib/ruby_spriter/version.rb +6 -7
- data/lib/ruby_spriter/video_processor.rb +357 -139
- data/lib/ruby_spriter.rb +38 -34
- data/ruby_spriter.gemspec +44 -42
- data/spec/fixtures/centered_sprite_with_inner_bg.png +0 -0
- data/spec/fixtures/centered_sprite_with_inner_bg_inner_removed.png +0 -0
- data/spec/fixtures/centered_sprite_with_inner_bg_threshold_stepped.png +0 -0
- data/spec/fixtures/complex_background_sprite.png +0 -0
- data/spec/fixtures/death - bloodborne rekconing.mp4 +0 -0
- data/spec/fixtures/death - bloodborne rekconing_spritesheet-nobg-global.png +0 -0
- data/spec/fixtures/death - bloodborne rekconing_spritesheet.png +0 -0
- data/spec/fixtures/death - bloodborne rekconing_spritesheet_20251110_185027_431-nobg-global.png +0 -0
- data/spec/fixtures/death - bloodborne rekconing_spritesheet_20251110_185027_431.png +0 -0
- data/spec/fixtures/death - bloodborne rekconing_spritesheet_20251110_185125_738-nobg-global.png +0 -0
- data/spec/fixtures/death - bloodborne rekconing_spritesheet_20251110_185125_738.png +0 -0
- data/spec/fixtures/has_inner_bg.png +0 -0
- data/spec/fixtures/has_small_inner_bg.png +0 -0
- data/spec/fixtures/smoke_effect_sprite.png +0 -0
- data/spec/fixtures/spritesheet_with_metadata.png +0 -0
- data/spec/fixtures/test_sprite.png +0 -0
- data/spec/fixtures/test_sprite_smoke_processed.png +0 -0
- data/spec/fixtures/test_video_spritesheet.png +0 -0
- data/spec/fixtures/transparent_bg_sprite.png +0 -0
- data/spec/fixtures/walk_north_sprite-sheet.png +0 -0
- data/spec/integration/no_fuzzy_mode_spec.rb +100 -0
- data/spec/ruby_spriter/batch_processor_spec.rb +509 -200
- data/spec/ruby_spriter/cli_spec.rb +2026 -1892
- data/spec/ruby_spriter/compression_manager_spec.rb +157 -157
- data/spec/ruby_spriter/consolidator_spec.rb +538 -538
- data/spec/ruby_spriter/gimp_processor_spec.rb +523 -425
- data/spec/ruby_spriter/platform_spec.rb +92 -82
- data/spec/ruby_spriter/processor_spec.rb +911 -735
- data/spec/ruby_spriter/utils/file_helper_spec.rb +150 -150
- data/spec/ruby_spriter/utils/path_helper_spec.rb +78 -78
- data/spec/ruby_spriter/utils/spritesheet_splitter_spec.rb +104 -104
- data/spec/ruby_spriter/video_processor_spec.rb +346 -29
- data/spec/spec_helper.rb +41 -41
- data/spec/tmp/cli_test_output.png +0 -0
- data/spec/tmp/cli_test_output_20251105_114647_395.png +0 -0
- data/spec/tmp/combined_test.png +0 -0
- data/spec/tmp/compat_test.png +0 -0
- data/spec/tmp/compat_test_20251030_174233_361.png +0 -0
- data/spec/tmp/final_all_features.png +0 -0
- data/spec/tmp/final_test_all_features.png +0 -0
- data/spec/tmp/full_pipeline_test.png +0 -0
- data/spec/tmp/inner_test.png +0 -0
- data/spec/tmp/integration_test.png +0 -0
- data/spec/tmp/validation_test.png +0 -0
- data/spec/unit/background_sampler_spec.rb +132 -0
- data/spec/unit/cell_cleanup_config_spec.rb +32 -0
- data/spec/unit/cell_cleanup_gimp_script_spec.rb +59 -0
- data/spec/unit/cell_cleanup_processor_spec.rb +261 -0
- data/spec/unit/ghost_edge_cleaner_spec.rb +223 -0
- data/spec/unit/gimp_processor_single_point_selection_spec.rb +81 -0
- data/spec/unit/smoke_detector_spec.rb +246 -0
- data/spec/unit/threshold_stepper_spec.rb +195 -0
- metadata +56 -10
data/CHANGELOG.md
CHANGED
|
@@ -1,405 +1,1035 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
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
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
####
|
|
158
|
-
- **
|
|
159
|
-
-
|
|
160
|
-
-
|
|
161
|
-
-
|
|
162
|
-
-
|
|
163
|
-
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
-
|
|
170
|
-
-
|
|
171
|
-
- **
|
|
172
|
-
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
####
|
|
181
|
-
- **
|
|
182
|
-
-
|
|
183
|
-
-
|
|
184
|
-
-
|
|
185
|
-
- **
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
-
|
|
192
|
-
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
196
|
-
-
|
|
197
|
-
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
-
|
|
211
|
-
-
|
|
212
|
-
-
|
|
213
|
-
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
-
|
|
217
|
-
- **
|
|
218
|
-
- **
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
####
|
|
241
|
-
-
|
|
242
|
-
-
|
|
243
|
-
-
|
|
244
|
-
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
- **
|
|
249
|
-
- **
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
- **
|
|
271
|
-
-
|
|
272
|
-
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
-
|
|
277
|
-
-
|
|
278
|
-
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
-
|
|
285
|
-
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
- **
|
|
306
|
-
-
|
|
307
|
-
-
|
|
308
|
-
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
- **
|
|
312
|
-
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
-
|
|
316
|
-
- **
|
|
317
|
-
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
-
|
|
327
|
-
- **
|
|
328
|
-
- **
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
- **
|
|
332
|
-
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
-
|
|
336
|
-
- **
|
|
337
|
-
|
|
338
|
-
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
-
|
|
343
|
-
-
|
|
344
|
-
-
|
|
345
|
-
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
-
|
|
357
|
-
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
-
|
|
381
|
-
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
-
|
|
389
|
-
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
1
|
+
---
|
|
2
|
+
|
|
3
|
+
### **CHANGELOG.md**
|
|
4
|
+
```markdown
|
|
5
|
+
## [0.7.0.1] - 2025-11-07 to 2025-11-11
|
|
6
|
+
### ๐ง Code Quality & Performance Release (Nov 8-11, 2025)
|
|
7
|
+
|
|
8
|
+
### ๐จ Cell-Based Background Cleanup (EXPERIMENTAL - Nov 10-11, 2025)
|
|
9
|
+
|
|
10
|
+
#### Added
|
|
11
|
+
- **Cell-Based Background Cleanup** (`--cleanup-cells`): Post-process residual backgrounds from finished spritesheets
|
|
12
|
+
- Analyzes each cell independently for dominant background colors exceeding threshold
|
|
13
|
+
- Uses GIMP to remove detected dominant colors from individual cells
|
|
14
|
+
- Configurable threshold via `--cell-cleanup-threshold` (default: 15.0%, range: 1.0-50.0)
|
|
15
|
+
- Requires `--remove-bg` flag (validates usage)
|
|
16
|
+
- Cannot be combined with `--by-frame` (redundant - by-frame already handles per-frame cleanup)
|
|
17
|
+
- Works with both `--video` and `--batch` modes
|
|
18
|
+
- Progress reporting shows cells processed/cleaned/skipped counts
|
|
19
|
+
- โ ๏ธ **Experimental**: Feature is technically complete and all tests pass, but background removal is not yet effective in practice. Requires algorithm optimization. Not recommended for production use.
|
|
20
|
+
|
|
21
|
+
#### New Classes
|
|
22
|
+
- **CellCleanupProcessor** (`lib/ruby_spriter/cell_cleanup_processor.rb`)
|
|
23
|
+
- Orchestrates cell-by-cell analysis and cleanup
|
|
24
|
+
- Methods: `cleanup_cells`, `extract_cell`, `analyze_cell_colors`, `remove_dominant_colors`, `reassemble_spritesheet`
|
|
25
|
+
- Integrates with GimpProcessor for color selection
|
|
26
|
+
- Returns statistics: `{ processed: N, cleaned: N, skipped: N, colors_removed: N }`
|
|
27
|
+
|
|
28
|
+
- **CellCleanupConfig** (`lib/ruby_spriter/cell_cleanup_config.rb`)
|
|
29
|
+
- Configuration validation for cleanup parameters
|
|
30
|
+
- Validates threshold range (1.0-50.0)
|
|
31
|
+
|
|
32
|
+
- **CellCleanupGimpScript** (`lib/ruby_spriter/cell_cleanup_gimp_script.rb`)
|
|
33
|
+
- Generates GIMP 3.x Python-fu scripts for cell cleanup
|
|
34
|
+
- Handles path normalization for Windows
|
|
35
|
+
- Uses exact color matching with Gegl.Color API
|
|
36
|
+
- Proper garbage collection to prevent memory leaks
|
|
37
|
+
|
|
38
|
+
#### Integration
|
|
39
|
+
- **Processor**: Updated `apply_cell_cleanup` method with proper parameter passing
|
|
40
|
+
- **VideoProcessor**: Added cell cleanup step after standard background removal in pipeline
|
|
41
|
+
- **BatchProcessor**: Cell cleanup automatically applies to all videos when flag set
|
|
42
|
+
- **Execution Order**: Standard BG removal โ Cell-based cleanup โ Scaling/Sharpening/Compression
|
|
43
|
+
|
|
44
|
+
#### Test Coverage
|
|
45
|
+
- **21 New Tests Added**: CellCleanupProcessor (13), CellCleanupConfig (4), CellCleanupGimpScript (4)
|
|
46
|
+
- **CLI Validation**: 6 tests for flag combination validation
|
|
47
|
+
- **Integration Tests**: 2 VideoProcessor integration tests
|
|
48
|
+
- **Total**: 512 examples, 0 failures
|
|
49
|
+
- **Code Coverage**: 72.58% (1844 / 2544 lines)
|
|
50
|
+
|
|
51
|
+
#### Technical Details
|
|
52
|
+
- Uses ImageMagick `histogram:info` for dominant color detection
|
|
53
|
+
- Skips transparent pixels in histogram analysis
|
|
54
|
+
- Uses GIMP `gimp-image-select-color` with REPLACE (first color) and ADD (subsequent colors) operations
|
|
55
|
+
- Clears selection with `gimp-drawable-edit-clear` to make colors transparent
|
|
56
|
+
- Reassembles cells using ImageMagick `montage` with no gaps/borders
|
|
57
|
+
|
|
58
|
+
#### Known Issues (Deferred to v0.7.0.2)
|
|
59
|
+
1. **Ineffective Background Removal** (AC-35, AC-48)
|
|
60
|
+
- Feature executes without errors but doesn't effectively remove backgrounds
|
|
61
|
+
- GIMP color selection may need explicit threshold parameter
|
|
62
|
+
- Requires algorithm investigation and refinement
|
|
63
|
+
|
|
64
|
+
2. **Performance Exceeds Target** (AC-41)
|
|
65
|
+
- Adds more than 30% overhead to total processing time
|
|
66
|
+
- Each cell invokes separate GIMP process (16 invocations for 16-cell spritesheet)
|
|
67
|
+
- Requires parallel processing optimization
|
|
68
|
+
|
|
69
|
+
3. **Missing PNG Metadata** (AC-39)
|
|
70
|
+
- Cell cleanup statistics not embedded in PNG metadata
|
|
71
|
+
- Low priority - informational only
|
|
72
|
+
|
|
73
|
+
#### Fixes
|
|
74
|
+
- **Division by Zero in Cell Cleanup**: Fixed parameter passing through pipeline (frames/columns not passed to cleanup_cells)
|
|
75
|
+
- **GIMP Script Generation**: Corrected path normalization, Gegl.Color API, removed non-existent threshold property
|
|
76
|
+
- **Module Loading**: Added missing require for CellCleanupGimpScript in CellCleanupProcessor
|
|
77
|
+
|
|
78
|
+
#### Documentation
|
|
79
|
+
- Updated requirements document (Revision #11)
|
|
80
|
+
- Added 49 acceptance criteria tracking table
|
|
81
|
+
- Marked feature as "Implemented but requires optimization"
|
|
82
|
+
- Added comprehensive known issues section with root cause analysis
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
### ๐ Bug Fixes (Nov 8, 2025)
|
|
87
|
+
|
|
88
|
+
#### Fixed
|
|
89
|
+
- **Missing `--by-frame` Flag in Help Text**: Added `--by-frame` to context-sensitive help
|
|
90
|
+
- Now appears in `--video --help` output under "Background Removal Options"
|
|
91
|
+
- Now appears in `--batch --help` output under "Background Removal Options"
|
|
92
|
+
- Now appears in `--image --help` output under "Background Removal Options"
|
|
93
|
+
- Description: "Remove background from each frame individually (slower, better quality)"
|
|
94
|
+
- Proper indentation with tree character (โโ) showing hierarchy under `--remove-bg`
|
|
95
|
+
|
|
96
|
+
- **Runtime Error with `--by-frame` Flag**: Fixed `NoMethodError: undefined method 'extract_frames'`
|
|
97
|
+
- **Root Causes Identified**:
|
|
98
|
+
1. `extract_frames` method didn't exist in VideoProcessor
|
|
99
|
+
2. `assemble_spritesheet_from_frames` method didn't exist in VideoProcessor
|
|
100
|
+
3. `temp_dir` not passed in options hash to assembly method
|
|
101
|
+
4. Pattern detection missing for `_nobg` suffix in frame filenames
|
|
102
|
+
5. Metadata embedding using incorrect API (single argument instead of two)
|
|
103
|
+
|
|
104
|
+
- **Fixes Implemented**:
|
|
105
|
+
1. โ
Implemented `VideoProcessor#extract_frames(video_path, temp_dir, options)`
|
|
106
|
+
- Extracts individual frames from video using FFmpeg
|
|
107
|
+
- Calculates FPS based on video duration and frame count
|
|
108
|
+
- Returns array of frame filenames (basenames only)
|
|
109
|
+
- Proper error handling with ProcessingError
|
|
110
|
+
|
|
111
|
+
2. โ
Implemented `VideoProcessor#assemble_spritesheet_from_frames(frame_files, output_path, options)`
|
|
112
|
+
- Assembles frames into spritesheet using FFmpeg tile filter
|
|
113
|
+
- Automatic row calculation with ceiling division
|
|
114
|
+
- Pattern detection for `_nobg` suffix (handles both regular and processed frames)
|
|
115
|
+
- Validates output file exists after assembly
|
|
116
|
+
|
|
117
|
+
3. โ
Fixed `temp_dir` passing in options
|
|
118
|
+
- `process_with_background_removal` now merges `temp_dir` into options
|
|
119
|
+
- Both by-frame and standard paths correctly pass temp directory
|
|
120
|
+
|
|
121
|
+
4. โ
Added pattern detection for `_nobg` suffix
|
|
122
|
+
- Detects suffix from first filename in array
|
|
123
|
+
- Constructs correct FFmpeg input pattern: `frame_%03d.png` or `frame_%03d_nobg.png`
|
|
124
|
+
- Handles frame-by-frame processed files correctly
|
|
125
|
+
|
|
126
|
+
5. โ
Fixed metadata embedding API
|
|
127
|
+
- Changed from single-argument hash to two-argument form with keywords
|
|
128
|
+
- Uses temp file pattern: create temp โ embed metadata โ cleanup
|
|
129
|
+
- Matches `create_spritesheet` implementation pattern
|
|
130
|
+
- Properly calculates rows for metadata
|
|
131
|
+
|
|
132
|
+
#### Test Coverage
|
|
133
|
+
- **11 New Tests Added** (470 โ 481 examples, all passing)
|
|
134
|
+
- CLI help text: 2 tests (video mode, batch mode)
|
|
135
|
+
- `extract_frames`: 3 tests (FFmpeg command, return value, error handling)
|
|
136
|
+
- `assemble_spritesheet_from_frames`: 6 tests (assembly, row calculation, ceiling division, _nobg suffix, error handling, file validation)
|
|
137
|
+
- **Code Coverage**: Increased to 19.23% (457 / 2377 lines)
|
|
138
|
+
- **No Regressions**: All existing tests continue to pass
|
|
139
|
+
|
|
140
|
+
#### Real-World Testing
|
|
141
|
+
- โ
Tested with actual video file processing
|
|
142
|
+
- โ
Frame-by-frame processing completes successfully
|
|
143
|
+
- โ
All frames extracted and processed individually
|
|
144
|
+
- โ
Spritesheet assembled correctly from processed frames
|
|
145
|
+
- โ
Metadata embedded properly
|
|
146
|
+
- โ
Output file created successfully
|
|
147
|
+
|
|
148
|
+
#### Files Modified
|
|
149
|
+
- `lib/ruby_spriter/cli.rb` - Added `--by-frame` to help text (3 locations)
|
|
150
|
+
- `lib/ruby_spriter/video_processor.rb` - Implemented missing methods, fixed bugs
|
|
151
|
+
- `spec/ruby_spriter/cli_spec.rb` - Added 2 help text tests
|
|
152
|
+
- `spec/ruby_spriter/video_processor_spec.rb` - Added 9 method tests
|
|
153
|
+
- `requirements/Ruby Spriter v0.7.0.1 Bug Fixes.md` - Updated to Revision 2
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
#### Refactored
|
|
158
|
+
- **BatchProcessor Architecture**: Eliminated code duplication and improved performance
|
|
159
|
+
- **Eager Dependency Checking**: Dependencies now checked once during initialization (not per video)
|
|
160
|
+
- **Cached Instance Variables**: `@gimp_path` and `@gimp_version` stored and reused
|
|
161
|
+
- **Helper Methods Extracted**:
|
|
162
|
+
- `using_frame_by_frame_background_removal?` - Checks both `--by-frame` and `--remove-bg` flags
|
|
163
|
+
- `normalize_video_result_format` - Standardizes result hash format
|
|
164
|
+
- `needs_dependency_setup?` - Determines if GIMP operations required
|
|
165
|
+
- `setup_dependencies` - Caches dependency check results
|
|
166
|
+
- **Refactored Methods**:
|
|
167
|
+
- `process_video` - Uses cached dependencies, eliminates redundant VideoProcessor instantiation
|
|
168
|
+
- `process_with_gimp` - Uses cached dependencies directly
|
|
169
|
+
- **Performance Impact**: 20ร reduction in dependency checks (2 per video โ 1 total during initialization)
|
|
170
|
+
- **Architectural Consistency**: BatchProcessor now follows same pattern as Processor class
|
|
171
|
+
- **Test Coverage**: Added 14 new tests (15 โ 29 examples, all passing)
|
|
172
|
+
- **Code Quality**: Eliminated 5 duplication issues identified in code review
|
|
173
|
+
|
|
174
|
+
#### Performance
|
|
175
|
+
- **Before**: 2 `DependencyChecker` instantiations per video (shell commands executed repeatedly)
|
|
176
|
+
- **After**: 1 `DependencyChecker` instantiation during initialization (results cached)
|
|
177
|
+
- **Batch Processing**: For 10 videos, reduced from 20 dependency checks to 1 (20ร improvement)
|
|
178
|
+
- **Shell Command Reduction**: Eliminated redundant `where gimp`, `gimp --version` calls
|
|
179
|
+
|
|
180
|
+
#### Technical Details
|
|
181
|
+
- **Files Modified**:
|
|
182
|
+
- `lib/ruby_spriter/batch_processor.rb` - Refactored implementation (+287 lines net)
|
|
183
|
+
- `spec/ruby_spriter/batch_processor_spec.rb` - Added comprehensive test coverage
|
|
184
|
+
- `requirements/Ruby Spriter v0.7.0.1 Requirements.md` - Updated to Revision 10
|
|
185
|
+
- **Test Results**: 474 examples, 0 failures, 0 regressions
|
|
186
|
+
- **Commit**: 1a0f5f3
|
|
187
|
+
|
|
188
|
+
### ๐๏ธ Frame-by-Frame Background Removal Release
|
|
189
|
+
|
|
190
|
+
#### Added
|
|
191
|
+
- **Frame-by-Frame Processing** (`--by-frame`): Process each video frame individually before assembling spritesheet
|
|
192
|
+
- Perfect for videos with varying backgrounds (lighting changes, environment changes, camera movement)
|
|
193
|
+
- Processes each frame with background removal before assembly
|
|
194
|
+
- Progress indicator: "Processing frame X/Y..."
|
|
195
|
+
- Adds `processing_mode: by-frame` to PNG metadata
|
|
196
|
+
- Works with all background removal modes: `--fuzzy`, `--threshold`, `--threshold-stepping`
|
|
197
|
+
- Compatible with `--scale`, `--sharpen`, `--max-compress`
|
|
198
|
+
- Supports both `--video` and `--batch` modes
|
|
199
|
+
- **CLI Validation**: `--by-frame` requires both `--video` or `--batch` AND `--remove-bg`
|
|
200
|
+
- **VideoProcessor Enhancement**: New `process_with_background_removal` method for frame-by-frame workflow
|
|
201
|
+
- **Processor Integration**: Automatic routing to frame-by-frame processing when flag is set
|
|
202
|
+
- **BatchProcessor Integration**: Full support for batch processing with frame-by-frame mode
|
|
203
|
+
|
|
204
|
+
#### Changed
|
|
205
|
+
- **Processing Workflow**: When `--by-frame` is used, workflow changes from "Extract โ Assemble โ Remove BG" to "Extract โ Remove BG (each) โ Assemble"
|
|
206
|
+
- **Performance Trade-off**: Frame-by-frame processing is ~16ร slower than standard mode (e.g., 16 frames: ~120s vs ~7.5s) but produces superior results for varying backgrounds
|
|
207
|
+
|
|
208
|
+
#### Technical Details
|
|
209
|
+
- **New Methods**:
|
|
210
|
+
- `VideoProcessor#process_with_background_removal(video_path, output_path, options)` - Main frame-by-frame processing
|
|
211
|
+
- `VideoProcessor#process_frames_individually(frame_files, temp_dir, options)` - Per-frame background removal
|
|
212
|
+
- `VideoProcessor#process_image_with_gimp(input_path, output_path, options)` - Helper for GIMP processing
|
|
213
|
+
- `VideoProcessor#no_background_filename(filename)` - Generate _nobg filenames
|
|
214
|
+
- `Processor#using_frame_by_frame_background_removal?` - Check if frame-by-frame mode active
|
|
215
|
+
- `Processor#normalize_video_result_format(result)` - Normalize result format
|
|
216
|
+
- `BatchProcessor#process_video` - Updated to support frame-by-frame mode
|
|
217
|
+
- **Constants**: `VideoProcessor::NO_BACKGROUND_SUFFIX = '_nobg'`
|
|
218
|
+
- **Test Coverage**: 12 new tests (5 CLI validation, 3 VideoProcessor, 2 Processor integration, 2 BatchProcessor)
|
|
219
|
+
- **Total Tests**: 455 examples, 0 failures
|
|
220
|
+
|
|
221
|
+
#### Examples
|
|
222
|
+
```bash
|
|
223
|
+
# Basic frame-by-frame processing
|
|
224
|
+
ruby_spriter --video input.mp4 --remove-bg --by-frame
|
|
225
|
+
|
|
226
|
+
# With custom grid and scaling
|
|
227
|
+
ruby_spriter --video input.mp4 --remove-bg --by-frame \
|
|
228
|
+
--frames 32 --columns 8 \
|
|
229
|
+
--scale 50 --sharpen
|
|
230
|
+
|
|
231
|
+
# Batch processing with frame-by-frame
|
|
232
|
+
ruby_spriter --batch --dir "videos/" --remove-bg --by-frame
|
|
233
|
+
|
|
234
|
+
# Combine with threshold stepping for maximum quality
|
|
235
|
+
ruby_spriter --video explosion.mp4 \
|
|
236
|
+
--remove-bg --by-frame --threshold-stepping \
|
|
237
|
+
--frames 32 --columns 8
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
#### When to Use `--by-frame`
|
|
241
|
+
- โ
Video has changing backgrounds between frames
|
|
242
|
+
- โ
Character moves through different environments
|
|
243
|
+
- โ
Lighting conditions vary throughout video
|
|
244
|
+
- โ
Camera pans or moves during recording
|
|
245
|
+
- โ
Quality is more important than processing speed
|
|
246
|
+
|
|
247
|
+
#### Performance Characteristics
|
|
248
|
+
- **Standard Mode**: ~7.5 seconds for 16 frames (1ร background removal)
|
|
249
|
+
- **Frame-by-Frame Mode**: ~120 seconds for 16 frames (16ร background removal)
|
|
250
|
+
- **Trade-off**: Significantly longer processing time for superior quality with varying backgrounds
|
|
251
|
+
|
|
252
|
+
#### Backward Compatibility
|
|
253
|
+
- Fully backward compatible - all existing workflows continue to work unchanged
|
|
254
|
+
- `--by-frame` is opt-in and disabled by default
|
|
255
|
+
- No breaking changes to existing features or APIs
|
|
256
|
+
|
|
257
|
+
Closes #XX (Frame-by-Frame Background Removal)
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
## [0.7.0.1] - 2025-11-06
|
|
262
|
+
|
|
263
|
+
### Added
|
|
264
|
+
- BackgroundSampler class for intelligent background color sampling
|
|
265
|
+
- Two-pass background removal: outer (single-point) + inner (sampled colors)
|
|
266
|
+
- CLI options: --bg-sample-offset (default: 5), --bg-sample-count (default: 10)
|
|
267
|
+
- Pixel cache optimization for 65x performance improvement in sampling
|
|
268
|
+
|
|
269
|
+
### Changed
|
|
270
|
+
- **BREAKING**: --no-fuzzy is now the DEFAULT for --remove-bg
|
|
271
|
+
- --fuzzy flag now required for contiguous-only selection
|
|
272
|
+
- Single-point selection at (5,5) instead of 4-corner selection
|
|
273
|
+
- GIMP threshold behavior now matches GUI (fixed over-removal at high thresholds)
|
|
274
|
+
|
|
275
|
+
### Removed
|
|
276
|
+
- --try-inner flag (functionality now in --no-fuzzy default)
|
|
277
|
+
- --threshold-stepping flag (superseded by BackgroundSampler)
|
|
278
|
+
- --inner-min-area, --adaptive-min-area, --multi-pass flags
|
|
279
|
+
- --edge-sample-depth, --edge-sample-pattern flags
|
|
280
|
+
- --color-space, --remove-smoke, --bg-fuzz, --ghost-threshold flags
|
|
281
|
+
- EdgeSampler, InnerBackgroundProcessor, InnerBgConfig classes
|
|
282
|
+
|
|
283
|
+
### Fixed
|
|
284
|
+
- GIMP threshold parameter now works correctly at all values (0-100)
|
|
285
|
+
- Single-point selection eliminates threshold compounding issue
|
|
286
|
+
- Background removal no longer removes more pixels than GIMP GUI
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
All notable changes to Ruby Spriter will be documented in this file.
|
|
290
|
+
|
|
291
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
292
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## [0.7.0] - 2025-10-30
|
|
297
|
+
|
|
298
|
+
### ๐จ Inner Background Removal Release
|
|
299
|
+
|
|
300
|
+
Major feature release introducing advanced background removal capabilities with multi-stage processing pipeline for superior sprite edge quality.
|
|
301
|
+
|
|
302
|
+
#### Added
|
|
303
|
+
|
|
304
|
+
##### Inner Background Removal System (`--try-inner`)
|
|
305
|
+
- **Flood Fill-Based Background Removal**: Targets interior transparent regions missed by edge-based methods
|
|
306
|
+
- Detects fully transparent pixels (alpha = 0)
|
|
307
|
+
- Samples pixel colors from surrounding opaque regions
|
|
308
|
+
- Uses flood fill to remove matching colors from transparent areas
|
|
309
|
+
- Preserves sprite edges and anti-aliasing
|
|
310
|
+
- Configurable tolerance and opacity thresholds
|
|
311
|
+
- **Edge Sampling Algorithm**: Intelligent color detection from sprite boundaries
|
|
312
|
+
- Scans 8-directional neighbors (N, S, E, W, NE, NW, SE, SW)
|
|
313
|
+
- Configurable search radius (default: 10 pixels, up to 50)
|
|
314
|
+
- Returns most common color from opaque edge pixels
|
|
315
|
+
- Handles cases with no opaque neighbors gracefully
|
|
316
|
+
- **Configuration Options**:
|
|
317
|
+
- `--inner-tolerance VALUE`: Flood fill color matching tolerance (0.0-100.0%, default: 10.0%)
|
|
318
|
+
- `--inner-opacity VALUE`: Minimum opacity threshold for edge sampling (0.0-1.0, default: 0.9)
|
|
319
|
+
- `--inner-radius VALUE`: Edge sampling search radius in pixels (1-50, default: 10)
|
|
320
|
+
|
|
321
|
+
##### Threshold Stepping (`--threshold-stepping`)
|
|
322
|
+
- **Multi-Threshold Processing**: Applies background removal with multiple fuzzy select thresholds
|
|
323
|
+
- Default thresholds: [0.0, 0.5, 1.0, 3.0, 5.0, 10.0]
|
|
324
|
+
- Processes image separately with each threshold
|
|
325
|
+
- Combines results using ImageMagick DstOver composite
|
|
326
|
+
- Improves edge detection compared to single threshold
|
|
327
|
+
- **Automatic Result Combination**: Layers threshold results from highest to lowest
|
|
328
|
+
- **Configurable Thresholds**: Can override defaults via InnerBgConfig
|
|
329
|
+
|
|
330
|
+
##### Ghost Edge Prevention (`--multi-pass`)
|
|
331
|
+
- **Multi-Pass Alpha Cleanup**: Removes semi-transparent "ghost" pixels from edges
|
|
332
|
+
- Iterative processing (up to 3 passes)
|
|
333
|
+
- Detects pixels with alpha below threshold (default: 30/255 = ~12%)
|
|
334
|
+
- Sets low-alpha pixels to fully transparent
|
|
335
|
+
- Converges when no more ghost pixels detected
|
|
336
|
+
- **Convergence Detection**: Stops early when cleanup complete
|
|
337
|
+
- **Configuration**:
|
|
338
|
+
- `--ghost-threshold VALUE`: Alpha threshold for ghost detection (0-255, default: 30)
|
|
339
|
+
|
|
340
|
+
##### Smoke Detection and Removal (`--remove-smoke`)
|
|
341
|
+
- **Transparency Gradient Detection**: Identifies smoke-like semi-transparent regions
|
|
342
|
+
- Detects alpha values between 20-80% (MIN_ALPHA to MAX_ALPHA)
|
|
343
|
+
- Filters by minimum contiguous area (50 pixels)
|
|
344
|
+
- Grid-based sampling for performance (20-pixel steps)
|
|
345
|
+
- Reports region coordinates, areas, and alpha ranges
|
|
346
|
+
- **Optional Removal**: Remove detected smoke effects with `--remove-smoke`
|
|
347
|
+
- **Detection Reports**: Always reports smoke regions when background removal active
|
|
348
|
+
|
|
349
|
+
##### Enhanced Color Space Support
|
|
350
|
+
- **RGBA Enforcement**: All modules force RGBA color space with `-define png:color-type=6`
|
|
351
|
+
- Handles grayscale input images correctly
|
|
352
|
+
- Ensures alpha channel availability for all operations
|
|
353
|
+
- Prevents colorspace-related processing failures
|
|
354
|
+
|
|
355
|
+
##### Comprehensive Reporting
|
|
356
|
+
- **Detailed Processing Reports**: Each module provides timing and statistics
|
|
357
|
+
- ThresholdStepper: Lists processed thresholds and timing
|
|
358
|
+
- InnerBackgroundProcessor: Reports pixels removed, regions processed, edge sampling stats
|
|
359
|
+
- GhostEdgeCleaner: Reports passes performed, ghost pixels detected/removed
|
|
360
|
+
- SmokeDetector: Reports smoke regions detected, removal status, processing time
|
|
361
|
+
- **Pipeline Visibility**: Clear output formatting for each processing stage
|
|
362
|
+
|
|
363
|
+
#### Changed
|
|
364
|
+
|
|
365
|
+
##### Processing Pipeline Order
|
|
366
|
+
1. **Threshold Stepping** (if `--threshold-stepping` and `--remove-bg`)
|
|
367
|
+
2. **GIMP Edge-Based Removal** (if `--remove-bg` or `--scale`)
|
|
368
|
+
3. **Inner Background Removal** (if `--try-inner` and `--remove-bg`)
|
|
369
|
+
4. **Ghost Edge Cleaning** (if `--multi-pass` and `--remove-bg`)
|
|
370
|
+
5. **Smoke Detection** (always active when `--remove-bg`)
|
|
371
|
+
|
|
372
|
+
##### GIMP Version Requirement
|
|
373
|
+
- **Requires GIMP 3.x**: GIMP 2.x is NOT supported
|
|
374
|
+
- **Ubuntu 25.04+**: Native GIMP 3.x package available
|
|
375
|
+
- **Older distributions**: Use Flatpak for GIMP 3.x installation
|
|
376
|
+
|
|
377
|
+
#### Performance
|
|
378
|
+
|
|
379
|
+
##### Benchmark Results (Windows 11, i7-12700K)
|
|
380
|
+
- **Edge Sampling**: ~0.015s per transparent pixel
|
|
381
|
+
- **Inner Background Removal**: ~2-5s for typical sprite (depends on transparent regions)
|
|
382
|
+
- **Threshold Stepping**: ~10-15s (6 thresholds ร ~2s per threshold)
|
|
383
|
+
- **Ghost Edge Cleaning**: ~1-2s per pass (typically 1-2 passes)
|
|
384
|
+
- **Smoke Detection**: ~5-10s for typical sprite (grid sampling)
|
|
385
|
+
|
|
386
|
+
##### Total Pipeline Time
|
|
387
|
+
- **Basic Pipeline** (edge removal only): ~5-10s
|
|
388
|
+
- **Full Pipeline** (all features): ~25-40s
|
|
389
|
+
- **Recommended**: Enable only features needed for your sprites to optimize performance
|
|
390
|
+
|
|
391
|
+
#### Backward Compatibility
|
|
392
|
+
|
|
393
|
+
##### Fully Backward Compatible
|
|
394
|
+
- All existing CLI flags and workflows continue to work unchanged
|
|
395
|
+
- Default behavior (without new flags) identical to v0.6.7.1
|
|
396
|
+
- Existing spritesheets and metadata formats fully supported
|
|
397
|
+
- No breaking changes to public APIs or file formats
|
|
398
|
+
|
|
399
|
+
##### Opt-In Features
|
|
400
|
+
- All v0.7.0 features disabled by default
|
|
401
|
+
- Must explicitly enable with command-line flags
|
|
402
|
+
- Safe to upgrade without workflow changes
|
|
403
|
+
|
|
404
|
+
#### Testing
|
|
405
|
+
|
|
406
|
+
##### Test Coverage
|
|
407
|
+
- **102 Unit Tests**: All passing (35 new tests added)
|
|
408
|
+
- 12 tests for ThresholdStepper
|
|
409
|
+
- 16 tests for GhostEdgeCleaner
|
|
410
|
+
- 20 tests for SmokeDetector
|
|
411
|
+
- 14 tests for EdgeSampler
|
|
412
|
+
- 17 tests for InnerBackgroundProcessor
|
|
413
|
+
- 4 tests for InnerBgConfig
|
|
414
|
+
- **3 Feature Tests**: Integration tests for complete workflows
|
|
415
|
+
- **471 Total Examples**: Comprehensive coverage across entire codebase
|
|
416
|
+
- **Test Duration**: ~3 minutes 8 seconds for full suite
|
|
417
|
+
|
|
418
|
+
##### Test Quality
|
|
419
|
+
- TDD methodology (RED-GREEN-REFACTOR) used throughout
|
|
420
|
+
- ImageMagick command mocking for unit tests
|
|
421
|
+
- Real image processing in feature tests
|
|
422
|
+
- Performance tests ensure reasonable processing times
|
|
423
|
+
|
|
424
|
+
#### Documentation
|
|
425
|
+
|
|
426
|
+
##### Updated Documentation
|
|
427
|
+
- **README.md**: Added comprehensive v0.7.0 features section
|
|
428
|
+
- 11 new command-line flags documented
|
|
429
|
+
- 3 usage examples (basic, full pipeline, advanced)
|
|
430
|
+
- Processing order diagram
|
|
431
|
+
- Performance considerations
|
|
432
|
+
- **CHANGELOG.md**: This comprehensive release documentation
|
|
433
|
+
- **Code Comments**: Extensive inline documentation in all new modules
|
|
434
|
+
|
|
435
|
+
#### Technical Details
|
|
436
|
+
|
|
437
|
+
##### New Modules
|
|
438
|
+
- `lib/ruby_spriter/inner_bg_config.rb` (134 lines)
|
|
439
|
+
- `lib/ruby_spriter/edge_sampler.rb` (141 lines)
|
|
440
|
+
- `lib/ruby_spriter/inner_background_processor.rb` (256 lines)
|
|
441
|
+
- `lib/ruby_spriter/threshold_stepper.rb` (133 lines)
|
|
442
|
+
- `lib/ruby_spriter/ghost_edge_cleaner.rb` (153 lines)
|
|
443
|
+
- `lib/ruby_spriter/smoke_detector.rb` (224 lines)
|
|
444
|
+
|
|
445
|
+
##### New Test Files
|
|
446
|
+
- `spec/unit/inner_bg_config_spec.rb` (61 lines, 4 tests)
|
|
447
|
+
- `spec/unit/edge_sampler_spec.rb` (137 lines, 14 tests)
|
|
448
|
+
- `spec/unit/inner_background_processor_spec.rb` (188 lines, 17 tests)
|
|
449
|
+
- `spec/unit/threshold_stepper_spec.rb` (164 lines, 12 tests)
|
|
450
|
+
- `spec/unit/ghost_edge_cleaner_spec.rb` (217 lines, 16 tests)
|
|
451
|
+
- `spec/unit/smoke_detector_spec.rb` (246 lines, 20 tests)
|
|
452
|
+
- `spec/features/inner_background_removal_spec.rb` (139 lines, 3 tests)
|
|
453
|
+
|
|
454
|
+
##### Modified Files
|
|
455
|
+
- `lib/ruby_spriter/processor.rb`: Added 5-stage pipeline integration (3 new methods)
|
|
456
|
+
- `lib/ruby_spriter/cli.rb`: Added 11 new command-line options
|
|
457
|
+
- `lib/ruby_spriter.rb`: Added requires for new modules
|
|
458
|
+
|
|
459
|
+
#### Known Issues
|
|
460
|
+
|
|
461
|
+
##### Performance Considerations
|
|
462
|
+
- Full pipeline (all features enabled) takes 25-40s for typical sprites
|
|
463
|
+
- Smoke detection uses grid sampling - may miss very small smoke regions
|
|
464
|
+
- Inner background removal performance depends on transparent region size
|
|
465
|
+
|
|
466
|
+
##### Recommended Usage
|
|
467
|
+
- Enable `--try-inner` for sprites with complex interior backgrounds
|
|
468
|
+
- Use `--threshold-stepping` for sprites with subtle edge colors
|
|
469
|
+
- Enable `--multi-pass` for sprites with noticeable ghost edges
|
|
470
|
+
- Use `--remove-smoke` only if smoke effects detected in report
|
|
471
|
+
- For best performance, enable only features you need
|
|
472
|
+
|
|
473
|
+
#### Migration Guide
|
|
474
|
+
|
|
475
|
+
##### Upgrading from v0.6.7.1
|
|
476
|
+
|
|
477
|
+
**No Changes Required**
|
|
478
|
+
```bash
|
|
479
|
+
# Existing workflows continue to work unchanged
|
|
480
|
+
ruby_spriter --video input.mp4 --remove-bg --scale 50%
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
**Opt-In to New Features**
|
|
484
|
+
```bash
|
|
485
|
+
# Basic inner background removal
|
|
486
|
+
ruby_spriter --video input.mp4 --remove-bg --try-inner
|
|
487
|
+
|
|
488
|
+
# Full pipeline with all features
|
|
489
|
+
ruby_spriter --video input.mp4 --remove-bg \
|
|
490
|
+
--threshold-stepping \
|
|
491
|
+
--try-inner \
|
|
492
|
+
--multi-pass \
|
|
493
|
+
--remove-smoke
|
|
494
|
+
|
|
495
|
+
# Advanced configuration
|
|
496
|
+
ruby_spriter --video input.mp4 --remove-bg \
|
|
497
|
+
--try-inner \
|
|
498
|
+
--inner-tolerance 15.0 \
|
|
499
|
+
--inner-opacity 0.85 \
|
|
500
|
+
--inner-radius 15 \
|
|
501
|
+
--ghost-threshold 40
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
**Performance Optimization**
|
|
505
|
+
```bash
|
|
506
|
+
# For simple sprites: edge removal only (fastest)
|
|
507
|
+
ruby_spriter --video input.mp4 --remove-bg
|
|
508
|
+
|
|
509
|
+
# For sprites with interior backgrounds: add --try-inner (moderate)
|
|
510
|
+
ruby_spriter --video input.mp4 --remove-bg --try-inner
|
|
511
|
+
|
|
512
|
+
# For complex sprites: full pipeline (slowest but highest quality)
|
|
513
|
+
ruby_spriter --video input.mp4 --remove-bg --threshold-stepping --try-inner --multi-pass
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
---
|
|
517
|
+
|
|
518
|
+
## [0.6.7.1] - 2025-10-24
|
|
519
|
+
|
|
520
|
+
### ๐ง Linux Support Enhancement Release
|
|
521
|
+
|
|
522
|
+
#### Added
|
|
523
|
+
- **Linux GIMP 3.x Support**: Full support for GIMP 3.x on Linux via Flatpak
|
|
524
|
+
- Automatic detection of Flatpak GIMP installation (`flatpak:org.gimp.GIMP`)
|
|
525
|
+
- Automatic Xvfb integration for completely headless GIMP operation
|
|
526
|
+
- Virtual display provided by Xvfb eliminates display connection requirement
|
|
527
|
+
- Flatpak socket isolation (`--nosocket=x11 --nosocket=wayland`) prevents GUI from appearing
|
|
528
|
+
- Python-fu batch mode works correctly with `python-fu-eval` interpreter
|
|
529
|
+
- Background removal, scaling, and all GIMP features fully functional
|
|
530
|
+
- Perfect for desktop use (no GUI distraction) and server environments (CI/CD, Docker, SSH)
|
|
531
|
+
- **GIMP Version Detection**: Detect and report GIMP version (2.x or 3.x)
|
|
532
|
+
- `Platform.detect_gimp_version(version_output)` - Parse version from `--version` output
|
|
533
|
+
- `Platform.get_gimp_version(gimp_path)` - Get version from executable or Flatpak
|
|
534
|
+
- Works with both regular executables and Flatpak installations
|
|
535
|
+
- **Xvfb Dependency Checking**: Added Xvfb to dependency checker (Linux only)
|
|
536
|
+
- Marked as required on Linux, optional on Windows/macOS
|
|
537
|
+
- Provides clear installation instructions if missing
|
|
538
|
+
- Validates availability before GIMP operations
|
|
539
|
+
- **DependencyChecker Version Tracking**: Store and report detected GIMP version
|
|
540
|
+
- **Xvfb Integration**: Transparent Xvfb usage when GIMP Flatpak detected
|
|
541
|
+
- Command format: `xvfb-run --auto-servernum --server-args='-screen 0 1024x768x24' flatpak run --nosocket=x11 --nosocket=wayland org.gimp.GIMP --no-splash --quit --batch-interpreter=python-fu-eval`
|
|
542
|
+
- No user configuration required - works automatically
|
|
543
|
+
- Completely headless - no GUI windows appear on screen
|
|
544
|
+
|
|
545
|
+
#### Changed
|
|
546
|
+
- **Platform Detection**: Enhanced to detect Flatpak GIMP alongside traditional installations
|
|
547
|
+
- **GimpProcessor**: Updated to support both GIMP 2.x and 3.x APIs (version-aware)
|
|
548
|
+
- **Unix GIMP Execution**: Automatically uses Xvfb with socket isolation for Flatpak installations
|
|
549
|
+
- **Alternative GIMP Paths**: Added `flatpak:org.gimp.GIMP` to Linux search paths
|
|
550
|
+
- **Warning Filters**: Enhanced to filter Xvfb, Wayland, and Flatpak cosmetic warnings
|
|
551
|
+
- **DependencyChecker**: Now supports platform-specific optional dependencies
|
|
552
|
+
|
|
553
|
+
#### Technical Details
|
|
554
|
+
- **GIMP Flatpak Detection**: Uses `flatpak list --app | grep` to verify installation
|
|
555
|
+
- **Version Parsing**: Regex-based parsing of `GIMP version X.Y.Z` output
|
|
556
|
+
- **Python Interpreter**: Correct name is `python-fu-eval` (not `python-eval`)
|
|
557
|
+
- **Xvfb Flags**:
|
|
558
|
+
- `--auto-servernum` - Automatically finds free display number
|
|
559
|
+
- `--server-args='-screen 0 1024x768x24'` - Configures virtual display
|
|
560
|
+
- **Flatpak Socket Isolation**:
|
|
561
|
+
- `--nosocket=x11` - Prevents access to host X11 display socket
|
|
562
|
+
- `--nosocket=wayland` - Prevents access to host Wayland display socket
|
|
563
|
+
- Ensures GIMP runs only in Xvfb virtual display
|
|
564
|
+
- **Platform Module**: New methods for version detection and Flatpak handling
|
|
565
|
+
- **Warning Filtering**: Filters Gdk-WARNING, LibGimp-WARNING, Gimp-Core-WARNING, X11 socket messages
|
|
566
|
+
|
|
567
|
+
#### Installation Requirements (Linux)
|
|
568
|
+
```bash
|
|
569
|
+
# Ubuntu/Debian
|
|
570
|
+
sudo apt install flatpak xvfb -y
|
|
571
|
+
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
|
572
|
+
flatpak install flathub org.gimp.GIMP -y
|
|
573
|
+
|
|
574
|
+
# Fedora/RHEL
|
|
575
|
+
sudo dnf install flatpak xorg-x11-server-Xvfb -y
|
|
576
|
+
flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo
|
|
577
|
+
flatpak install flathub org.gimp.GIMP -y
|
|
578
|
+
```
|
|
579
|
+
|
|
580
|
+
#### Example Output
|
|
581
|
+
```bash
|
|
582
|
+
$ ruby_spriter --check-dependencies
|
|
583
|
+
============================================================
|
|
584
|
+
Dependency Check
|
|
585
|
+
============================================================
|
|
586
|
+
|
|
587
|
+
โ
FFMPEG
|
|
588
|
+
Found: 6.1.1
|
|
589
|
+
|
|
590
|
+
โ
FFPROBE
|
|
591
|
+
Found: 6.1.1
|
|
592
|
+
|
|
593
|
+
โ
IMAGEMAGICK
|
|
594
|
+
Found: Version: ImageMagick 6.9.12-98 Q16 x86_64
|
|
595
|
+
|
|
596
|
+
โ
XVFB
|
|
597
|
+
Found: Usage: xvfb-run [OPTION ...] COMMAND
|
|
598
|
+
|
|
599
|
+
โ
GIMP
|
|
600
|
+
Found: flatpak:org.gimp.GIMP
|
|
601
|
+
Version: GIMP 3.0.6
|
|
602
|
+
|
|
603
|
+
============================================================
|
|
604
|
+
|
|
605
|
+
$ ruby_spriter --image sprite.png --remove-bg
|
|
606
|
+
============================================================
|
|
607
|
+
GIMP Processing
|
|
608
|
+
============================================================
|
|
609
|
+
๐ Using GIMP via Xvfb (virtual display)
|
|
610
|
+
Removing background (fuzzy select)...
|
|
611
|
+
=== GIMP Messages ===
|
|
612
|
+
Loading image...
|
|
613
|
+
Image size: 1280x748
|
|
614
|
+
Added alpha channel
|
|
615
|
+
Sampling 4 corners...
|
|
616
|
+
Using FUZZY SELECT (contiguous regions only)
|
|
617
|
+
Corner 1 at (0, 0)
|
|
618
|
+
Corner 2 at (1279, 0)
|
|
619
|
+
Corner 3 at (0, 747)
|
|
620
|
+
Corner 4 at (1279, 747)
|
|
621
|
+
Selection complete
|
|
622
|
+
Growing selection by 1 pixels...
|
|
623
|
+
Selection grown
|
|
624
|
+
Removing background...
|
|
625
|
+
Background removed
|
|
626
|
+
Deselecting...
|
|
627
|
+
Exporting...
|
|
628
|
+
SUCCESS - Background removed!
|
|
629
|
+
====================
|
|
630
|
+
โ
Background Removal complete (142.15 KB)
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
**Note**: No GIMP GUI window appears on screen - completely headless operation!
|
|
634
|
+
|
|
635
|
+
---
|
|
636
|
+
|
|
637
|
+
## [0.6.7] - 2025-10-24
|
|
638
|
+
|
|
639
|
+
### ๐ Batch Processing, Compression, Directory Consolidation & Frame Extraction Release
|
|
640
|
+
|
|
641
|
+
#### Added
|
|
642
|
+
- **Batch Processing Mode** (`--batch`): Process multiple MP4 files in a directory (Issue #16)
|
|
643
|
+
- `--dir DIRECTORY`: Specify directory containing MP4 files to process
|
|
644
|
+
- `--outputdir DIRECTORY`: Optional output directory (defaults to input directory)
|
|
645
|
+
- `--batch-consolidate`: Automatically consolidate all resulting spritesheets
|
|
646
|
+
- Supports all existing processing options: `--scale`, `--remove-bg`, `--sharpen`, `--interpolation`, etc.
|
|
647
|
+
- Enforces unique filenames unless `--overwrite` is specified
|
|
648
|
+
- Continues processing remaining videos if one fails
|
|
649
|
+
- Provides detailed summary of successes and failures
|
|
650
|
+
- **Maximum Compression** (`--max-compress`): Apply maximum PNG compression (Issue #14)
|
|
651
|
+
- Uses ImageMagick with optimal compression settings (level 9, filter 5, strategy 1, quality 95)
|
|
652
|
+
- Preserves embedded metadata through compression
|
|
653
|
+
- Works with all processing modes: `--video`, `--image`, `--batch`, `--consolidate`
|
|
654
|
+
- Displays compression statistics (original size, compressed size, savings, reduction percentage)
|
|
655
|
+
- **Directory-Based Consolidation**: `--consolidate` now supports `--dir` option to automatically consolidate all spritesheets in a directory
|
|
656
|
+
- Scans directory for PNG files with embedded spritesheet metadata
|
|
657
|
+
- Automatically filters out non-spritesheet PNG files
|
|
658
|
+
- Sorts files alphabetically by filename before consolidation
|
|
659
|
+
- Requires at least 2 valid spritesheets in directory
|
|
660
|
+
- Works with all existing consolidation options: `--output`, `--outputdir`, `--overwrite`, `--max-compress`, `--no-validate-columns`
|
|
661
|
+
- Mutual exclusivity validation: Cannot use both comma-separated file list and `--dir` with `--consolidate`
|
|
662
|
+
- **Enhanced Context-Sensitive Help System**: Mode-specific help displays only relevant options
|
|
663
|
+
- `ruby_spriter --video --help`: Shows video mode options (spritesheet generation, processing, output)
|
|
664
|
+
- `ruby_spriter --image --help`: Shows image mode options (processing, frame extraction, output)
|
|
665
|
+
- `ruby_spriter --consolidate --help`: Shows consolidation options (input methods, validation, output)
|
|
666
|
+
- `ruby_spriter --batch --help`: Shows batch processing options (directory processing, applied options)
|
|
667
|
+
- `ruby_spriter --split --help`: Shows frame extraction options (split format, metadata behavior, output)
|
|
668
|
+
- General `--help`: Shows mode-specific help hints and directs users to detailed help
|
|
669
|
+
- **Parent-Child Option Hierarchy**: Visual hierarchy (โโ) shows modifier options grouped under parent options
|
|
670
|
+
- `--interpolation`, `--sharpen*` modifiers shown under `--scale`
|
|
671
|
+
- `--fuzzy`, `--threshold`, `--grow` modifiers shown under `--remove-bg`
|
|
672
|
+
- `--override-md` modifier shown under `--split`
|
|
673
|
+
- `--validate-columns` modifier shown under `--consolidate --dir`
|
|
674
|
+
- Organized by function (Image Processing, Output Options) instead of by tool (GIMP Processing Options)
|
|
675
|
+
- **Frame Extraction** (`--extract`): Extract specific frames and create new spritesheet
|
|
676
|
+
- `--extract FRAMES`: Comma-separated frame numbers (e.g., `1,2,4,5,8`)
|
|
677
|
+
- `--columns NUM`: Specify output grid columns (default: 4)
|
|
678
|
+
- Supports duplicate frame numbers for animation sequences
|
|
679
|
+
- 1-indexed frame numbering (left-to-right, top-to-bottom)
|
|
680
|
+
- Requires spritesheet metadata (works with `--verify` output)
|
|
681
|
+
- Works with all `--image` processing options: `--scale`, `--remove-bg`, `--sharpen`, `--max-compress`
|
|
682
|
+
- Automatic output naming with `_extracted` suffix or custom via `--output`
|
|
683
|
+
- Temporary frames deleted after reassembly unless `--save-frames` specified
|
|
684
|
+
- Minimum 2 frames required
|
|
685
|
+
- Out-of-bounds validation against spritesheet metadata
|
|
686
|
+
- Mutual exclusivity with `--split`
|
|
687
|
+
- **Metadata Management** (`--add-meta`): Add spritesheet metadata to images without metadata
|
|
688
|
+
- `--add-meta R:C`: Specify grid layout (rows:columns, e.g., `4:4`)
|
|
689
|
+
- `--overwrite-meta`: Replace existing metadata
|
|
690
|
+
- `--frames COUNT`: Custom frame count for partial grids (fewer frames than grid size)
|
|
691
|
+
- In-place modification by default (respects `--overwrite` flag)
|
|
692
|
+
- Optional `--output` for copying to new file
|
|
693
|
+
- Dimension validation: Image dimensions must divide evenly by grid
|
|
694
|
+
- Enables `--extract`, `--consolidate`, `--verify`, `--split` on external spritesheets
|
|
695
|
+
- Standalone mode: Cannot combine with `--scale`, `--remove-bg`, `--sharpen`
|
|
696
|
+
- **Enhanced `--save-frames`**: Now works with both `--video` and `--extract`
|
|
697
|
+
- **New Modules**:
|
|
698
|
+
- `BatchProcessor` (lib/ruby_spriter/batch_processor.rb): Orchestrates batch video processing
|
|
699
|
+
- `CompressionManager` (lib/ruby_spriter/compression_manager.rb): Handles PNG compression with metadata preservation
|
|
700
|
+
- **New Public Method**: `Consolidator#find_spritesheets_in_directory(directory)` for directory scanning
|
|
701
|
+
- **Comprehensive Test Coverage**: 68 new tests (13 for BatchProcessor, 11 for CompressionManager, 15 for directory consolidation, 7 for context-sensitive help, 22 for frame extraction and metadata management)
|
|
702
|
+
|
|
703
|
+
#### Changed
|
|
704
|
+
- **CLI**: Updated `--consolidate` description to mention `--dir` option
|
|
705
|
+
- **CLI**: Renamed "GIMP Processing Options" to "Processing Options" for tool-agnostic organization
|
|
706
|
+
- **CLI**: Updated image mode help with Frame Extraction & Reassembly section
|
|
707
|
+
- **CLI**: Added Metadata Management section to image mode help
|
|
708
|
+
- **Processor**: Refactored consolidation workflow to support both file list and directory modes
|
|
709
|
+
- **Test Suite**: Increased from 274 to 365 examples (all passing), 75.8% line coverage
|
|
710
|
+
- **CLI**: Added parent-child visual hierarchy to all context-sensitive help displays
|
|
711
|
+
- **CLI**: Corrected `--sharpen` to show as standalone option (not under `--scale`)
|
|
712
|
+
|
|
713
|
+
#### Examples
|
|
714
|
+
```bash
|
|
715
|
+
# Get context-sensitive help for specific modes
|
|
716
|
+
ruby_spriter --video --help
|
|
717
|
+
ruby_spriter --image --help
|
|
718
|
+
ruby_spriter --consolidate --help
|
|
719
|
+
ruby_spriter --batch --help
|
|
720
|
+
ruby_spriter --split --help
|
|
721
|
+
|
|
722
|
+
# Process all videos in directory
|
|
723
|
+
ruby_spriter --batch --dir "videos/"
|
|
724
|
+
|
|
725
|
+
# Process with output to different directory
|
|
726
|
+
ruby_spriter --batch --dir "videos/" --outputdir "output/"
|
|
727
|
+
|
|
728
|
+
# Process and consolidate all results
|
|
729
|
+
ruby_spriter --batch --dir "videos/" --batch-consolidate
|
|
730
|
+
|
|
731
|
+
# Process with scaling and compression
|
|
732
|
+
ruby_spriter --batch --dir "videos/" --scale 50 --max-compress
|
|
733
|
+
|
|
734
|
+
# Compress video output
|
|
735
|
+
ruby_spriter --video "input.mp4" --max-compress
|
|
736
|
+
|
|
737
|
+
# Compress image processing output
|
|
738
|
+
ruby_spriter --image "sprite.png" --scale 50 --max-compress
|
|
739
|
+
|
|
740
|
+
# Directory-based consolidation
|
|
741
|
+
ruby_spriter --consolidate --dir "spritesheets/"
|
|
742
|
+
ruby_spriter --consolidate --dir "spritesheets/" --outputdir "output/"
|
|
743
|
+
ruby_spriter --consolidate --dir "spritesheets/" --max-compress
|
|
744
|
+
|
|
745
|
+
# File list consolidation still works
|
|
746
|
+
ruby_spriter --consolidate file1.png,file2.png,file3.png
|
|
747
|
+
|
|
748
|
+
# Extract specific frames and create new spritesheet
|
|
749
|
+
ruby_spriter --image sprite.png --extract 1,2,4,5,8 --columns 3
|
|
750
|
+
|
|
751
|
+
# Extract with duplicates for animation loops
|
|
752
|
+
ruby_spriter --image sprite.png --extract 1,1,2,2,3,3 --save-frames
|
|
753
|
+
|
|
754
|
+
# Extract and process
|
|
755
|
+
ruby_spriter --image sprite.png --extract 1,3,5,7 --scale 50 --sharpen
|
|
756
|
+
|
|
757
|
+
# Add metadata to external spritesheet
|
|
758
|
+
ruby_spriter --image sprite.png --add-meta 4:4
|
|
759
|
+
|
|
760
|
+
# Add metadata with partial grid
|
|
761
|
+
ruby_spriter --image sprite.png --add-meta 4:4 --frames 14 --output sprite_meta.png
|
|
762
|
+
|
|
763
|
+
# Replace existing metadata
|
|
764
|
+
ruby_spriter --image existing.png --add-meta 8:8 --overwrite-meta
|
|
765
|
+
|
|
766
|
+
# Workflow: Add metadata, then extract frames
|
|
767
|
+
ruby_spriter --image external.png --add-meta 4:4
|
|
768
|
+
ruby_spriter --image external.png --extract 1,5,9,13 --columns 2
|
|
769
|
+
```
|
|
770
|
+
|
|
771
|
+
Closes #14, #16
|
|
772
|
+
|
|
773
|
+
---
|
|
774
|
+
|
|
775
|
+
## [0.6.6] - 2025-10-23
|
|
776
|
+
|
|
777
|
+
### ๐ File Protection & Frame Extraction Release
|
|
778
|
+
|
|
779
|
+
#### Added
|
|
780
|
+
- **Automatic Unique Filenames**: By default, generates timestamped filenames to prevent accidental overwrites
|
|
781
|
+
- Format: `filename_YYYYMMDD_HHMMSS_mmm.ext` (includes milliseconds)
|
|
782
|
+
- Applies to all output modes: `--video`, `--image`, `--consolidate`
|
|
783
|
+
- Works with both auto-generated and `--output` specified filenames
|
|
784
|
+
- **`--overwrite` Flag**: Optional flag to explicitly allow overwriting existing files
|
|
785
|
+
- **`--split R:C` Option**: Split spritesheets into individual frames for `--image` workflow
|
|
786
|
+
- Format: `--split 4:4` (rows:columns, e.g., 4 rows ร 4 columns)
|
|
787
|
+
- Validation: Rows and columns must be 1-99, total frames < 1000
|
|
788
|
+
- Frame naming: `FRddd_filename.png` (3-digit zero-padded format: FR001, FR002, ..., FR999)
|
|
789
|
+
- Output directory: `filename_frames/`
|
|
790
|
+
- Metadata priority: Uses embedded metadata if available, unless `--override-md` flag is provided
|
|
791
|
+
- Dimension validation: Image dimensions must divide evenly by specified rows and columns
|
|
792
|
+
- **`--override-md` Flag**: Override embedded metadata when using `--split` with images that have metadata
|
|
793
|
+
- **Intermediate File Cleanup**: Fixed cleanup of intermediate files from GIMP processing
|
|
794
|
+
- Now correctly removes files with dash separator (e.g., `file-nobg-fuzzy.png`, `file-scaled-40pct.png`)
|
|
795
|
+
- Added Windows-compatible path normalization for file comparison
|
|
796
|
+
- **Frame Extraction Tests**: 17 new comprehensive tests for split functionality
|
|
797
|
+
- CLI option tests for `--split` and `--override-md`
|
|
798
|
+
- Format and range validation tests (10 tests)
|
|
799
|
+
- Metadata priority logic tests (5 tests)
|
|
800
|
+
- Updated SpritesheetSplitter tests for FR%03d format
|
|
801
|
+
|
|
802
|
+
#### Changed
|
|
803
|
+
- **Default Behavior**: Changed from overwriting to creating unique files (breaking change, but safer)
|
|
804
|
+
- **GimpProcessor**: Now respects `--overwrite` flag for scaled and background-removed images
|
|
805
|
+
- **Consolidate Workflow**: Default filename changed from `consolidated_spritesheet_TIMESTAMP.png` to `consolidated_spritesheet.png` (uniqueness handled by flag)
|
|
806
|
+
- **Frame Naming Format**: Changed from FR%02d (2 digits) to FR%03d (3 digits) to support up to 999 frames
|
|
807
|
+
- **Intermediate File Pattern**: Fixed glob pattern from underscore to dash separator for GIMP output files
|
|
808
|
+
|
|
809
|
+
#### Technical Details
|
|
810
|
+
- New utility methods in `Utils::FileHelper`:
|
|
811
|
+
- `unique_filename(path)` - Generates timestamped filename if file exists
|
|
812
|
+
- `ensure_unique_output(path, overwrite:)` - Applies overwrite logic
|
|
813
|
+
- New methods in `Processor`:
|
|
814
|
+
- `validate_split_option!` - Validates split format and ranges during initialization
|
|
815
|
+
- `determine_split_parameters(image_file)` - Implements metadata priority logic
|
|
816
|
+
- `validate_image_dimensions(image_file, rows, columns)` - Validates even division
|
|
817
|
+
- Processor workflows updated to use `ensure_unique_output` for all output paths
|
|
818
|
+
- `SpritesheetSplitter` updated to use 3-digit frame format (FR%03d)
|
|
819
|
+
- Test coverage increased to 72.27% (688/952 lines)
|
|
820
|
+
|
|
821
|
+
Closes #17, #19, #30
|
|
822
|
+
|
|
823
|
+
---
|
|
824
|
+
|
|
825
|
+
## [0.6.5] - 2025-10-23
|
|
826
|
+
|
|
827
|
+
### ๐ฆ Distribution & Packaging Release
|
|
828
|
+
|
|
829
|
+
**Note**: Version 0.6.5 is functionally identical to 0.6.4, which was yanked from RubyGems due to RubyGems policy preventing re-publication of yanked versions.
|
|
830
|
+
|
|
831
|
+
#### Added
|
|
832
|
+
- **GitHub Actions CI/CD Pipeline**: Automated testing across Ruby 2.7-3.3 on Ubuntu, macOS, and Windows
|
|
833
|
+
- **Automated RubyGems Publishing**: Auto-publish gem to RubyGems.org on version tag push
|
|
834
|
+
- **Release Automation Workflow**: Multi-platform gem builds with artifact uploads to GitHub Releases
|
|
835
|
+
- **Code Coverage Reporting**: SimpleCov integration in CI with PR summaries
|
|
836
|
+
|
|
837
|
+
#### Changed
|
|
838
|
+
- **Installation Options**: Two installation methods (RubyGems for all platforms, from source)
|
|
839
|
+
- **README Structure**: Simplified installation section focusing on gem distribution
|
|
840
|
+
- **Gemspec Author Info**: Updated from placeholders to actual author details
|
|
841
|
+
|
|
842
|
+
#### Distribution
|
|
843
|
+
- **RubyGems**: Published gem with all runtime files (works on Windows, macOS, Linux)
|
|
844
|
+
- **Source Install**: Git clone with local gem build option
|
|
845
|
+
|
|
846
|
+
#### Deferred
|
|
847
|
+
- **Windows Standalone Executable**: Deferred due to OCRA incompatibility with Ruby 3.x
|
|
848
|
+
- OCRA 1.3.11 (last version, 2019) fails with Ruby 3.2+ due to internal fiber changes
|
|
849
|
+
- Windows users can use `gem install ruby_spriter` after installing Ruby
|
|
850
|
+
- Will revisit when better Windows packaging tools become available
|
|
851
|
+
|
|
852
|
+
Closes #18
|
|
853
|
+
|
|
854
|
+
---
|
|
855
|
+
|
|
856
|
+
## [0.6.4] - 2025-10-23 [YANKED]
|
|
857
|
+
|
|
858
|
+
Version yanked from RubyGems. Use 0.6.5 instead.
|
|
859
|
+
|
|
860
|
+
### ๐ฆ Distribution & Packaging Release
|
|
861
|
+
|
|
862
|
+
#### Added
|
|
863
|
+
- **GitHub Actions CI/CD Pipeline**: Automated testing across Ruby 2.7-3.3 on Ubuntu, macOS, and Windows
|
|
864
|
+
- **Automated RubyGems Publishing**: Auto-publish gem to RubyGems.org on version tag push
|
|
865
|
+
- **Release Automation Workflow**: Multi-platform gem builds with artifact uploads to GitHub Releases
|
|
866
|
+
- **Code Coverage Reporting**: SimpleCov integration in CI with PR summaries
|
|
867
|
+
|
|
868
|
+
#### Changed
|
|
869
|
+
- **Installation Options**: Two installation methods (RubyGems for all platforms, from source)
|
|
870
|
+
- **README Structure**: Simplified installation section focusing on gem distribution
|
|
871
|
+
- **Gemspec Author Info**: Updated from placeholders to actual author details
|
|
872
|
+
|
|
873
|
+
#### Distribution
|
|
874
|
+
- **RubyGems**: Published gem with all runtime files (works on Windows, macOS, Linux)
|
|
875
|
+
- **Source Install**: Git clone with local gem build option
|
|
876
|
+
|
|
877
|
+
#### Deferred
|
|
878
|
+
- **Windows Standalone Executable**: Deferred due to OCRA incompatibility with Ruby 3.x
|
|
879
|
+
- OCRA 1.3.11 (last version, 2019) fails with Ruby 3.2+ due to internal fiber changes
|
|
880
|
+
- Windows users can use `gem install ruby_spriter` after installing Ruby
|
|
881
|
+
- Will revisit when better Windows packaging tools become available
|
|
882
|
+
|
|
883
|
+
Closes #18
|
|
884
|
+
|
|
885
|
+
---
|
|
886
|
+
|
|
887
|
+
## [0.6.3] - 2025-10-23
|
|
888
|
+
|
|
889
|
+
### ๐งช Testing & Quality Assurance Release
|
|
890
|
+
|
|
891
|
+
#### Added
|
|
892
|
+
- **155 New RSpec Tests**: Comprehensive test coverage for CLI, GimpProcessor, Consolidator, PathHelper
|
|
893
|
+
- **Test Fixtures**: Real spritesheet fixtures (4x2, 6x2, 4x4), PNG images, MP4 video
|
|
894
|
+
- **Code Coverage Reporting**: SimpleCov tracking showing 57.09% coverage
|
|
895
|
+
|
|
896
|
+
#### Fixed
|
|
897
|
+
- **CLI Preset Bug**: Fixed OptionParser limitation preventing all 4 presets from working
|
|
898
|
+
- **PathHelper Quote Escaping**: Fixed single quote escaping in Unix paths (needed 4 backslashes)
|
|
899
|
+
- **Spec Helper Bug**: Changed instance variable to global variable for cross-context access
|
|
900
|
+
- **PathHelper Tests**: Made drive letter detection flexible for E: drive compatibility
|
|
901
|
+
|
|
902
|
+
#### Testing
|
|
903
|
+
- **CLI Tests (97)**: --help, --version, --check-dependencies, --image, --video, --consolidate, --verify
|
|
904
|
+
- **GimpProcessor Tests (48)**: Initialization, operations, interpolation, output filtering, script generation
|
|
905
|
+
- **Consolidator Tests (33)**: File validation, metadata, column validation, consolidation logic
|
|
906
|
+
- **PathHelper Tests (7)**: Quote paths, normalize for Python, native format conversion
|
|
907
|
+
- **Coverage**: Increased from 22.52% to 57.09% (+34.57 percentage points)
|
|
908
|
+
|
|
909
|
+
Closes #5
|
|
910
|
+
|
|
911
|
+
---
|
|
912
|
+
|
|
913
|
+
## [0.6.2] - 2025-10-22
|
|
914
|
+
|
|
915
|
+
### โจ Quality Enhancement & Tooling Release
|
|
916
|
+
|
|
917
|
+
#### Added
|
|
918
|
+
- **Interpolation Options**: 5 interpolation methods for scaling (none, linear, cubic, nohalo, lohalo)
|
|
919
|
+
- **Sharpening Support**: Unsharp mask with configurable radius, gain, and threshold
|
|
920
|
+
- **`--version` Flag**: Display version, platform, and date information
|
|
921
|
+
- **`--check-dependencies` Flag**: Verify all external tools are installed with platform-specific guidance
|
|
922
|
+
- **File Extension Validation**: Runtime validation for MP4 (video) and PNG (images)
|
|
923
|
+
- **GIMP Investigation Documentation**: Comprehensive documentation of GIMP sharpen attempts and solutions
|
|
924
|
+
|
|
925
|
+
#### Changed
|
|
926
|
+
- **Automatic Operation Order**: Auto-optimize to remove background before scaling for better quality
|
|
927
|
+
- **Sharpening via ImageMagick**: Use ImageMagick instead of GIMP for reliable cross-platform sharpening
|
|
928
|
+
- **Alpha Channel Preservation**: Use merge instead of flatten to preserve transparency
|
|
929
|
+
- **Conservative Sharpen Defaults**: radius: 2.0, gain: 0.5, threshold: 0.03 to minimize halo artifacts
|
|
930
|
+
- **Parameter Terminology**: Changed "amount" to "gain" to match ImageMagick documentation
|
|
931
|
+
|
|
932
|
+
#### Fixed
|
|
933
|
+
- **Gem Build Error**: Removed .rb extension from `bin/ruby_spriter` executable
|
|
934
|
+
- **Clear Error Messages**: File extension validation provides helpful feedback
|
|
935
|
+
|
|
936
|
+
#### Documentation
|
|
937
|
+
- **README.md**: Added interpolation and sharpening documentation, file format requirements
|
|
938
|
+
- **CLAUDE.md**: Updated with new features and validation details
|
|
939
|
+
- **GIMP_SHARPEN_INVESTIGATION.md**: Documents 8 failed GIMP attempts and architectural decisions
|
|
940
|
+
|
|
941
|
+
---
|
|
942
|
+
|
|
943
|
+
## [0.6.1] - 2025-10-22
|
|
944
|
+
|
|
945
|
+
### ๐ Major Refactoring Release
|
|
946
|
+
|
|
947
|
+
#### Added
|
|
948
|
+
- **Modular Architecture**: Split monolithic script into organized modules
|
|
949
|
+
- **RSpec Testing Framework**: Comprehensive unit test coverage
|
|
950
|
+
- **Dependency Checking**: Automatic validation of external tools
|
|
951
|
+
- **Better Error Handling**: Custom exception classes
|
|
952
|
+
- **Code Documentation**: Inline comments and YARD-compatible docs
|
|
953
|
+
- **SimpleCov Integration**: Code coverage reporting
|
|
954
|
+
- **RuboCop Support**: Code style enforcement
|
|
955
|
+
|
|
956
|
+
#### Changed
|
|
957
|
+
- **Project Structure**: Reorganized into `lib/`, `spec/`, and `bin/` directories
|
|
958
|
+
- **Class Organization**:
|
|
959
|
+
- `Platform` - Platform detection and configuration
|
|
960
|
+
- `DependencyChecker` - External tool validation
|
|
961
|
+
- `VideoProcessor` - FFmpeg operations
|
|
962
|
+
- `GimpProcessor` - GIMP operations
|
|
963
|
+
- `MetadataManager` - PNG metadata handling
|
|
964
|
+
- `Consolidator` - Spritesheet consolidation
|
|
965
|
+
- `Processor` - Main orchestration
|
|
966
|
+
- `CLI` - Command-line interface
|
|
967
|
+
- Utilities: `PathHelper`, `FileHelper`, `OutputFormatter`
|
|
968
|
+
|
|
969
|
+
#### Fixed
|
|
970
|
+
- Path handling edge cases on Windows
|
|
971
|
+
- Improved error messages with actionable guidance
|
|
972
|
+
- Better temp file cleanup
|
|
973
|
+
|
|
974
|
+
#### Developer Experience
|
|
975
|
+
- Gemfile for dependency management
|
|
976
|
+
- RSpec test suite with fixtures
|
|
977
|
+
- Comprehensive README with examples
|
|
978
|
+
- Troubleshooting guide
|
|
979
|
+
- Contributing guidelines
|
|
980
|
+
|
|
981
|
+
---
|
|
982
|
+
|
|
983
|
+
## [0.6.0] - 2024-XX-XX
|
|
984
|
+
|
|
985
|
+
### Added
|
|
986
|
+
- Metadata embedding in PNG files
|
|
987
|
+
- Spritesheet consolidation feature
|
|
988
|
+
- Metadata verification command (`--verify`)
|
|
989
|
+
- Debug mode for troubleshooting
|
|
990
|
+
|
|
991
|
+
### Changed
|
|
992
|
+
- Improved GIMP script generation
|
|
993
|
+
- Better cross-platform path handling
|
|
994
|
+
|
|
995
|
+
---
|
|
996
|
+
|
|
997
|
+
## [0.5.0] - 2024-XX-XX
|
|
998
|
+
|
|
999
|
+
### Added
|
|
1000
|
+
- Background removal with GIMP
|
|
1001
|
+
- Fuzzy select and global color select options
|
|
1002
|
+
- Image scaling support
|
|
1003
|
+
- Configurable operation order
|
|
1004
|
+
|
|
1005
|
+
---
|
|
1006
|
+
|
|
1007
|
+
## [0.4.0] - 2024-XX-XX
|
|
1008
|
+
|
|
1009
|
+
### Added
|
|
1010
|
+
- Video to spritesheet conversion
|
|
1011
|
+
- FFmpeg integration
|
|
1012
|
+
- Customizable grid layouts
|
|
1013
|
+
|
|
1014
|
+
---
|
|
1015
|
+
|
|
1016
|
+
## [0.1.0] - 2024-XX-XX
|
|
1017
|
+
|
|
1018
|
+
### Added
|
|
1019
|
+
- Initial release
|
|
1020
|
+
- Basic video processing
|
|
1021
|
+
- Cross-platform support
|
|
1022
|
+
|
|
1023
|
+
---
|
|
1024
|
+
|
|
1025
|
+
[0.7.0.1]: https://github.com/scooter-indie/ruby-spriter/compare/v0.7.0...v0.7.0.1
|
|
1026
|
+
[0.7.0]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.7.1...v0.7.0
|
|
1027
|
+
[0.6.7.1]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.7...v0.6.7.1
|
|
1028
|
+
[0.6.7]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.6...v0.6.7
|
|
1029
|
+
[0.6.6]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.5...v0.6.6
|
|
1030
|
+
[0.6.5]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.4...v0.6.5
|
|
1031
|
+
[0.6.4]: https://github.com/scooter-indie/ruby-spriter/releases/tag/v0.6.4
|
|
1032
|
+
[0.6.3]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.2...v0.6.3
|
|
1033
|
+
[0.6.2]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.1...v0.6.2
|
|
1034
|
+
[0.6.1]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.0...v0.6.1
|
|
1035
|
+
[0.6.0]: https://github.com/scooter-indie/ruby-spriter/releases/tag/v0.6.0
|