Class: Capybara::Screenshot::Diff::ImageCompare

Inherits:
Object
  • Object
show all
Includes:
ChunkyPNG::Color
Defined in:
lib/capybara/screenshot/diff/image_compare.rb

Overview

Compare two images and determine if they are equal, different, or within som comparison range considering color values and difference area size.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(new_file_name, old_file_name = nil, dimensions: nil, color_distance_limit: nil, area_size_limit: nil, shift_distance_limit: nil, skip_area: nil) ⇒ ImageCompare

Returns a new instance of ImageCompare.



15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 15

def initialize(new_file_name, old_file_name = nil, dimensions: nil, color_distance_limit: nil,
    area_size_limit: nil, shift_distance_limit: nil, skip_area: nil)
  @new_file_name = new_file_name
  @color_distance_limit = color_distance_limit
  @area_size_limit = area_size_limit
  @shift_distance_limit = shift_distance_limit
  @dimensions = dimensions
  @skip_area = skip_area
  @old_file_name = old_file_name || "#{new_file_name}~"
  @annotated_old_file_name = "#{new_file_name.chomp('.png')}_0.png~"
  @annotated_new_file_name = "#{new_file_name.chomp('.png')}_1.png~"
  reset
end

Instance Attribute Details

#annotated_new_file_nameObject (readonly)

Returns the value of attribute annotated_new_file_name.



13
14
15
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13

def annotated_new_file_name
  @annotated_new_file_name
end

#annotated_old_file_nameObject (readonly)

Returns the value of attribute annotated_old_file_name.



13
14
15
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13

def annotated_old_file_name
  @annotated_old_file_name
end

#new_file_nameObject (readonly)

Returns the value of attribute new_file_name.



13
14
15
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13

def new_file_name
  @new_file_name
end

#old_file_nameObject (readonly)

Returns the value of attribute old_file_name.



13
14
15
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 13

def old_file_name
  @old_file_name
end

Instance Method Details

#different?Boolean

Compare the two images referenced by this object, and return ‘true` if they are different, and `false` if they are the same. Return `nil` if the old file does not exist or if the image dimensions do not match.

Returns:

  • (Boolean)


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
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 70

def different?
  return nil unless old_file_exists?

  old_file, new_file = load_image_files(@old_file_name, @new_file_name)

  return not_different if old_file == new_file

  images = load_images(old_file, new_file)

  crop_images(images, @dimensions) if @dimensions

  old_img = images.first
  new_img = images.last

  if sizes_changed?(old_img, new_img)
    save_images(@annotated_new_file_name, new_img, @annotated_old_file_name, old_img)
    @left = 0
    @top = 0
    @right = old_img.dimension.width - 1
    @bottom = old_img.dimension.height - 1
    return true
  end

  return not_different if old_img.pixels == new_img.pixels

  @left, @top, @right, @bottom = find_diff_rectangle(old_img, new_img)

  return not_different if @top.nil?
  return not_different if @area_size_limit && size <= @area_size_limit

  annotated_old_img, annotated_new_img = draw_rectangles(images, @bottom, @left, @right, @top)

  save_images(@annotated_new_file_name, annotated_new_img,
      @annotated_old_file_name, annotated_old_img)
  true
end

#dimensionsObject



119
120
121
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 119

def dimensions
  [@left, @top, @right, @bottom]
end

#max_color_distanceObject



127
128
129
130
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 127

def max_color_distance
  calculate_metrics unless @max_color_distance
  @max_color_distance
end

#max_shift_distanceObject



132
133
134
135
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 132

def max_shift_distance
  calculate_metrics unless @max_shift_distance || !@shift_distance_limit
  @max_shift_distance
end

#new_file_sizeObject



115
116
117
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 115

def new_file_size
  File.size(@new_file_name)
end

#old_file_exists?Boolean

Returns:

  • (Boolean)


107
108
109
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 107

def old_file_exists?
  @old_file_name && File.exist?(@old_file_name)
end

#old_file_sizeObject



111
112
113
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 111

def old_file_size
  @old_file_size ||= old_file_exists? && File.size(@old_file_name)
end

#quick_equal?Boolean

Compare the two image files and return ‘true` or `false` as quickly as possible. Return falsish if the old file does not exist or the image dimensions do not match.

Returns:

  • (Boolean)


39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 39

def quick_equal?
  return nil unless old_file_exists?
  return true if new_file_size == old_file_size

  old_bytes, new_bytes = load_image_files(@old_file_name, @new_file_name)
  return true if old_bytes == new_bytes

  images = load_images(old_bytes, new_bytes)
  old_bytes = new_bytes = nil # rubocop: disable Lint/UselessAssignment
  crop_images(images, @dimensions) if @dimensions

  return false if sizes_changed?(*images)
  return true if images.first.pixels == images.last.pixels

  return false unless @color_distance_limit || @shift_distance_limit

  @left, @top, @right, @bottom = find_top(*images)

  return true if @top.nil?

  if @area_size_limit
    @left, @top, @right, @bottom = find_diff_rectangle(*images)
    return true if size <= @area_size_limit
  end

  false
end

#resetObject

Resets the calculated data about the comparison with regard to the “new_image”. Data about the original image is kept.



31
32
33
34
35
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 31

def reset
  @max_color_distance = @color_distance_limit ? 0 : nil
  @max_shift_distance = @shift_distance_limit ? 0 : nil
  @left = @top = @right = @bottom = nil
end

#sizeObject



123
124
125
# File 'lib/capybara/screenshot/diff/image_compare.rb', line 123

def size
  (@right - @left + 1) * (@bottom - @top + 1)
end