require 'chunky_png' class ChunkyPNG::Image def neighbors(x,y) [[x, y-1], [x+1, y], [x, y+1], [x-1, y]].select do |xy| include_xy?(*xy) end end end def label_recursively(image, areas, label, x, y) image[x,y] = label (areas[label] ||= []) << [x,y] image.neighbors(x,y).each do |xy| if image[*xy] == -1 areas[label] << xy label_recursively(image, areas, label, *xy) end end end image = ChunkyPNG::Image.from_file('bassie.png') working_image = image.dup working_image.pixels.map! do |pixel| redness = ChunkyPNG::Color.r(pixel) - (ChunkyPNG::Color.g(pixel) + ChunkyPNG::Color.b(pixel)) redness > 100 ? -1 : 0 end areas, label = {}, 0 working_image.height.times do |y| working_image.row(y).each_with_index do |pixel, x| label_recursively(working_image, areas, label += 1, x, y) if pixel == -1 end end area = areas.values.max { |result, area| result.length <=> area.length } x, y = area.map{ |xy| xy[0] }, area.map{ |xy| xy[1] } image.rect(x.min, y.min, x.max, y.max, ChunkyPNG::Color.rgb(0,255,0)) image.save('bassie_detected.png')