class Motion::Screenspecs::ImageDiff

Public Instance Methods

percentage(image_a, image_b, failure_path) click to toggle source

via jeffkreeftmeijer.com/2011/comparing-images-and-creating-image-diffs/

# File lib/motion-screenspecs.rb, line 139
def percentage(image_a, image_b, failure_path)
  images = [
    ChunkyPNG::Image.from_file(image_a),
    ChunkyPNG::Image.from_file(image_b)
  ]

  output = ChunkyPNG::Image.new(images.first.width, images.last.height, WHITE)

  diff = []

  images.first.height.times do |y|
    images.first.row(y).each_with_index do |pixel, x|
      unless pixel == images.last[x,y]
        score = Math.sqrt(
          (r(images.last[x,y]) - r(pixel)) ** 2 +
          (g(images.last[x,y]) - g(pixel)) ** 2 +
          (b(images.last[x,y]) - b(pixel)) ** 2
        ) / Math.sqrt(MAX ** 2 * 3)

        output[x,y] = rgb(
          r(pixel) + r(images.last[x,y]) - 2 * [r(pixel), r(images.last[x,y])].min,
          g(pixel) + g(images.last[x,y]) - 2 * [g(pixel), g(images.last[x,y])].min,
          b(pixel) + b(images.last[x,y]) - 2 * [b(pixel), b(images.last[x,y])].min
        )
        diff << score
      end
    end
  end

  summed = diff.inject {|sum, value| sum + value}
  if summed
    percent = (summed / images.first.pixels.length) * 100
  else
    percent = 0
  end
  if percent >= Motion::Screenspecs.tolerance
    output.save(failure_path)
    Motion::Screenspecs.failures << failure_path
  end
  percent
end