image_compare 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +2 -1
- data/README.md +41 -27
- data/lib/image_compare/color_methods.rb +2 -2
- data/lib/image_compare/image.rb +1 -1
- data/lib/image_compare/matcher.rb +14 -12
- data/lib/image_compare/modes/base.rb +1 -1
- data/lib/image_compare/modes/color.rb +6 -6
- data/lib/image_compare/modes/delta.rb +1 -1
- data/lib/image_compare/modes/grayscale.rb +1 -1
- data/lib/image_compare/modes/rgb.rb +1 -1
- data/lib/image_compare/modes.rb +4 -4
- data/lib/image_compare/rectangle.rb +2 -2
- data/lib/image_compare/version.rb +1 -1
- data/lib/image_compare.rb +3 -3
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fddeaa634a928ccfeed4d71797a78d9f8201bc5df036275181ac10addd6a315c
|
4
|
+
data.tar.gz: 43128e9a8fb1c95d246808bdd746ab8023ee984a754e3690b411eb17768399e1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dbc5a9c8c6a9b4f34ea24d9259cc0913aa12672dfa10e279134a477a0331b079bd51c1355e1d09b3b0e6a4008ee19c8feda0baa04e3465899b6e001453c15533
|
7
|
+
data.tar.gz: e5cd324880f6f97459eb0b290a3764934f750852d234f775d32ccfbe060cd73152307db6d175f3c120592686e74e9c0509308546f68534c7d741ded33ee99e16
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
# Change log
|
2
2
|
|
3
3
|
## main
|
4
|
-
- Add Color mode to generate "normal" diff images ([@gsguma][], [@cristianofmc][])
|
4
|
+
- v1.0.0: Add Color mode to generate "normal" diff images ([@gsguma][], [@cristianofmc][])
|
5
|
+
- v1.0.1: Fix all code smells and integration tests ([@gsguma][])
|
5
6
|
|
6
7
|
[@gsguma]: https://github.com/gsguma
|
7
8
|
[@cristianofmc]: https://github.com/cristianofmc
|
data/README.md
CHANGED
@@ -8,10 +8,10 @@ This is an utility library for image regression testing.
|
|
8
8
|
|
9
9
|
## Installation
|
10
10
|
|
11
|
-
Add this line to your application
|
11
|
+
Add this line to your application"s Gemfile:
|
12
12
|
|
13
13
|
```ruby
|
14
|
-
gem
|
14
|
+
gem "image_compare"
|
15
15
|
```
|
16
16
|
|
17
17
|
Or adding to your project:
|
@@ -20,7 +20,7 @@ Or adding to your project:
|
|
20
20
|
# my-cool-gem.gemspec
|
21
21
|
Gem::Specification.new do |spec|
|
22
22
|
# ...
|
23
|
-
spec.add_dependency
|
23
|
+
spec.add_dependency "image_compare"
|
24
24
|
# ...
|
25
25
|
end
|
26
26
|
```
|
@@ -33,8 +33,8 @@ ImageCompare supports different ways (_modes_) of comparing images.
|
|
33
33
|
|
34
34
|
Source images used in examples:
|
35
35
|
|
36
|
-
<img alt=
|
37
|
-
<img alt=
|
36
|
+
<img alt="a.png" src="spec/fixtures/a.png" />
|
37
|
+
<img alt="b.png" src="spec/fixtures/b.png" />
|
38
38
|
|
39
39
|
### Color
|
40
40
|
|
@@ -42,14 +42,14 @@ Compare pixels, resulting score is a ratio of unequal pixels (with respect to pr
|
|
42
42
|
|
43
43
|
Resulting diff contains version of the first image with different pixels highlighted in red and red bounding box.
|
44
44
|
|
45
|
-
<img alt=
|
45
|
+
<img alt="color_diff" src="spec/fixtures/color_diff.png" />
|
46
46
|
|
47
47
|
### Base (RGB) mode
|
48
48
|
|
49
49
|
Compare pixels by values, resulting score is a ratio of unequal pixels.
|
50
50
|
Resulting diff represents per-channel difference.
|
51
51
|
|
52
|
-
<img alt=
|
52
|
+
<img alt="rgb_diff.png" src="spec/fixtures/rgb_diff.png" width="480" />
|
53
53
|
|
54
54
|
### Grayscale mode
|
55
55
|
|
@@ -57,14 +57,14 @@ Compare pixels as grayscale (by brightness and alpha), resulting score is a rati
|
|
57
57
|
|
58
58
|
Resulting diff contains grayscale version of the first image with different pixels highlighted in red and red bounding box.
|
59
59
|
|
60
|
-
<img alt=
|
60
|
+
<img alt="grayscale_diff.png" src="spec/fixtures/grayscale_diff.png" width="480" />
|
61
61
|
|
62
62
|
### Delta
|
63
63
|
|
64
64
|
Compare pixels using [Delta E](https://en.wikipedia.org/wiki/Color_difference) distance.
|
65
65
|
Resulting diff contains grayscale version of the first image with different pixels highlighted in red (with respect to diff score).
|
66
66
|
|
67
|
-
<img alt=
|
67
|
+
<img alt="delta_diff.png" src="spec/fixtures/delta_diff.png" width="480" />
|
68
68
|
|
69
69
|
## Usage
|
70
70
|
|
@@ -91,7 +91,7 @@ cmp.lower_threshold #=> 0.01
|
|
91
91
|
cmp = ImageCompare::Matcher.new mode: :grayscale, tolerance: 0
|
92
92
|
cmp.mode #=> ImageCompare::Modes::Grayscale
|
93
93
|
|
94
|
-
res = cmp.compare(
|
94
|
+
res = cmp.compare("path/image1.png", "path/image2.png")
|
95
95
|
res #=> ImageCompare::Result
|
96
96
|
res.match? #=> true
|
97
97
|
res.score #=> 0.0
|
@@ -101,44 +101,44 @@ res.difference_image #=> ImageCompare::Image
|
|
101
101
|
res.difference_image.save(result)
|
102
102
|
|
103
103
|
# without explicit matcher
|
104
|
-
res = ImageCompare.compare(
|
104
|
+
res = ImageCompare.compare("path/image1.png", "path/image2.png", options)
|
105
105
|
res.match? #=> true
|
106
106
|
res.score #=> 0.0
|
107
107
|
|
108
108
|
# equals to
|
109
|
-
res = ImageCompare::Matcher.new(options).compare(
|
109
|
+
res = ImageCompare::Matcher.new(options).compare("my_images_path/image1.png", "my_images_path/image2.png")
|
110
110
|
res.match? #=> true
|
111
111
|
res.score #=> 0.0
|
112
112
|
```
|
113
113
|
|
114
114
|
## Excluding rectangle
|
115
115
|
|
116
|
-
<img alt=
|
117
|
-
<img alt=
|
116
|
+
<img alt="a.png" src="spec/fixtures/a.png" />
|
117
|
+
<img alt="a1.png" src="spec/fixtures/a1.png" />
|
118
118
|
|
119
119
|
You can exclude rectangle from comparing by passing `:exclude_rect` to `compare`.
|
120
120
|
E.g., if `path_1` and `path_2` contain images above
|
121
121
|
```ruby
|
122
|
-
ImageCompare.compare(
|
122
|
+
ImageCompare.compare("path/image1.png", "path/image2.png", exclude_rect: [200, 150, 275, 200]).match? # => true
|
123
123
|
|
124
124
|
# or
|
125
125
|
|
126
126
|
cmp = ImageCompare::Matcher.new exclude_rect: [200, 150, 275, 200]
|
127
|
-
res = cmp.compare(
|
127
|
+
res = cmp.compare("path/image1.png", "path/image2.png")
|
128
128
|
res #=> ImageCompare::Result
|
129
129
|
res.match? #=> true
|
130
130
|
res.score #=> 0.0
|
131
131
|
|
132
132
|
# Return diff image object
|
133
133
|
res.difference_image #=> ImageCompare::Image
|
134
|
-
res.difference_image.save(
|
134
|
+
res.difference_image.save("path/diff.png")
|
135
135
|
```
|
136
136
|
`[200, 150, 275, 200]` is array of two vertices of rectangle -- (200, 150) is left-top vertex and (275, 200) is right-bottom.
|
137
137
|
|
138
138
|
### Cucumber + Capybara example
|
139
139
|
`support/env.rb`:
|
140
140
|
```ruby
|
141
|
-
require
|
141
|
+
require "image_compare"
|
142
142
|
```
|
143
143
|
|
144
144
|
`support/capybara_extensions.rb`:
|
@@ -147,15 +147,15 @@ require 'image_compare'
|
|
147
147
|
|
148
148
|
Capybara::Node::Element.class_eval do
|
149
149
|
def rect_area
|
150
|
-
rect_area = self.evaluate_script(
|
150
|
+
rect_area = self.evaluate_script("this.getBoundingClientRect()") # rubocop:disable Style/RedundantSelf
|
151
151
|
|
152
152
|
[
|
153
|
-
rect_area[
|
154
|
-
rect_area[
|
155
|
-
rect_area[
|
156
|
-
rect_area[
|
153
|
+
rect_area["left"].to_f.round,
|
154
|
+
rect_area["top"].to_f.round,
|
155
|
+
rect_area["right"].to_f.round,
|
156
|
+
rect_area["bottom"].to_f.round
|
157
157
|
]
|
158
|
-
rescue StandardError => e
|
158
|
+
rescue StandardError => e # rubocop:disable Style/RescueStandardError
|
159
159
|
raise "Error getting element rect area: #{e.inspect}!"
|
160
160
|
end
|
161
161
|
end
|
@@ -163,11 +163,11 @@ end
|
|
163
163
|
|
164
164
|
`steps/my_step.rb`:
|
165
165
|
```ruby
|
166
|
-
my_element = page.find(
|
166
|
+
my_element = page.find("#my_element").rect_area
|
167
167
|
|
168
168
|
cmp = ImageCompare::Matcher.new exclude_rect: my_element.rect_area
|
169
|
-
res = cmp.compare(
|
170
|
-
res.difference_image.save(
|
169
|
+
res = cmp.compare("path/image1.png", "path/image2.png")
|
170
|
+
res.difference_image.save("path/diff.png")
|
171
171
|
|
172
172
|
expect(res.match?).to eq(true)
|
173
173
|
```
|
@@ -180,6 +180,20 @@ You can set bounds of comparing by passing `:include_rect` to `compare` with arr
|
|
180
180
|
|
181
181
|
Bug reports and pull requests are welcome on GitHub at https://github.com/instantink/image_compare.
|
182
182
|
|
183
|
+
### Running tests and code inspections
|
184
|
+
|
185
|
+
- `rake rubocop`
|
186
|
+
- `rake rubocop:md`
|
187
|
+
- `rake spec`
|
188
|
+
- `ruby examples/performance.rb` Create the gemfile.local file with the content below to run the performance tests:
|
189
|
+
```ruby
|
190
|
+
# frozen_string_literal: true
|
191
|
+
|
192
|
+
source "https://rubygems.org"
|
193
|
+
gem "benchmark-ips", "~> 2.7", ">= 2.7.2"
|
194
|
+
```
|
195
|
+
|
196
|
+
|
183
197
|
## License
|
184
198
|
|
185
199
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
data/lib/image_compare/image.rb
CHANGED
@@ -2,15 +2,15 @@
|
|
2
2
|
|
3
3
|
module ImageCompare
|
4
4
|
class Matcher
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
5
|
+
require "image_compare/image"
|
6
|
+
require "image_compare/result"
|
7
|
+
require "image_compare/modes"
|
8
8
|
|
9
9
|
MODES = {
|
10
|
-
rgb:
|
11
|
-
delta:
|
12
|
-
grayscale:
|
13
|
-
color:
|
10
|
+
rgb: "RGB",
|
11
|
+
delta: "Delta",
|
12
|
+
grayscale: "Grayscale",
|
13
|
+
color: "Color"
|
14
14
|
}.freeze
|
15
15
|
|
16
16
|
attr_reader :mode
|
@@ -26,25 +26,27 @@ module ImageCompare
|
|
26
26
|
b = Image.from_file(b) unless b.is_a?(Image)
|
27
27
|
|
28
28
|
unless a.sizes_match?(b)
|
29
|
-
raise
|
30
|
-
|
29
|
+
raise(
|
30
|
+
SizesMismatchError,
|
31
|
+
"Size mismatch: first image size: #{a.width}x#{a.height}, second image size: #{b.width}x#{b.height}"
|
32
|
+
)
|
31
33
|
end
|
32
34
|
|
33
35
|
image_area = Rectangle.new(0, 0, a.width - 1, a.height - 1)
|
34
36
|
|
35
37
|
unless mode.exclude_rect.nil?
|
36
38
|
unless image_area.contains?(mode.exclude_rect)
|
37
|
-
raise ArgumentError,
|
39
|
+
raise ArgumentError, "Bounds must be in image"
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
41
43
|
unless mode.include_rect.nil?
|
42
44
|
unless image_area.contains?(mode.include_rect)
|
43
|
-
raise ArgumentError,
|
45
|
+
raise ArgumentError, "Bounds must be in image"
|
44
46
|
end
|
45
47
|
unless mode.exclude_rect.nil?
|
46
48
|
unless mode.include_rect.contains?(mode.exclude_rect)
|
47
|
-
raise ArgumentError,
|
49
|
+
raise ArgumentError, "Included area must contain excluded"
|
48
50
|
end
|
49
51
|
end
|
50
52
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module ImageCompare
|
4
4
|
module Modes
|
5
|
-
require
|
5
|
+
require "image_compare/modes/base"
|
6
6
|
|
7
7
|
class Color < Base
|
8
8
|
include ColorMethods
|
@@ -33,20 +33,20 @@ module ImageCompare
|
|
33
33
|
left: bounds.bounds[0],
|
34
34
|
top: bounds.bounds[1],
|
35
35
|
right: bounds.bounds[2],
|
36
|
-
bot:
|
36
|
+
bot: bounds.bounds[3]
|
37
37
|
}
|
38
38
|
|
39
39
|
exclude_area = {
|
40
40
|
left: exclude_rect.bounds[0],
|
41
41
|
top: exclude_rect.bounds[1],
|
42
42
|
right: exclude_rect.bounds[2],
|
43
|
-
bot:
|
43
|
+
bot: exclude_rect.bounds[3]
|
44
44
|
}
|
45
45
|
|
46
46
|
diff_area[:left] <= exclude_area[:left] &&
|
47
|
-
|
48
|
-
|
49
|
-
|
47
|
+
diff_area[:top] <= exclude_area[:top] &&
|
48
|
+
diff_area[:right] >= exclude_area[:right] &&
|
49
|
+
diff_area[:bot] >= exclude_area[:bot]
|
50
50
|
end
|
51
51
|
|
52
52
|
def pixels_equal?(a, b)
|
data/lib/image_compare/modes.rb
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
|
3
3
|
module ImageCompare
|
4
4
|
module Modes
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
5
|
+
require "image_compare/modes/color"
|
6
|
+
require "image_compare/modes/delta"
|
7
|
+
require "image_compare/modes/grayscale"
|
8
|
+
require "image_compare/modes/rgb"
|
9
9
|
end
|
10
10
|
end
|
@@ -28,8 +28,8 @@ module ImageCompare
|
|
28
28
|
|
29
29
|
def contains_point?(x, y)
|
30
30
|
(x >= left && y >= top && x <= right && y <= bot) ||
|
31
|
-
|
32
|
-
|
31
|
+
(x <= right && y <= top && x >= left && y >= bot) ||
|
32
|
+
(x.between?(right, left) && y.between?(bot, top))
|
33
33
|
end
|
34
34
|
end
|
35
35
|
end
|
data/lib/image_compare.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
3
|
+
require "image_compare/version"
|
4
4
|
|
5
5
|
module ImageCompare
|
6
6
|
class SizesMismatchError < StandardError
|
7
7
|
end
|
8
8
|
|
9
|
-
require
|
10
|
-
require
|
9
|
+
require "image_compare/color_methods"
|
10
|
+
require "image_compare/matcher"
|
11
11
|
|
12
12
|
def self.compare(path_a, path_b, **options)
|
13
13
|
Matcher.new(**options).compare(path_a, path_b)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: image_compare
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- cristianofmc
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-03-
|
12
|
+
date: 2023-03-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: chunky_png
|