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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.rspec +3 -3
  3. data/CHANGELOG.md +1035 -405
  4. data/Gemfile +17 -17
  5. data/LICENSE +21 -21
  6. data/README.md +183 -902
  7. data/bin/ruby_spriter +20 -20
  8. data/lib/ruby_spriter/background_sampler.rb +140 -0
  9. data/lib/ruby_spriter/batch_processor.rb +268 -212
  10. data/lib/ruby_spriter/cell_cleanup_config.rb +21 -0
  11. data/lib/ruby_spriter/cell_cleanup_gimp_script.rb +123 -0
  12. data/lib/ruby_spriter/cell_cleanup_processor.rb +230 -0
  13. data/lib/ruby_spriter/cli.rb +676 -612
  14. data/lib/ruby_spriter/compression_manager.rb +101 -101
  15. data/lib/ruby_spriter/consolidator.rb +179 -179
  16. data/lib/ruby_spriter/dependency_checker.rb +224 -174
  17. data/lib/ruby_spriter/ghost_edge_cleaner.rb +164 -0
  18. data/lib/ruby_spriter/gimp_processor.rb +1188 -667
  19. data/lib/ruby_spriter/metadata_manager.rb +117 -116
  20. data/lib/ruby_spriter/platform.rb +137 -82
  21. data/lib/ruby_spriter/processor.rb +1230 -886
  22. data/lib/ruby_spriter/smoke_detector.rb +223 -0
  23. data/lib/ruby_spriter/threshold_stepper.rb +227 -0
  24. data/lib/ruby_spriter/utils/file_helper.rb +82 -82
  25. data/lib/ruby_spriter/utils/image_helper.rb +16 -0
  26. data/lib/ruby_spriter/utils/output_formatter.rb +65 -65
  27. data/lib/ruby_spriter/utils/path_helper.rb +59 -59
  28. data/lib/ruby_spriter/utils/spritesheet_splitter.rb +86 -86
  29. data/lib/ruby_spriter/version.rb +6 -7
  30. data/lib/ruby_spriter/video_processor.rb +357 -139
  31. data/lib/ruby_spriter.rb +38 -34
  32. data/ruby_spriter.gemspec +44 -42
  33. data/spec/fixtures/centered_sprite_with_inner_bg.png +0 -0
  34. data/spec/fixtures/centered_sprite_with_inner_bg_inner_removed.png +0 -0
  35. data/spec/fixtures/centered_sprite_with_inner_bg_threshold_stepped.png +0 -0
  36. data/spec/fixtures/complex_background_sprite.png +0 -0
  37. data/spec/fixtures/death - bloodborne rekconing.mp4 +0 -0
  38. data/spec/fixtures/death - bloodborne rekconing_spritesheet-nobg-global.png +0 -0
  39. data/spec/fixtures/death - bloodborne rekconing_spritesheet.png +0 -0
  40. data/spec/fixtures/death - bloodborne rekconing_spritesheet_20251110_185027_431-nobg-global.png +0 -0
  41. data/spec/fixtures/death - bloodborne rekconing_spritesheet_20251110_185027_431.png +0 -0
  42. data/spec/fixtures/death - bloodborne rekconing_spritesheet_20251110_185125_738-nobg-global.png +0 -0
  43. data/spec/fixtures/death - bloodborne rekconing_spritesheet_20251110_185125_738.png +0 -0
  44. data/spec/fixtures/has_inner_bg.png +0 -0
  45. data/spec/fixtures/has_small_inner_bg.png +0 -0
  46. data/spec/fixtures/smoke_effect_sprite.png +0 -0
  47. data/spec/fixtures/spritesheet_with_metadata.png +0 -0
  48. data/spec/fixtures/test_sprite.png +0 -0
  49. data/spec/fixtures/test_sprite_smoke_processed.png +0 -0
  50. data/spec/fixtures/test_video_spritesheet.png +0 -0
  51. data/spec/fixtures/transparent_bg_sprite.png +0 -0
  52. data/spec/fixtures/walk_north_sprite-sheet.png +0 -0
  53. data/spec/integration/no_fuzzy_mode_spec.rb +100 -0
  54. data/spec/ruby_spriter/batch_processor_spec.rb +509 -200
  55. data/spec/ruby_spriter/cli_spec.rb +2026 -1892
  56. data/spec/ruby_spriter/compression_manager_spec.rb +157 -157
  57. data/spec/ruby_spriter/consolidator_spec.rb +538 -538
  58. data/spec/ruby_spriter/gimp_processor_spec.rb +523 -425
  59. data/spec/ruby_spriter/platform_spec.rb +92 -82
  60. data/spec/ruby_spriter/processor_spec.rb +911 -735
  61. data/spec/ruby_spriter/utils/file_helper_spec.rb +150 -150
  62. data/spec/ruby_spriter/utils/path_helper_spec.rb +78 -78
  63. data/spec/ruby_spriter/utils/spritesheet_splitter_spec.rb +104 -104
  64. data/spec/ruby_spriter/video_processor_spec.rb +346 -29
  65. data/spec/spec_helper.rb +41 -41
  66. data/spec/tmp/cli_test_output.png +0 -0
  67. data/spec/tmp/cli_test_output_20251105_114647_395.png +0 -0
  68. data/spec/tmp/combined_test.png +0 -0
  69. data/spec/tmp/compat_test.png +0 -0
  70. data/spec/tmp/compat_test_20251030_174233_361.png +0 -0
  71. data/spec/tmp/final_all_features.png +0 -0
  72. data/spec/tmp/final_test_all_features.png +0 -0
  73. data/spec/tmp/full_pipeline_test.png +0 -0
  74. data/spec/tmp/inner_test.png +0 -0
  75. data/spec/tmp/integration_test.png +0 -0
  76. data/spec/tmp/validation_test.png +0 -0
  77. data/spec/unit/background_sampler_spec.rb +132 -0
  78. data/spec/unit/cell_cleanup_config_spec.rb +32 -0
  79. data/spec/unit/cell_cleanup_gimp_script_spec.rb +59 -0
  80. data/spec/unit/cell_cleanup_processor_spec.rb +261 -0
  81. data/spec/unit/ghost_edge_cleaner_spec.rb +223 -0
  82. data/spec/unit/gimp_processor_single_point_selection_spec.rb +81 -0
  83. data/spec/unit/smoke_detector_spec.rb +246 -0
  84. data/spec/unit/threshold_stepper_spec.rb +195 -0
  85. metadata +56 -10
