module PNG_Comparison::Comparator
Public Class Methods
compare_images(img1:, img2:, diff_file:, threshold:)
click to toggle source
# File lib/png_comparison.rb, line 51 def self.compare_images(img1:, img2:, diff_file:, threshold:) read_start = Time.now puts 'Reading images...' if !(img1.is_a?(ChunkyPNG::Image) && img2.is_a?(ChunkyPNG::Image) && diff_file.is_a?(ChunkyPNG::Image)) image1 = ChunkyPNG::Image.from_file(img1) image2 = ChunkyPNG::Image.from_file(img2) output_file = ChunkyPNG::Image.new(image1.width, image1.height, WHITE) else image1 = img1 image2 = img2 output_file = diff_file diff_file = 'diff_file' end read_end = Time.now puts "Finished reading images in #{read_end - read_start} seconds" image_length = image1.pixels.length diff = [] perceptual_diff = 0 if !image1.eql?(image2) && (image1.dimension == image2.dimension) diff, output_file = img_diff(image1: image1, image2: image2, output_file: output_file) perceptual_diff = (diff.inject { |sum, value| sum + value } / image_length) * 100 else if image1.dimension != image2.dimension puts 'Images have different dimensions!' return false end end absolute_change = show_statistics(image_length, diff, perceptual_diff, threshold) # you can use here "if absolute_change > perceptual_diff" if absolute_change > threshold puts 'Images are not identical.' output_file.save(diff_file) return false else puts 'Images are identical or differ within threshold.' output_file.save(diff_file) unless image1.eql?(image2) return true end end
Private Class Methods
img_diff(image1:, image2:, output_file:)
click to toggle source
Main color difference algorithm, kind of CIE76 metric
# File lib/png_comparison.rb, line 97 def self.img_diff(image1:, image2:, output_file:) diff = [] image1.height.times do |y| image1.row(y).each_with_index do |pixel, x| next if pixel == image2[x, y] score = Math.sqrt((r(image2[x, y]) - r(pixel))**2 + (g(image2[x, y]) - g(pixel))**2 + (b(image2[x, y]) - b(pixel))**2) / Math.sqrt(MAX**2 * 3) output_file[x, y] = grayscale(MAX - (score * MAX).round) diff << score end end [diff, output_file] end
show_statistics(image_length, diff, perceptual_diff, threshold)
click to toggle source
# File lib/png_comparison.rb, line 111 def self.show_statistics(image_length, diff, perceptual_diff, threshold) total_pixels = image_length non_matching_pixels = diff.length absolute_change = (non_matching_pixels.to_f / total_pixels.to_f) * 100 puts "Pixels processed: #{total_pixels}" puts "Differing Pixels: #{non_matching_pixels}" puts "Perceptual image difference: #{perceptual_diff} (%)" puts "Absolute image difference: #{absolute_change} (%), threshold is #{threshold}(%)" absolute_change end