Class: RubySpriter::GhostEdgeCleaner
- Inherits:
-
Object
- Object
- RubySpriter::GhostEdgeCleaner
- Defined in:
- lib/ruby_spriter/ghost_edge_cleaner.rb
Overview
GhostEdgeCleaner removes semi-transparent “ghost” pixels around sprite edges using multi-pass alpha channel cleanup while preserving anti-aliasing
Constant Summary collapse
- MAX_PASSES =
Maximum cleanup passes to prevent infinite loops
3
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#ghost_pixels_detected ⇒ Object
readonly
Returns the value of attribute ghost_pixels_detected.
-
#input_image ⇒ Object
readonly
Returns the value of attribute input_image.
-
#output_image ⇒ Object
readonly
Returns the value of attribute output_image.
-
#passes_performed ⇒ Object
readonly
Returns the value of attribute passes_performed.
-
#processing_time ⇒ Object
readonly
Returns the value of attribute processing_time.
Instance Method Summary collapse
-
#clean_edges ⇒ Object
Clean edges by removing low-alpha pixels.
-
#detect_ghost_pixels ⇒ Object
Detect pixels with alpha below threshold.
-
#initialize(input_image, output_image, config) ⇒ GhostEdgeCleaner
constructor
A new instance of GhostEdgeCleaner.
-
#multi_pass_cleanup ⇒ Object
Perform multiple cleanup passes.
-
#process ⇒ Object
Main processing method.
-
#report ⇒ Object
Generate processing report.
Constructor Details
#initialize(input_image, output_image, config) ⇒ GhostEdgeCleaner
Returns a new instance of GhostEdgeCleaner.
15 16 17 18 19 20 21 22 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 15 def initialize(input_image, output_image, config) @input_image = input_image @output_image = output_image @config = config @ghost_pixels_detected = 0 @passes_performed = 0 @processing_time = 0 end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
10 11 12 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 10 def config @config end |
#ghost_pixels_detected ⇒ Object (readonly)
Returns the value of attribute ghost_pixels_detected.
11 12 13 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 11 def ghost_pixels_detected @ghost_pixels_detected end |
#input_image ⇒ Object (readonly)
Returns the value of attribute input_image.
10 11 12 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 10 def input_image @input_image end |
#output_image ⇒ Object (readonly)
Returns the value of attribute output_image.
10 11 12 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 10 def output_image @output_image end |
#passes_performed ⇒ Object (readonly)
Returns the value of attribute passes_performed.
11 12 13 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 11 def passes_performed @passes_performed end |
#processing_time ⇒ Object (readonly)
Returns the value of attribute processing_time.
11 12 13 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 11 def processing_time @processing_time end |
Instance Method Details
#clean_edges ⇒ Object
Clean edges by removing low-alpha pixels
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 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 74 def clean_edges threshold = @config.ghost_threshold # Use ImageMagick to selectively remove pixels below alpha threshold # This preserves RGB data and anti-aliasing for pixels above threshold threshold_fraction = threshold / 255.0 # Use direct -fx operation on alpha channel with explicit RGB preservation # Use png:color-type=6 to force RGBA output (handles grayscale inputs) # Use 'u' to refer to current channel value in -channel context convert_cmd = Platform.imagemagick_convert_cmd cmd = "#{convert_cmd} #{Utils::PathHelper.quote_path(@output_image)} " \ "-define png:color-type=6 " \ "-alpha set " \ "-channel A " \ "-fx \"u < #{threshold_fraction} ? 0 : u\" " \ "+channel " \ "#{Utils::PathHelper.quote_path(@output_image)}" stdout, stderr, status = Open3.capture3(cmd) unless status.success? warn "Failed to clean edges: #{stderr}" return false end true end |
#detect_ghost_pixels ⇒ Object
Detect pixels with alpha below threshold
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 49 def detect_ghost_pixels threshold = @config.ghost_threshold # Use ImageMagick to count pixels with alpha below threshold # Alpha values are 0-255, threshold is 0-255 threshold_fraction = threshold / 255.0 convert_cmd = Platform.imagemagick_convert_cmd cmd = "#{convert_cmd} #{Utils::PathHelper.quote_path(@input_image)} " \ "-channel A " \ "-separate " \ "-threshold #{(threshold_fraction * 100).to_i}% " \ "-format '%[fx:w*h*(1-mean)]' " \ "info:" stdout, stderr, status = Open3.capture3(cmd) if status.success? stdout.strip.gsub("'", '').to_f.to_i else 0 end end |
#multi_pass_cleanup ⇒ Object
Perform multiple cleanup passes
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 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 104 def multi_pass_cleanup passes = 0 previous_ghost_count = @ghost_pixels_detected MAX_PASSES.times do passes += 1 # Perform cleanup pass clean_edges # Check if we still have ghost pixels current_ghost_count = detect_ghost_pixels_from_file(@output_image) # Stop if no improvement or no ghost pixels remain break if current_ghost_count == 0 break if current_ghost_count >= previous_ghost_count previous_ghost_count = current_ghost_count end # Update instance variable for reporting @passes_performed = passes passes end |
#process ⇒ Object
Main processing method
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 25 def process start_time = Time.now # Copy input to output as starting point FileUtils.cp(@input_image, @output_image) # Detect ghost pixels before cleanup @ghost_pixels_detected = detect_ghost_pixels # Perform multi-pass cleanup if multi_pass enabled if @config.multi_pass @passes_performed = multi_pass_cleanup else # Single pass cleanup clean_edges @passes_performed = 1 end @processing_time = Time.now - start_time true end |
#report ⇒ Object
Generate processing report
131 132 133 134 135 136 137 138 139 |
# File 'lib/ruby_spriter/ghost_edge_cleaner.rb', line 131 def report { ghost_pixels_detected: @ghost_pixels_detected, threshold_used: @config.ghost_threshold, passes_performed: @passes_performed, processing_time: @processing_time.round(3), max_passes: MAX_PASSES } end |