Method: Pixelart::Image.parse

Defined in:
lib/pixelart/image.rb

.parse(pixels, colors:, background: Color::TRANSPARENT, chars: CHARS, width: nil, height: nil) ⇒ Object

todo/check: support default chars encoding auto-of-the-box always

or require user-defined chars to be passed in - why? why not?


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
# File 'lib/pixelart/image.rb', line 54

def self.parse( pixels, colors:,
                        background: Color::TRANSPARENT,
                        chars: CHARS,
                        width: nil,
                        height: nil )
  has_keys  = colors.is_a?(Hash)   ## check if passed-in user-defined keys (via hash table)?

  colors = parse_colors( colors )

  ## note: for now use strict parser only 
  ##        if colors with hash map / keys defined
  ##         will raise error / exit if unknown token found!!!
  ##   AND  pixels is a single txt / text string to parse (NOT array of string lines) 
  ##
  #
  #  note default for now is:
  #      1) tokens separated by space if not strict (e.g. has no color keys AND not array of strings)
  #      2) every char is a token  if array of strings
  pixels =  if has_keys && pixels.is_a?( String )
              keys = colors.keys.map { |key| key.to_s }
              ## todo/fix: - sort by lenght first; 
              ##           - escape for rx chars!!
              rx = /#{keys.join('|')}/
              parse_pixels_strict( rx, pixels )  
            else
              parse_pixels( pixels )
            end 

  ## note: for now only use (require) width for flattened/streamed text input
  if width   
     ## always flattern first - why? why not?
     ##   allow multi-line text inputs - allow/support why? why not?
     pixels = pixels.flatten.each_slice( width ).to_a
  else
    ## find row with max width  
    width  = pixels.reduce(1) {|width,row| row.size > width ? row.size : width }
    height = pixels.size
  end

   background = Color.parse( background )   unless background.is_a?( Integer )

  img = new( width, height )

  pixels.each_with_index do |row,y|
    row.each_with_index do |color,x|
      pixel = if has_keys     ## if passed-in user-defined keys check only the user-defined keys
                colors[color]
              else
                ## try map ascii art char (.@xo etc.) to color index (0,1,2)
                ##   if no match found - fallback on assuming draw by number (0 1 2 etc.) encoding
                pos = chars.index( color )
                if pos
                  colors[ pos.to_s ]
                else ## assume nil (not found)
                  colors[ color ]
                end
              end


      img[x,y] = if background && background != Color::TRANSPARENT &&
                                  pixel == Color::TRANSPARENT
                   background   ## note: auto-fill transparent with background color
                 else
                   pixel
                 end
    end # each row
  end # each data

  img
end