png_comparison 1.0.8
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 +7 -0
- data/Gemfile +11 -0
- data/README +2 -0
- data/Rakefile +13 -0
- data/cli_run.rb +41 -0
- data/lib/png_comparison.rb +141 -0
- data/png_comparison.gemspec +19 -0
- data/sample_images/diff_file.png +0 -0
- data/sample_images/sample1.png +0 -0
- data/sample_images/sample2.png +0 -0
- data/spec/spec_helper.rb +96 -0
- data/spec/test_image_comparison_spec.rb +167 -0
- metadata +100 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: dff43c3ee23e0d48544dec3c6c4b36d4f76ccfe1
|
4
|
+
data.tar.gz: 581a32c8b258a0779b759516b8089241027ae325
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: bd6b528120bd8ab6cc7a7c96025ddc40854955c74da7df63e810005ee80aaa0584150500f8d61a41742f113c33279443d2ed5bf04db2e7fee2bd406a54a2890b
|
7
|
+
data.tar.gz: ada107fa11d843101bc57a4f196b8d3443f8661d8ee45df52531d3464414c95150b498aa5f5114984ef7087b98e4938c66b303d9a006e68ae4d6097cc0aa9a39
|
data/Gemfile
ADDED
data/README
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rspec/core/rake_task'
|
2
|
+
|
3
|
+
desc 'This task runs all the rspec tests'
|
4
|
+
task :unit_test do
|
5
|
+
spec = RSpec::Core::RakeTask.new(:spec)
|
6
|
+
spec.run_task('rspec')
|
7
|
+
end
|
8
|
+
|
9
|
+
task :sample_run do
|
10
|
+
io = `ruby cli_run.rb --file1 ./sample_images/sample1.png --file2 ./sample_images/sample2.png\
|
11
|
+
--diff-file ./sample_images/diff_file.png --threshold 50`
|
12
|
+
puts io
|
13
|
+
end
|
data/cli_run.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require_relative './lib/png_comparison'
|
2
|
+
require 'optparse'
|
3
|
+
|
4
|
+
module CliRunner
|
5
|
+
def self.run
|
6
|
+
options = {}
|
7
|
+
opt_parser = OptionParser.new do |opts|
|
8
|
+
opts.banner = "The arguments should be: \n --file1 [path/]img1.png --file2 [path/]img2.png --diff-file [path/]diff.png\
|
9
|
+
--threshold [threshold in percents], [path] can be absolute or relative"
|
10
|
+
opts.on('-h', '--help', 'Prints this help') do
|
11
|
+
puts opts
|
12
|
+
exit
|
13
|
+
end
|
14
|
+
opts.on( '--file1 file_name', "[file_name] can be either absolute or relative") do |file1|
|
15
|
+
options[:file1] = file1
|
16
|
+
end
|
17
|
+
opts.on('--file2 file_name', "[file_name] can be either absolute or relative") do |file2|
|
18
|
+
options[:file2] = file2
|
19
|
+
end
|
20
|
+
opts.on('-d', '--diff-file diff_file_name', 'default is diff_file.png') do |diff_file|
|
21
|
+
options[:diff_file] = diff_file
|
22
|
+
end
|
23
|
+
opts.on('-t', '--threshold diff_file_name', 'default is diff_file.png') do |threshold|
|
24
|
+
options[:threshold] = threshold
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
opt_parser.parse!(ARGV)
|
29
|
+
if options.key?(:file1) && options.key?(:file2) && options.key?(:diff_file) && options.key?(:threshold)
|
30
|
+
img1 = options[:file1] # base image
|
31
|
+
img2 = options[:file2] # actual image
|
32
|
+
diff_file = options[:diff_file] # difference image
|
33
|
+
threshold = options[:threshold] # absolute threshold
|
34
|
+
PNG_Comparison::compare(img1: img1, img2: img2, diff_file: diff_file, threshold: threshold)
|
35
|
+
else
|
36
|
+
puts "Error: not all the mandatory parameters set. please run with -h/--help option"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
CliRunner.run if $PROGRAM_NAME == __FILE__
|
41
|
+
end
|
@@ -0,0 +1,141 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
if (Gem::Specification.find_all_by_name 'oily_png') != []
|
4
|
+
require 'oily_png'
|
5
|
+
else
|
6
|
+
require 'chunky_png'
|
7
|
+
end
|
8
|
+
|
9
|
+
include ChunkyPNG::Color
|
10
|
+
#==How to use:
|
11
|
+
#
|
12
|
+
#===1.Running from a command line
|
13
|
+
# ruby cli_run.rb -h
|
14
|
+
#
|
15
|
+
# or run a test run with
|
16
|
+
# rake sample_run
|
17
|
+
#===2.Including this module to a class
|
18
|
+
#
|
19
|
+
# require 'png_comparison'
|
20
|
+
#
|
21
|
+
# class YourClass
|
22
|
+
# include PNG_Comparison
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
# c = YourClass.new
|
26
|
+
# c.compare(img1: image1, img2: image2, diff_file: diff_file, threshold: threshold)
|
27
|
+
#
|
28
|
+
# this will make available the method "PNG_Comparison::compare()" to your class. The parameters the same as above
|
29
|
+
# img1,2,diff_file can be either filenames or instances of ChunkyPNG::Image class
|
30
|
+
#
|
31
|
+
#===3.Running compare() method directly from your program
|
32
|
+
# require 'png_comparison'
|
33
|
+
# ...
|
34
|
+
# PNG_Comparison::compare(img1: image1, img2: image2, diff_file: diff_file, threshold: threshold)
|
35
|
+
#
|
36
|
+
#==Tips and tricks:
|
37
|
+
#===For CRuby users: to speed up the program, please run:
|
38
|
+
# * "gem install 'oily_png'" in cmd after.
|
39
|
+
#====this will make comparison run much faster for big images as it uses C extensions. But oily_png gem is only for C platform
|
40
|
+
#
|
41
|
+
#===For JRuby users:
|
42
|
+
# Please adjust JVM memory when comparing big images to avoid OutOfMemory error :
|
43
|
+
# jruby -J-Xmx2200m png_comparison.rb [params]
|
44
|
+
# or use the above flag when running your own scripts that will use the png_comparison gem.
|
45
|
+
# Please bear in mind that the flag should be placed after 'jruby' but before your script name.
|
46
|
+
# The above memory size should be enough for images like 1700x7200, which is quite a regular web page size today.
|
47
|
+
#
|
48
|
+
# The main image difference algorithm is a kind of CIE76 (see https://en.wikipedia.org/wiki/Color_difference#CIE76).
|
49
|
+
|
50
|
+
module PNG_Comparison
|
51
|
+
module Comparator
|
52
|
+
def self.compare_images(img1:, img2:, diff_file:, threshold:)
|
53
|
+
read_start = Time.now
|
54
|
+
puts 'Reading images...'
|
55
|
+
if !(img1.is_a?(ChunkyPNG::Image) && img2.is_a?(ChunkyPNG::Image) && diff_file.is_a?(ChunkyPNG::Image))
|
56
|
+
image1 = ChunkyPNG::Image.from_file(img1)
|
57
|
+
image2 = ChunkyPNG::Image.from_file(img2)
|
58
|
+
output_file = ChunkyPNG::Image.new(image1.width, image1.height, WHITE)
|
59
|
+
else
|
60
|
+
image1 = img1
|
61
|
+
image2 = img2
|
62
|
+
output_file = diff_file
|
63
|
+
diff_file = 'diff_file'
|
64
|
+
end
|
65
|
+
|
66
|
+
read_end = Time.now
|
67
|
+
puts "Finished reading images in #{read_end - read_start} seconds"
|
68
|
+
|
69
|
+
image_length = image1.pixels.length
|
70
|
+
diff = []
|
71
|
+
perceptual_diff = 0
|
72
|
+
|
73
|
+
if !image1.eql?(image2) && (image1.dimension == image2.dimension)
|
74
|
+
diff, output_file = img_diff(image1: image1, image2: image2, output_file: output_file)
|
75
|
+
perceptual_diff = (diff.inject { |sum, value| sum + value } / image_length) * 100
|
76
|
+
else if image1.dimension != image2.dimension
|
77
|
+
puts 'Images have different dimensions!'
|
78
|
+
return false
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
absolute_change = show_statistics(image_length, diff, perceptual_diff, threshold)
|
83
|
+
# you can use here "if absolute_change > perceptual_diff"
|
84
|
+
if absolute_change > threshold
|
85
|
+
puts 'Images are not identical.'
|
86
|
+
output_file.save(diff_file)
|
87
|
+
return false
|
88
|
+
else
|
89
|
+
puts 'Images are identical or differ within threshold.'
|
90
|
+
output_file.save(diff_file) unless image1.eql?(image2)
|
91
|
+
return true
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
private
|
96
|
+
|
97
|
+
# Main color difference algorithm, kind of CIE76 metric
|
98
|
+
def self.img_diff(image1:, image2:, output_file:)
|
99
|
+
diff = []
|
100
|
+
image1.height.times do |y|
|
101
|
+
image1.row(y).each_with_index do |pixel, x|
|
102
|
+
next if pixel == image2[x, y]
|
103
|
+
score = Math.sqrt((r(image2[x, y]) - r(pixel))**2 + (g(image2[x, y]) - g(pixel))**2 +
|
104
|
+
(b(image2[x, y]) - b(pixel))**2) / Math.sqrt(MAX**2 * 3)
|
105
|
+
output_file[x, y] = grayscale(MAX - (score * MAX).round)
|
106
|
+
diff << score
|
107
|
+
end
|
108
|
+
end
|
109
|
+
[diff, output_file]
|
110
|
+
end
|
111
|
+
|
112
|
+
def self.show_statistics(image_length, diff, perceptual_diff, threshold)
|
113
|
+
total_pixels = image_length
|
114
|
+
non_matching_pixels = diff.length
|
115
|
+
absolute_change = (non_matching_pixels.to_f / total_pixels.to_f) * 100
|
116
|
+
puts "Pixels processed: #{total_pixels}"
|
117
|
+
puts "Differing Pixels: #{non_matching_pixels}"
|
118
|
+
puts "Perceptual image difference: #{perceptual_diff} (%)"
|
119
|
+
puts "Absolute image difference: #{absolute_change} (%), threshold is #{threshold}(%)"
|
120
|
+
absolute_change
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# This method will appear as an instance method if you include PNG_Comparison module to your class.
|
125
|
+
# will return true if images are identical, otherwize false
|
126
|
+
def compare(img1:, img2:, diff_file:, threshold:)
|
127
|
+
begin
|
128
|
+
start = Time.now
|
129
|
+
comparison = PNG_Comparison::Comparator.compare_images(img1: img1, img2: img2, diff_file: diff_file, threshold: threshold.to_f)
|
130
|
+
finish = Time.now
|
131
|
+
puts "Comparison took #{finish - start} seconds."
|
132
|
+
rescue Exception => e
|
133
|
+
puts "This error has occured: #{e.message}"
|
134
|
+
puts "The backtrace is #{e.backtrace}"
|
135
|
+
return nil
|
136
|
+
end
|
137
|
+
comparison
|
138
|
+
end
|
139
|
+
|
140
|
+
extend self
|
141
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
|
3
|
+
Gem::Specification.new do |spec|
|
4
|
+
spec.name = 'png_comparison'
|
5
|
+
spec.version = '1.0.8'
|
6
|
+
spec.authors = ['Ivan Pevtsov']
|
7
|
+
spec.email = ['ivan.pevtsov@gmail.com']
|
8
|
+
spec.license = 'MIT'
|
9
|
+
spec.summary = 'This simple program compares two PNG files and outputs the difference file.\
|
10
|
+
Should work on both C and J Ruby. See documentation for more details please.'
|
11
|
+
spec.description = File.read(File.join(File.dirname(__FILE__), 'Readme'))
|
12
|
+
spec.files = Dir['./lib/png_comparison.rb'] + Dir['./spec/*.rb'] + Dir['Rakefile', 'README', '*.gemspec', 'Gemfile','cli_run.rb']\
|
13
|
+
+ Dir['./sample_images/*.*']
|
14
|
+
spec.require_paths = Dir['lib']
|
15
|
+
spec.required_ruby_version = '>=1.9'
|
16
|
+
spec.add_runtime_dependency 'chunky_png', '>= 1.3.8'
|
17
|
+
spec.add_development_dependency 'bundler'
|
18
|
+
spec.add_development_dependency 'rspec'
|
19
|
+
end
|
Binary file
|
Binary file
|
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# The generated `.rspec` file contains `--require spec_helper` which will cause
|
4
|
+
# this file to always be loaded, without a need to explicitly require it in any
|
5
|
+
# files.
|
6
|
+
#
|
7
|
+
# Given that it is always loaded, you are encouraged to keep this file as
|
8
|
+
# light-weight as possible. Requiring heavyweight dependencies from this file
|
9
|
+
# will add to the boot time of your test suite on EVERY test run, even for an
|
10
|
+
# individual file that may not need all of that loaded. Instead, consider making
|
11
|
+
# a separate helper file that requires the additional dependencies and performs
|
12
|
+
# the additional setup, and require it from the spec files that actually need
|
13
|
+
# it.
|
14
|
+
#
|
15
|
+
# The `.rspec` file also contains a few flags that are not defaults but that
|
16
|
+
# users commonly want.
|
17
|
+
#
|
18
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
19
|
+
RSpec.configure do |config|
|
20
|
+
# rspec-expectations config goes here. You can use an alternate
|
21
|
+
# assertion/expectation library such as wrong or the stdlib/minitest
|
22
|
+
# assertions if you prefer.
|
23
|
+
config.expect_with :rspec do |expectations|
|
24
|
+
# This option will default to `true` in RSpec 4. It makes the `description`
|
25
|
+
# and `failure_message` of custom matchers include text for helper methods
|
26
|
+
# defined using `chain`, e.g.:
|
27
|
+
# be_bigger_than(2).and_smaller_than(4).description
|
28
|
+
# # => "be bigger than 2 and smaller than 4"
|
29
|
+
# ...rather than:
|
30
|
+
# # => "be bigger than 2"
|
31
|
+
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
|
32
|
+
end
|
33
|
+
|
34
|
+
# rspec-mocks config goes here. You can use an alternate test double
|
35
|
+
# library (such as bogus or mocha) by changing the `mock_with` option here.
|
36
|
+
config.mock_with :rspec do |mocks|
|
37
|
+
# Prevents you from mocking or stubbing a method that does not exist on
|
38
|
+
# a real object. This is generally recommended, and will default to
|
39
|
+
# `true` in RSpec 4.
|
40
|
+
mocks.verify_partial_doubles = true
|
41
|
+
end
|
42
|
+
|
43
|
+
# The settings below are suggested to provide a good initial experience
|
44
|
+
# with RSpec, but feel free to customize to your heart's content.
|
45
|
+
=begin
|
46
|
+
# These two settings work together to allow you to limit a spec run
|
47
|
+
# to individual examples or groups you care about by tagging them with
|
48
|
+
# `:focus` metadata. When nothing is tagged with `:focus`, all examples
|
49
|
+
# get run.
|
50
|
+
config.filter_run :focus
|
51
|
+
config.run_all_when_everything_filtered = true
|
52
|
+
|
53
|
+
# Allows RSpec to persist some state between runs in order to support
|
54
|
+
# the `--only-failures` and `--next-failure` CLI options. We recommend
|
55
|
+
# you configure your source control system to ignore this file.
|
56
|
+
config.example_status_persistence_file_path = "spec/examples.txt"
|
57
|
+
|
58
|
+
# Limits the available syntax to the non-monkey patched syntax that is
|
59
|
+
# recommended. For more details, see:
|
60
|
+
# - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
|
61
|
+
# - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
|
62
|
+
# - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
|
63
|
+
config.disable_monkey_patching!
|
64
|
+
|
65
|
+
# This setting enables warnings. It's recommended, but in some cases may
|
66
|
+
# be too noisy due to issues in dependencies.
|
67
|
+
config.warnings = true
|
68
|
+
|
69
|
+
# Many RSpec users commonly either run the entire suite or an individual
|
70
|
+
# file, and it's useful to allow more verbose output when running an
|
71
|
+
# individual spec file.
|
72
|
+
if config.files_to_run.one?
|
73
|
+
# Use the documentation formatter for detailed output,
|
74
|
+
# unless a formatter has already been configured
|
75
|
+
# (e.g. via a command-line flag).
|
76
|
+
config.default_formatter = 'doc'
|
77
|
+
end
|
78
|
+
|
79
|
+
# Print the 10 slowest examples and example groups at the
|
80
|
+
# end of the spec run, to help surface which specs are running
|
81
|
+
# particularly slow.
|
82
|
+
config.profile_examples = 10
|
83
|
+
|
84
|
+
# Run specs in random order to surface order dependencies. If you find an
|
85
|
+
# order dependency and want to debug it, you can fix the order by providing
|
86
|
+
# the seed, which is printed after each run.
|
87
|
+
# --seed 1234
|
88
|
+
config.order = :random
|
89
|
+
|
90
|
+
# Seed global randomization in this process using the `--seed` CLI option.
|
91
|
+
# Setting this allows you to use `--seed` to deterministically reproduce
|
92
|
+
# test failures related to randomization by passing the same `--seed` value
|
93
|
+
# as the one that triggered the failure.
|
94
|
+
Kernel.srand config.seed
|
95
|
+
=end
|
96
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
require_relative '../lib/png_comparison'
|
2
|
+
|
3
|
+
describe PNG_Comparison do
|
4
|
+
before(:context) do
|
5
|
+
@command = if RUBY_PLATFORM == 'java'
|
6
|
+
'jruby '
|
7
|
+
else
|
8
|
+
'ruby '
|
9
|
+
end
|
10
|
+
@image_path = './spec/spec_images/'
|
11
|
+
Dir.mkdir(@image_path) unless Dir.exist?(@image_path)
|
12
|
+
@image1_file = @image_path + 'valid_base.png'
|
13
|
+
@image2_file = @image_path + 'valid_base2.png'
|
14
|
+
@wrong_dimension_image_filename = @image_path + 'wrong_dimension.png'
|
15
|
+
@diff_file = @image_path + 'diff_file.png'
|
16
|
+
@c = Comparison.new
|
17
|
+
@valid_image = fill_in(ChunkyPNG::Image.new(200, 200, WHITE), 0)
|
18
|
+
@valid_image2 = fill_in(ChunkyPNG::Image.new(200, 200, WHITE), 5)
|
19
|
+
@another_dimension_image = fill_in(ChunkyPNG::Image.new(120, 100, WHITE), 50)
|
20
|
+
@valid_image.save(@image1_file)
|
21
|
+
@valid_image2.save(@image2_file)
|
22
|
+
@another_dimension_image.save(@wrong_dimension_image_filename)
|
23
|
+
end
|
24
|
+
|
25
|
+
def fill_in(image, offset)
|
26
|
+
off = 0
|
27
|
+
image.height.times do |y|
|
28
|
+
image.row(y).each_with_index do |_pixel, x|
|
29
|
+
off = offset if (x > image.width.to_f / 2) & (y > image.height.to_f / 2)
|
30
|
+
image[x, y] = rgb(x + off, (x + y) - 10 + off, y)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
image
|
34
|
+
end
|
35
|
+
|
36
|
+
class Comparison
|
37
|
+
include PNG_Comparison
|
38
|
+
end
|
39
|
+
|
40
|
+
describe '#run' do
|
41
|
+
context 'from the command line -' do
|
42
|
+
it "doesn't save the output when images are the same", same_images_file_command_line: true do
|
43
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file} --file2 #{@image1_file} --diff-file #{@diff_file} --threshold 0.5", 'r+')
|
44
|
+
output = cons.read
|
45
|
+
puts output
|
46
|
+
expect(File.exist?(@diff_file)).to be false
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'saves the difference to a specified file', different_images_file_command_line: true do
|
50
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file} --file2 #{@image2_file} --diff-file #{@diff_file} --threshold 5", 'r+')
|
51
|
+
output = cons.read
|
52
|
+
puts output
|
53
|
+
expect(File.exist?(@diff_file)).to be true
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'prints a valid specified threshold to the command line', valid_threshold_command_line: true do
|
57
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file} --file2 #{@image2_file} --diff-file #{@diff_file} --threshold 5", 'r+')
|
58
|
+
output = cons.read
|
59
|
+
puts output
|
60
|
+
expect(output).to include('threshold is 5.0(%)')
|
61
|
+
end
|
62
|
+
|
63
|
+
it "shows an error when image dimension doesn't match", dim_error_command_line: true do
|
64
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file} --file2 #{@wrong_dimension_image_filename} --diff-file #{@diff_file} --threshold 5}", 'r+')
|
65
|
+
output = cons.read
|
66
|
+
puts output
|
67
|
+
expect(output).to include('Images have different dimensions!')
|
68
|
+
end
|
69
|
+
|
70
|
+
it "prints 'Images are identical or differ within threshold.'", same_images_true_command_line: true do
|
71
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file} --file2 #{@image1_file} --diff-file #{@diff_file} --threshold 0.5", 'r+')
|
72
|
+
output = cons.read
|
73
|
+
puts output
|
74
|
+
expect(output).to include('Images are identical or differ within threshold.')
|
75
|
+
end
|
76
|
+
|
77
|
+
context "in case there are less or more than 4 arguments provided, \
|
78
|
+
it prints error 'Error: Wrong number of Parameters!!! The arguments should be: \
|
79
|
+
[path][img1].png [path][img2].png [path][diff].png [threshold] (=0.05 by default),\
|
80
|
+
[path] can be absolute or relative' ", wrong_arguments: true do
|
81
|
+
it ' for 1 argument', different_images_file_command_line_1arg: true do
|
82
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file}", 'r+')
|
83
|
+
output = cons.read
|
84
|
+
puts output
|
85
|
+
expect(output).to include('Error: not all the mandatory parameters set. please run with -h/--help option')
|
86
|
+
end
|
87
|
+
|
88
|
+
it ' for 2 arguments', different_images_file_command_line_2arg: true do
|
89
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file} --file2 #{@image1_file}", 'r+')
|
90
|
+
output = cons.read
|
91
|
+
puts output
|
92
|
+
expect(output).to include('Error: not all the mandatory parameters set. please run with -h/--help option')
|
93
|
+
end
|
94
|
+
|
95
|
+
it ' for 3 arguments', different_images_file_command_line_3arg: true do
|
96
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file} --file2 #{@image2_file} --diff-file #{@diff_file}", 'r+')
|
97
|
+
output = cons.read
|
98
|
+
puts output
|
99
|
+
expect(output).to include('Error: not all the mandatory parameters set. please run with -h/--help option')
|
100
|
+
end
|
101
|
+
|
102
|
+
it ' for 6 arguments', different_images_file_command_line_6arg: true do
|
103
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file} --file2 #{@image2_file} --diff-file #{@diff_file} --file1 #{@image1_file}\
|
104
|
+
--file2 #{@image2_file} -diff-file #{@diff_file}", 'r+')
|
105
|
+
output = cons.read
|
106
|
+
puts output
|
107
|
+
expect(output).to include('Error: not all the mandatory parameters set. please run with -h/--help option')
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'shows right statistics', statistics_command_line: true do
|
112
|
+
cons = IO.popen(@command + "./cli_run.rb --file1 #{@image1_file} --file2 #{@image2_file} --diff-file #{@diff_file} --threshold 5", 'r+')
|
113
|
+
output = cons.read
|
114
|
+
puts output
|
115
|
+
expect(File.exist?(@diff_file)).to be true
|
116
|
+
expect(output).to include('Reading images...')
|
117
|
+
expect(output).to include('Finished reading images')
|
118
|
+
expect(output).to include('Pixels processed:')
|
119
|
+
expect(output).to include('Differing Pixels:')
|
120
|
+
expect(output).to include('Perceptual image difference:')
|
121
|
+
expect(output).to include('Perceptual image difference:')
|
122
|
+
expect(output).to include('Comparison took')
|
123
|
+
end
|
124
|
+
|
125
|
+
it "shows help when run with -h key" do
|
126
|
+
cons = IO.popen(@command + "./cli_run.rb -h", 'r+')
|
127
|
+
output = cons.read
|
128
|
+
puts output
|
129
|
+
expect(output).to include("The arguments should be:")
|
130
|
+
expect(output).to include("--file1 [path/]img1.png --file2 [path/]img2.png --diff-file [path/]diff.png")
|
131
|
+
expect(output).to include("--threshold [threshold in percents], [path] can be absolute or relative")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context 'when using module method' do
|
136
|
+
it 'returns true when images are different (below threshold)', different_images_below_threshold: true do
|
137
|
+
expect(PNG_Comparison.compare(img1:@image1_file, img2:@image2_file, diff_file:@diff_file, threshold:60)).to be true
|
138
|
+
end
|
139
|
+
|
140
|
+
it "accepts ChunkyPNG::Image data as input parameters" do
|
141
|
+
diff_image = ChunkyPNG::Image.new(200, 200, WHITE)
|
142
|
+
#require 'pry'
|
143
|
+
#binding.pry
|
144
|
+
expect(PNG_Comparison.compare(img1:@valid_image, img2:@valid_image2, diff_file:diff_image, threshold:60)).to be true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'included to a class ', same_images: true do
|
149
|
+
it 'returns true when images are different (below threshold)', different_images_below_threshold: true do
|
150
|
+
expect(@c.compare(img1:@image1_file, img2:@image2_file, diff_file:@diff_file, threshold:60)).to be true
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'returns false when images are different (above threshold)', different_images_above_threshold: true do
|
154
|
+
expect(@c.compare(img1:@image1_file, img2:@image2_file, diff_file:@diff_file, threshold:5)).to be false
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
after(:each) do
|
160
|
+
File.delete(@diff_file) if File.exist?(@diff_file)
|
161
|
+
end
|
162
|
+
|
163
|
+
after(:context) do
|
164
|
+
Dir.glob(@image_path + '*.png').each { |file| File.delete(file) }
|
165
|
+
Dir.delete(@image_path)
|
166
|
+
end
|
167
|
+
end
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: png_comparison
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.8
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Ivan Pevtsov
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2017-11-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: chunky_png
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 1.3.8
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 1.3.8
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
description: |
|
56
|
+
This simple program compares two 'png' images, says whether they are different or not and outputs a difference file.
|
57
|
+
Please see '/lib/png_comparison.rb' file or run 'rdoc' for this gem for more details.
|
58
|
+
email:
|
59
|
+
- ivan.pevtsov@gmail.com
|
60
|
+
executables: []
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- "./lib/png_comparison.rb"
|
65
|
+
- "./sample_images/diff_file.png"
|
66
|
+
- "./sample_images/sample1.png"
|
67
|
+
- "./sample_images/sample2.png"
|
68
|
+
- "./spec/spec_helper.rb"
|
69
|
+
- "./spec/test_image_comparison_spec.rb"
|
70
|
+
- Gemfile
|
71
|
+
- README
|
72
|
+
- Rakefile
|
73
|
+
- cli_run.rb
|
74
|
+
- png_comparison.gemspec
|
75
|
+
homepage:
|
76
|
+
licenses:
|
77
|
+
- MIT
|
78
|
+
metadata: {}
|
79
|
+
post_install_message:
|
80
|
+
rdoc_options: []
|
81
|
+
require_paths:
|
82
|
+
- lib
|
83
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ">="
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '1.9'
|
88
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
89
|
+
requirements:
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: '0'
|
93
|
+
requirements: []
|
94
|
+
rubyforge_project:
|
95
|
+
rubygems_version: 2.6.10
|
96
|
+
signing_key:
|
97
|
+
specification_version: 4
|
98
|
+
summary: This simple program compares two PNG files and outputs the difference file.\
|
99
|
+
Should work on both C and J Ruby. See documentation for more details please.
|
100
|
+
test_files: []
|