data/CHANGELOG.md CHANGED
@@ -1,405 +1,1035 @@
1
-
2
- ---
3
-
4
- ### **CHANGELOG.md**
5
- ```markdown
6
- # Changelog
7
-
8
- All notable changes to Ruby Spriter will be documented in this file.
9
-
10
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
11
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
12
-
13
- ---
14
-
15
- ## [0.6.7] - 2025-10-24
16
-
17
- ### ๐Ÿš€ Batch Processing, Compression, Directory Consolidation & Frame Extraction Release
18
-
19
- #### Added
20
- - **Batch Processing Mode** (`--batch`): Process multiple MP4 files in a directory (Issue #16)
21
- - `--dir DIRECTORY`: Specify directory containing MP4 files to process
22
- - `--outputdir DIRECTORY`: Optional output directory (defaults to input directory)
23
- - `--batch-consolidate`: Automatically consolidate all resulting spritesheets
24
- - Supports all existing processing options: `--scale`, `--remove-bg`, `--sharpen`, `--interpolation`, etc.
25
- - Enforces unique filenames unless `--overwrite` is specified
26
- - Continues processing remaining videos if one fails
27
- - Provides detailed summary of successes and failures
28
- - **Maximum Compression** (`--max-compress`): Apply maximum PNG compression (Issue #14)
29
- - Uses ImageMagick with optimal compression settings (level 9, filter 5, strategy 1, quality 95)
30
- - Preserves embedded metadata through compression
31
- - Works with all processing modes: `--video`, `--image`, `--batch`, `--consolidate`
32
- - Displays compression statistics (original size, compressed size, savings, reduction percentage)
33
- - **Directory-Based Consolidation**: `--consolidate` now supports `--dir` option to automatically consolidate all spritesheets in a directory
34
- - Scans directory for PNG files with embedded spritesheet metadata
35
- - Automatically filters out non-spritesheet PNG files
36
- - Sorts files alphabetically by filename before consolidation
37
- - Requires at least 2 valid spritesheets in directory
38
- - Works with all existing consolidation options: `--output`, `--outputdir`, `--overwrite`, `--max-compress`, `--no-validate-columns`
39
- - Mutual exclusivity validation: Cannot use both comma-separated file list and `--dir` with `--consolidate`
40
- - **Enhanced Context-Sensitive Help System**: Mode-specific help displays only relevant options
41
- - `ruby_spriter --video --help`: Shows video mode options (spritesheet generation, processing, output)
42
- - `ruby_spriter --image --help`: Shows image mode options (processing, frame extraction, output)
43
- - `ruby_spriter --consolidate --help`: Shows consolidation options (input methods, validation, output)
44
- - `ruby_spriter --batch --help`: Shows batch processing options (directory processing, applied options)
45
- - `ruby_spriter --split --help`: Shows frame extraction options (split format, metadata behavior, output)
46
- - General `--help`: Shows mode-specific help hints and directs users to detailed help
47
- - **Parent-Child Option Hierarchy**: Visual hierarchy (โ””โ”€) shows modifier options grouped under parent options
48
- - `--interpolation`, `--sharpen*` modifiers shown under `--scale`
49
- - `--fuzzy`, `--threshold`, `--grow` modifiers shown under `--remove-bg`
50
- - `--override-md` modifier shown under `--split`
51
- - `--validate-columns` modifier shown under `--consolidate --dir`
52
- - Organized by function (Image Processing, Output Options) instead of by tool (GIMP Processing Options)
53
- - **Frame Extraction** (`--extract`): Extract specific frames and create new spritesheet
54
- - `--extract FRAMES`: Comma-separated frame numbers (e.g., `1,2,4,5,8`)
55
- - `--columns NUM`: Specify output grid columns (default: 4)
56
- - Supports duplicate frame numbers for animation sequences
57
- - 1-indexed frame numbering (left-to-right, top-to-bottom)
58
- - Requires spritesheet metadata (works with `--verify` output)
59
- - Works with all `--image` processing options: `--scale`, `--remove-bg`, `--sharpen`, `--max-compress`
60
- - Automatic output naming with `_extracted` suffix or custom via `--output`
61
- - Temporary frames deleted after reassembly unless `--save-frames` specified
62
- - Minimum 2 frames required
63
- - Out-of-bounds validation against spritesheet metadata
64
- - Mutual exclusivity with `--split`
65
- - **Metadata Management** (`--add-meta`): Add spritesheet metadata to images without metadata
66
- - `--add-meta R:C`: Specify grid layout (rows:columns, e.g., `4:4`)
67
- - `--overwrite-meta`: Replace existing metadata
68
- - `--frames COUNT`: Custom frame count for partial grids (fewer frames than grid size)
69
- - In-place modification by default (respects `--overwrite` flag)
70
- - Optional `--output` for copying to new file
71
- - Dimension validation: Image dimensions must divide evenly by grid
72
- - Enables `--extract`, `--consolidate`, `--verify`, `--split` on external spritesheets
73
- - Standalone mode: Cannot combine with `--scale`, `--remove-bg`, `--sharpen`
74
- - **Enhanced `--save-frames`**: Now works with both `--video` and `--extract`
75
- - **New Modules**:
76
- - `BatchProcessor` (lib/ruby_spriter/batch_processor.rb): Orchestrates batch video processing
77
- - `CompressionManager` (lib/ruby_spriter/compression_manager.rb): Handles PNG compression with metadata preservation
78
- - **New Public Method**: `Consolidator#find_spritesheets_in_directory(directory)` for directory scanning
79
- - **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)
80
-
81
- #### Changed
82
- - **CLI**: Updated `--consolidate` description to mention `--dir` option
83
- - **CLI**: Renamed "GIMP Processing Options" to "Processing Options" for tool-agnostic organization
84
- - **CLI**: Updated image mode help with Frame Extraction & Reassembly section
85
- - **CLI**: Added Metadata Management section to image mode help
86
- - **Processor**: Refactored consolidation workflow to support both file list and directory modes
87
- - **Test Suite**: Increased from 274 to 365 examples (all passing), 75.8% line coverage
88
- - **CLI**: Added parent-child visual hierarchy to all context-sensitive help displays
89
- - **CLI**: Corrected `--sharpen` to show as standalone option (not under `--scale`)
90
-
91
- #### Examples
92
- ```bash
93
- # Get context-sensitive help for specific modes
94
- ruby_spriter --video --help
95
- ruby_spriter --image --help
96
- ruby_spriter --consolidate --help
97
- ruby_spriter --batch --help
98
- ruby_spriter --split --help
99
-
100
- # Process all videos in directory
101
- ruby_spriter --batch --dir "videos/"
102
-
103
- # Process with output to different directory
104
- ruby_spriter --batch --dir "videos/" --outputdir "output/"
105
-
106
- # Process and consolidate all results
107
- ruby_spriter --batch --dir "videos/" --batch-consolidate
108
-
109
- # Process with scaling and compression
110
- ruby_spriter --batch --dir "videos/" --scale 50 --max-compress
111
-
112
- # Compress video output
113
- ruby_spriter --video "input.mp4" --max-compress
114
-
115
- # Compress image processing output
116
- ruby_spriter --image "sprite.png" --scale 50 --max-compress
117
-
118
- # Directory-based consolidation
119
- ruby_spriter --consolidate --dir "spritesheets/"
120
- ruby_spriter --consolidate --dir "spritesheets/" --outputdir "output/"
121
- ruby_spriter --consolidate --dir "spritesheets/" --max-compress
122
-
123
- # File list consolidation still works
124
- ruby_spriter --consolidate file1.png,file2.png,file3.png
125
-
126
- # Extract specific frames and create new spritesheet
127
- ruby_spriter --image sprite.png --extract 1,2,4,5,8 --columns 3
128
-
129
- # Extract with duplicates for animation loops
130
- ruby_spriter --image sprite.png --extract 1,1,2,2,3,3 --save-frames
131
-
132
- # Extract and process
133
- ruby_spriter --image sprite.png --extract 1,3,5,7 --scale 50 --sharpen
134
-
135
- # Add metadata to external spritesheet
136
- ruby_spriter --image sprite.png --add-meta 4:4
137
-
138
- # Add metadata with partial grid
139
- ruby_spriter --image sprite.png --add-meta 4:4 --frames 14 --output sprite_meta.png
140
-
141
- # Replace existing metadata
142
- ruby_spriter --image existing.png --add-meta 8:8 --overwrite-meta
143
-
144
- # Workflow: Add metadata, then extract frames
145
- ruby_spriter --image external.png --add-meta 4:4
146
- ruby_spriter --image external.png --extract 1,5,9,13 --columns 2
147
- ```
148
-
149
- Closes #14, #16
150
-
151
- ---
152
-
153
- ## [0.6.6] - 2025-10-23
154
-
155
- ### ๐Ÿ”’ File Protection & Frame Extraction Release
156
-
157
- #### Added
158
- - **Automatic Unique Filenames**: By default, generates timestamped filenames to prevent accidental overwrites
159
- - Format: `filename_YYYYMMDD_HHMMSS_mmm.ext` (includes milliseconds)
160
- - Applies to all output modes: `--video`, `--image`, `--consolidate`
161
- - Works with both auto-generated and `--output` specified filenames
162
- - **`--overwrite` Flag**: Optional flag to explicitly allow overwriting existing files
163
- - **`--split R:C` Option**: Split spritesheets into individual frames for `--image` workflow
164
- - Format: `--split 4:4` (rows:columns, e.g., 4 rows ร— 4 columns)
165
- - Validation: Rows and columns must be 1-99, total frames < 1000
166
- - Frame naming: `FRddd_filename.png` (3-digit zero-padded format: FR001, FR002, ..., FR999)
167
- - Output directory: `filename_frames/`
168
- - Metadata priority: Uses embedded metadata if available, unless `--override-md` flag is provided
169
- - Dimension validation: Image dimensions must divide evenly by specified rows and columns
170
- - **`--override-md` Flag**: Override embedded metadata when using `--split` with images that have metadata
171
- - **Intermediate File Cleanup**: Fixed cleanup of intermediate files from GIMP processing
172
- - Now correctly removes files with dash separator (e.g., `file-nobg-fuzzy.png`, `file-scaled-40pct.png`)
173
- - Added Windows-compatible path normalization for file comparison
174
- - **Frame Extraction Tests**: 17 new comprehensive tests for split functionality
175
- - CLI option tests for `--split` and `--override-md`
176
- - Format and range validation tests (10 tests)
177
- - Metadata priority logic tests (5 tests)
178
- - Updated SpritesheetSplitter tests for FR%03d format
179
-
180
- #### Changed
181
- - **Default Behavior**: Changed from overwriting to creating unique files (breaking change, but safer)
182
- - **GimpProcessor**: Now respects `--overwrite` flag for scaled and background-removed images
183
- - **Consolidate Workflow**: Default filename changed from `consolidated_spritesheet_TIMESTAMP.png` to `consolidated_spritesheet.png` (uniqueness handled by flag)
184
- - **Frame Naming Format**: Changed from FR%02d (2 digits) to FR%03d (3 digits) to support up to 999 frames
185
- - **Intermediate File Pattern**: Fixed glob pattern from underscore to dash separator for GIMP output files
186
-
187
- #### Technical Details
188
- - New utility methods in `Utils::FileHelper`:
189
- - `unique_filename(path)` - Generates timestamped filename if file exists
190
- - `ensure_unique_output(path, overwrite:)` - Applies overwrite logic
191
- - New methods in `Processor`:
192
- - `validate_split_option!` - Validates split format and ranges during initialization
193
- - `determine_split_parameters(image_file)` - Implements metadata priority logic
194
- - `validate_image_dimensions(image_file, rows, columns)` - Validates even division
195
- - Processor workflows updated to use `ensure_unique_output` for all output paths
196
- - `SpritesheetSplitter` updated to use 3-digit frame format (FR%03d)
197
- - Test coverage increased to 72.27% (688/952 lines)
198
-
199
- Closes #17, #19, #30
200
-
201
- ---
202
-
203
- ## [0.6.5] - 2025-10-23
204
-
205
- ### ๐Ÿ“ฆ Distribution & Packaging Release
206
-
207
- **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.
208
-
209
- #### Added
210
- - **GitHub Actions CI/CD Pipeline**: Automated testing across Ruby 2.7-3.3 on Ubuntu, macOS, and Windows
211
- - **Automated RubyGems Publishing**: Auto-publish gem to RubyGems.org on version tag push
212
- - **Release Automation Workflow**: Multi-platform gem builds with artifact uploads to GitHub Releases
213
- - **Code Coverage Reporting**: SimpleCov integration in CI with PR summaries
214
-
215
- #### Changed
216
- - **Installation Options**: Two installation methods (RubyGems for all platforms, from source)
217
- - **README Structure**: Simplified installation section focusing on gem distribution
218
- - **Gemspec Author Info**: Updated from placeholders to actual author details
219
-
220
- #### Distribution
221
- - **RubyGems**: Published gem with all runtime files (works on Windows, macOS, Linux)
222
- - **Source Install**: Git clone with local gem build option
223
-
224
- #### Deferred
225
- - **Windows Standalone Executable**: Deferred due to OCRA incompatibility with Ruby 3.x
226
- - OCRA 1.3.11 (last version, 2019) fails with Ruby 3.2+ due to internal fiber changes
227
- - Windows users can use `gem install ruby_spriter` after installing Ruby
228
- - Will revisit when better Windows packaging tools become available
229
-
230
- Closes #18
231
-
232
- ---
233
-
234
- ## [0.6.4] - 2025-10-23 [YANKED]
235
-
236
- Version yanked from RubyGems. Use 0.6.5 instead.
237
-
238
- ### ๐Ÿ“ฆ Distribution & Packaging Release
239
-
240
- #### Added
241
- - **GitHub Actions CI/CD Pipeline**: Automated testing across Ruby 2.7-3.3 on Ubuntu, macOS, and Windows
242
- - **Automated RubyGems Publishing**: Auto-publish gem to RubyGems.org on version tag push
243
- - **Release Automation Workflow**: Multi-platform gem builds with artifact uploads to GitHub Releases
244
- - **Code Coverage Reporting**: SimpleCov integration in CI with PR summaries
245
-
246
- #### Changed
247
- - **Installation Options**: Two installation methods (RubyGems for all platforms, from source)
248
- - **README Structure**: Simplified installation section focusing on gem distribution
249
- - **Gemspec Author Info**: Updated from placeholders to actual author details
250
-
251
- #### Distribution
252
- - **RubyGems**: Published gem with all runtime files (works on Windows, macOS, Linux)
253
- - **Source Install**: Git clone with local gem build option
254
-
255
- #### Deferred
256
- - **Windows Standalone Executable**: Deferred due to OCRA incompatibility with Ruby 3.x
257
- - OCRA 1.3.11 (last version, 2019) fails with Ruby 3.2+ due to internal fiber changes
258
- - Windows users can use `gem install ruby_spriter` after installing Ruby
259
- - Will revisit when better Windows packaging tools become available
260
-
261
- Closes #18
262
-
263
- ---
264
-
265
- ## [0.6.3] - 2025-10-23
266
-
267
- ### ๐Ÿงช Testing & Quality Assurance Release
268
-
269
- #### Added
270
- - **155 New RSpec Tests**: Comprehensive test coverage for CLI, GimpProcessor, Consolidator, PathHelper
271
- - **Test Fixtures**: Real spritesheet fixtures (4x2, 6x2, 4x4), PNG images, MP4 video
272
- - **Code Coverage Reporting**: SimpleCov tracking showing 57.09% coverage
273
-
274
- #### Fixed
275
- - **CLI Preset Bug**: Fixed OptionParser limitation preventing all 4 presets from working
276
- - **PathHelper Quote Escaping**: Fixed single quote escaping in Unix paths (needed 4 backslashes)
277
- - **Spec Helper Bug**: Changed instance variable to global variable for cross-context access
278
- - **PathHelper Tests**: Made drive letter detection flexible for E: drive compatibility
279
-
280
- #### Testing
281
- - **CLI Tests (97)**: --help, --version, --check-dependencies, --image, --video, --consolidate, --verify
282
- - **GimpProcessor Tests (48)**: Initialization, operations, interpolation, output filtering, script generation
283
- - **Consolidator Tests (33)**: File validation, metadata, column validation, consolidation logic
284
- - **PathHelper Tests (7)**: Quote paths, normalize for Python, native format conversion
285
- - **Coverage**: Increased from 22.52% to 57.09% (+34.57 percentage points)
286
-
287
- Closes #5
288
-
289
- ---
290
-
291
- ## [0.6.2] - 2025-10-22
292
-
293
- ### โœจ Quality Enhancement & Tooling Release
294
-
295
- #### Added
296
- - **Interpolation Options**: 5 interpolation methods for scaling (none, linear, cubic, nohalo, lohalo)
297
- - **Sharpening Support**: Unsharp mask with configurable radius, gain, and threshold
298
- - **`--version` Flag**: Display version, platform, and date information
299
- - **`--check-dependencies` Flag**: Verify all external tools are installed with platform-specific guidance
300
- - **File Extension Validation**: Runtime validation for MP4 (video) and PNG (images)
301
- - **GIMP Investigation Documentation**: Comprehensive documentation of GIMP sharpen attempts and solutions
302
-
303
- #### Changed
304
- - **Automatic Operation Order**: Auto-optimize to remove background before scaling for better quality
305
- - **Sharpening via ImageMagick**: Use ImageMagick instead of GIMP for reliable cross-platform sharpening
306
- - **Alpha Channel Preservation**: Use merge instead of flatten to preserve transparency
307
- - **Conservative Sharpen Defaults**: radius: 2.0, gain: 0.5, threshold: 0.03 to minimize halo artifacts
308
- - **Parameter Terminology**: Changed "amount" to "gain" to match ImageMagick documentation
309
-
310
- #### Fixed
311
- - **Gem Build Error**: Removed .rb extension from `bin/ruby_spriter` executable
312
- - **Clear Error Messages**: File extension validation provides helpful feedback
313
-
314
- #### Documentation
315
- - **README.md**: Added interpolation and sharpening documentation, file format requirements
316
- - **CLAUDE.md**: Updated with new features and validation details
317
- - **GIMP_SHARPEN_INVESTIGATION.md**: Documents 8 failed GIMP attempts and architectural decisions
318
-
319
- ---
320
-
321
- ## [0.6.1] - 2025-10-22
322
-
323
- ### ๐ŸŽ‰ Major Refactoring Release
324
-
325
- #### Added
326
- - **Modular Architecture**: Split monolithic script into organized modules
327
- - **RSpec Testing Framework**: Comprehensive unit test coverage
328
- - **Dependency Checking**: Automatic validation of external tools
329
- - **Better Error Handling**: Custom exception classes
330
- - **Code Documentation**: Inline comments and YARD-compatible docs
331
- - **SimpleCov Integration**: Code coverage reporting
332
- - **RuboCop Support**: Code style enforcement
333
-
334
- #### Changed
335
- - **Project Structure**: Reorganized into `lib/`, `spec/`, and `bin/` directories
336
- - **Class Organization**:
337
- - `Platform` - Platform detection and configuration
338
- - `DependencyChecker` - External tool validation
339
- - `VideoProcessor` - FFmpeg operations
340
- - `GimpProcessor` - GIMP operations
341
- - `MetadataManager` - PNG metadata handling
342
- - `Consolidator` - Spritesheet consolidation
343
- - `Processor` - Main orchestration
344
- - `CLI` - Command-line interface
345
- - Utilities: `PathHelper`, `FileHelper`, `OutputFormatter`
346
-
347
- #### Fixed
348
- - Path handling edge cases on Windows
349
- - Improved error messages with actionable guidance
350
- - Better temp file cleanup
351
-
352
- #### Developer Experience
353
- - Gemfile for dependency management
354
- - RSpec test suite with fixtures
355
- - Comprehensive README with examples
356
- - Troubleshooting guide
357
- - Contributing guidelines
358
-
359
- ---
360
-
361
- ## [0.6.0] - 2024-XX-XX
362
-
363
- ### Added
364
- - Metadata embedding in PNG files
365
- - Spritesheet consolidation feature
366
- - Metadata verification command (`--verify`)
367
- - Debug mode for troubleshooting
368
-
369
- ### Changed
370
- - Improved GIMP script generation
371
- - Better cross-platform path handling
372
-
373
- ---
374
-
375
- ## [0.5.0] - 2024-XX-XX
376
-
377
- ### Added
378
- - Background removal with GIMP
379
- - Fuzzy select and global color select options
380
- - Image scaling support
381
- - Configurable operation order
382
-
383
- ---
384
-
385
- ## [0.4.0] - 2024-XX-XX
386
-
387
- ### Added
388
- - Video to spritesheet conversion
389
- - FFmpeg integration
390
- - Customizable grid layouts
391
-
392
- ---
393
-
394
- ## [0.1.0] - 2024-XX-XX
395
-
396
- ### Added
397
- - Initial release
398
- - Basic video processing
399
- - Cross-platform support
400
-
401
- ---
402
-
403
- [0.6.2]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.1...v0.6.2
404
- [0.6.1]: https://github.com/scooter-indie/ruby-spriter/compare/v0.6.0...v0.6.1
405
- [0.6.0]: https://github.com/scooter-indie/ruby-spriter/releases/tag/v0.6.0
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