Converting ASCII to an image
class Array
  def chunk(chunk_size)
    self.each_with_index.with_object(Array.new(size / chunk_size) { [] }) do |(elt, ind), result|
      result[ind / chunk_size] &lt;&lt; elt
    end
  end
end



You reinvented Enumerable#each_slice! It returns an enumerator, which is fine for your code. Simply write ARGV.each_slice(2).map do |char, color| instead of ARGV.chunk(2).map.


ARGV.length % 2 == 1



Change to ARGV.length.odd?.


'Run with -h to see usage.'



Doesn't work.


colors = Hash[
    ARGV.each_slice(2).map do |char, color|
      color = ChunkyPNG::Color.from_hex(color)
      [char, color]
    end
]



I'd use to_h instead of Hash[] and inline color, to make the code shorter:

colors = ARGV.each_slice(2).map do |char, color|
  [char, ChunkyPNG::Color.from_hex(color)]
end.to_h



text &lt;&lt; $_.chomp.chars until $stdin.gets.nil?



Instead of creating many arrays of characters, simply store the strings. Remove the call to .chars and iterate over a string using row.each_char.with_index. This makes the code a little faster.


raise ArgumentError, "No valid color provided for `#{char}`" if colors[char].nil?
image[x, y] = colors[char]



ChuckyPNG already throws an ArgumentError if the color is nil. You can remove your check for this, which may improve performance. (If you need to catch this error, you can wrap the loop with a begin-rescue block)