pxdoppelganger 0.1.1

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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c51c60a2ee727316dda9cc0fc8b4c73edb6c19f9
4
+ data.tar.gz: 3d623cc945a162ebe82470b83977eb1b6e9dc0e5
5
+ SHA512:
6
+ metadata.gz: 8b20cccc5c96cf628644bff2ce8e205ae1b64f5b77db311ab970e6d9175704475ed065f752ab225ebce6b0b9cd8ef698ad981b7da086bc5ba95068e64338d540
7
+ data.tar.gz: 839bf7efb354e0df470c6c9b303fb90cf3512edf9e7a3491c4cdaab01183f0894c1f9d567e0c3d59d9bc8e43ec1b9e285dbdef7836d7c6c2159b7a33dfb44fbc
@@ -0,0 +1,11 @@
1
+ lib/images/**
2
+ .idea/
3
+ out.html
4
+
5
+ *~
6
+ chromedriver.log
7
+ .ruby-version
8
+ .DS_Store
9
+ .kate-swp
10
+ .ruby-gemset
11
+ .swp
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'chunky_png'
6
+ gem 'oily_png'
7
+ gem 'rspec'
@@ -0,0 +1,37 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ pxdoppelganger (0.1.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ chunky_png (1.3.4)
10
+ diff-lcs (1.2.5)
11
+ oily_png (1.2.0)
12
+ chunky_png (~> 1.3.1)
13
+ rspec (3.3.0)
14
+ rspec-core (~> 3.3.0)
15
+ rspec-expectations (~> 3.3.0)
16
+ rspec-mocks (~> 3.3.0)
17
+ rspec-core (3.3.2)
18
+ rspec-support (~> 3.3.0)
19
+ rspec-expectations (3.3.1)
20
+ diff-lcs (>= 1.2.0, < 2.0)
21
+ rspec-support (~> 3.3.0)
22
+ rspec-mocks (3.3.2)
23
+ diff-lcs (>= 1.2.0, < 2.0)
24
+ rspec-support (~> 3.3.0)
25
+ rspec-support (3.3.0)
26
+
27
+ PLATFORMS
28
+ ruby
29
+
30
+ DEPENDENCIES
31
+ chunky_png
32
+ oily_png
33
+ pxdoppelganger!
34
+ rspec
35
+
36
+ BUNDLED WITH
37
+ 1.10.5
@@ -0,0 +1,49 @@
1
+ # pXdoppelganger
2
+
3
+ ## what can it do for me?
4
+
5
+ * pXdoppelganger can compare two images for you.
6
+ * pXdoppelganger converts the images into bitstreams and thus analyze every pixcel.
7
+ * pXdoppelganger can tell you if those images are equal and what the percentual change is.
8
+ * pXdoppelganger can also show you the "difference" image between the two images.
9
+
10
+ ## how do I use it?
11
+
12
+ install the gem:
13
+ ```
14
+ gem install pxdoppelganger
15
+ ```
16
+ and use it:
17
+ ```
18
+ require 'pxdoppelganger'
19
+ ```
20
+
21
+ provide paths to images:
22
+ ```
23
+ images = PXDoppelganger::Images.new('~/Downloads/Image1.png', '~/Downloads/Image2.png')
24
+ ```
25
+
26
+ see if images are equal:
27
+ ```
28
+ images.equal?
29
+ => true/false
30
+ ```
31
+
32
+ get the difference of the two images (in percent):
33
+ ```
34
+ images.difference
35
+ => 1.3849177058385036
36
+ ```
37
+
38
+ save the difference-image:
39
+ ```
40
+ images.save_difference_image('~Documents/analysis/diff_image.png')
41
+ ```
42
+
43
+ ## how do I contribute?
44
+
45
+ open pull request
46
+
47
+ ## license
48
+
49
+ MIT: http://opensource.org/licenses/MIT
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'pxdoppelganger'
4
+
5
+ Deployment.new
@@ -0,0 +1,76 @@
1
+ require 'oily_png'
2
+ require 'chunky_png'
3
+ require 'fileutils'
4
+ include OilyPNG::Color
5
+ include ChunkyPNG::Color
6
+
7
+ class Analyzer
8
+
9
+ attr_accessor :difference, :difference_in_percent
10
+
11
+ def initialize(base_image, new_image)
12
+ raise 'The images need to be in png format' unless are_images_png?(base_image, new_image)
13
+ self.images = [
14
+ ChunkyPNG::Image.from_file(base_image),
15
+ ChunkyPNG::Image.from_file(new_image),
16
+ ]
17
+ raise_different_size unless images_have_same_width?
18
+ self.difference = difference_analyzer
19
+ self.difference_in_percent = percent_calculator(difference)
20
+ end
21
+
22
+ def save_output(path)
23
+ @output.save(path)
24
+ end
25
+
26
+ private
27
+
28
+ attr_accessor :images
29
+
30
+ def are_images_png?(base, new)
31
+ true if (base.downcase.include? 'png') && (new.downcase.include? 'png')
32
+ end
33
+
34
+ def images_have_same_width?
35
+ images.first.width == images.last.width
36
+ end
37
+
38
+ def raise_different_size
39
+ raise "The images do not have the same width."
40
+ end
41
+
42
+ def difference_analyzer
43
+ @output = ChunkyPNG::Image.new(images.first.width, images.first.height, WHITE)
44
+ difference = []
45
+ images.first.height.times do |y|
46
+ images.first.row(y).each_with_index do |pixel, x|
47
+ begin
48
+ unless pixel == images.last[x,y]
49
+ score = Math.sqrt(
50
+ (r(images.last[x,y]) - r(pixel)) ** 2 +
51
+ (g(images.last[x,y]) - g(pixel)) ** 2 +
52
+ (b(images.last[x,y]) - b(pixel)) ** 2
53
+ ) / Math.sqrt(MAX ** 2 * 3)
54
+
55
+ @output[x,y] = grayscale(MAX - (score * MAX).round)
56
+ difference << score
57
+ end
58
+ rescue ChunkyPNG::OutOfBounds
59
+ # "out of bound error"
60
+ # in Y-Direction (= one image is longer than the other)
61
+ # if webpages change, they may have a different vertical length
62
+ end
63
+ end
64
+ end
65
+ difference
66
+ end
67
+
68
+ def percent_calculator(difference)
69
+ if difference == []
70
+ 0
71
+ else
72
+ ((difference.inject {|sum, value| sum + value} / images.first.pixels.length) * 100).to_f
73
+ end
74
+ end
75
+
76
+ end
@@ -0,0 +1,26 @@
1
+ require 'rubygems'
2
+ require 'controller/analyzer'
3
+
4
+ module PXDoppelganger
5
+
6
+ class Images
7
+
8
+ def initialize(base_image, new_image)
9
+ @result = Analyzer.new(base_image, new_image)
10
+ end
11
+
12
+ def equal?
13
+ @result.difference == []
14
+ end
15
+
16
+ def difference
17
+ @result.difference_in_percent
18
+ end
19
+
20
+ def save_difference_image(path)
21
+ @result.save_output(path)
22
+ end
23
+
24
+ end
25
+
26
+ end
@@ -0,0 +1,13 @@
1
+ module PXDoppelganger
2
+ class Version
3
+ MAJOR = 0
4
+ MINOR = 1
5
+ PATCH = 1
6
+
7
+ class << self
8
+ def to_s
9
+ [MAJOR, MINOR, PATCH].join('.')
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,16 @@
1
+ require File.expand_path('../lib/pxdoppelganger/version', __FILE__)
2
+
3
+ Gem::Specification.new do |gem|
4
+ gem.authors = %w(Finn Lorbeer)
5
+ gem.version = PXDoppelganger::Version
6
+ gem.name = 'pxdoppelganger'
7
+ gem.platform = Gem::Platform::RUBY
8
+ gem.require_paths = %w(lib)
9
+ gem.license = 'MIT'
10
+ gem.email = %w(finn.von.friesland@googlemail.com)
11
+ gem.summary = "pXdoppelganger will help you in your automated design regression testing"
12
+ gem.description = %q{pXdoppelganger compares two images and can tell you the exact difference (in % of pixels changed). If you compare two screenshots of you app before and after a release, it will help you to automate your design regression tests. It follows the suggestions of image comparison by in Jeff Kreeftmeijers blog: jeffkreeftmeijer.com/2011/comparing-images-and-creating-image-diffs/}
13
+ gem.homepage = 'https://www.otto.de'
14
+ gem.files = `git ls-files`.split($\)
15
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
16
+ end
Binary file
@@ -0,0 +1,74 @@
1
+ require 'rspec'
2
+ require 'fileutils'
3
+ require '../../lib/controller/analyzer'
4
+
5
+ describe '#analyzer' do
6
+
7
+ PATH_TO_OTTO_LOGO = '../images/ottologo.png'
8
+ PATH_TO_DIFFERENT_LOGO = '../images/ottologo2.png'
9
+ DIFFERENCE_IMAGE = '../images/otto_DIFF.png'
10
+
11
+ after(:each) { FileUtils.rm DIFFERENCE_IMAGE if File.exist? (DIFFERENCE_IMAGE) }
12
+
13
+ it "should throw an exception if the images is not png" do
14
+ expect {
15
+ Analyzer.new('some_wrong/path.JPG', 'another_wrong/path.JPG')
16
+ }.to raise_error("The images need to be in png format")
17
+ end
18
+
19
+ it "should throw an exception if the image cannot be found" do
20
+ expect {
21
+ Analyzer.new('some_wrong/path.png', 'another_wrong/path.PNG')
22
+ }.to raise_error(Errno::ENOENT)
23
+ end
24
+
25
+ it "should throw an exception if the images do not have the same width" do
26
+ expect {
27
+ Analyzer.new(PATH_TO_OTTO_LOGO, '../images/ottologosmall.png')
28
+ }.to raise_error("The images do not have the same width.")
29
+ end
30
+
31
+ it "should return an empty array if both analyzed images are the same" do
32
+ analyzer = Analyzer.new(PATH_TO_OTTO_LOGO, PATH_TO_OTTO_LOGO)
33
+ expect(
34
+ analyzer.difference.empty?
35
+ ).to be(true)
36
+ end
37
+
38
+ it "should return 0% change if both analyzed images are the same" do
39
+ analyzer = Analyzer.new(PATH_TO_OTTO_LOGO, PATH_TO_OTTO_LOGO)
40
+ expect(
41
+ analyzer.difference_in_percent
42
+ ).to eq(0)
43
+ end
44
+
45
+ it "should return a not empty array if both analyzed images are not the same" do
46
+ analyzer = Analyzer.new(PATH_TO_OTTO_LOGO, PATH_TO_DIFFERENT_LOGO)
47
+ expect(
48
+ analyzer.difference.empty?
49
+ ).to be(false)
50
+ end
51
+
52
+ it "should return x% change if the analyzed images are not the same" do
53
+ analyzer = Analyzer.new(PATH_TO_OTTO_LOGO, PATH_TO_DIFFERENT_LOGO)
54
+ expect(
55
+ analyzer.difference_in_percent.round(2)
56
+ ).to eq(1.38)
57
+ end
58
+
59
+ it "should create an output image" do
60
+ analyzer = Analyzer.new(PATH_TO_OTTO_LOGO, PATH_TO_DIFFERENT_LOGO)
61
+ expect(
62
+ analyzer.save_output(DIFFERENCE_IMAGE)
63
+ ).to be_a(File)
64
+ end
65
+
66
+ it "should save an output image" do
67
+ analyzer = Analyzer.new(PATH_TO_OTTO_LOGO, PATH_TO_DIFFERENT_LOGO)
68
+ analyzer.save_output(DIFFERENCE_IMAGE)
69
+ expect(
70
+ File.exist? (DIFFERENCE_IMAGE)
71
+ ).to be(true)
72
+ end
73
+
74
+ end
@@ -0,0 +1,58 @@
1
+ require 'rspec'
2
+ require '../../lib/controller/analyzer'
3
+ require '../../lib/pxdoppelganger'
4
+
5
+ PATH_TO_OTTO_LOGO = '../images/ottologo.png'
6
+ PATH_TO_DIFFERENT_LOGO = '../images/ottologo2.png'
7
+ DIFFERENCE_IMAGE = '../images/otto_DIFF.png'
8
+
9
+ describe '#equal?' do
10
+
11
+ it 'returns "true" if two images are equal' do
12
+ pxdoppelganger = PXDoppelganger::Images.new(
13
+ PATH_TO_OTTO_LOGO, PATH_TO_OTTO_LOGO
14
+ )
15
+ expect(
16
+ pxdoppelganger.equal?
17
+ ).to be(true)
18
+ end
19
+
20
+ it 'returns "false" if two images are equal' do
21
+ pxdoppelganger = PXDoppelganger::Images.new(
22
+ PATH_TO_OTTO_LOGO, PATH_TO_DIFFERENT_LOGO
23
+ )
24
+ expect(
25
+ pxdoppelganger.equal?
26
+ ).to be(false)
27
+ end
28
+
29
+ end
30
+
31
+ describe '#difference' do
32
+
33
+ it 'returns the %-difference of two images' do
34
+ pxdoppelganger = PXDoppelganger::Images.new(
35
+ PATH_TO_OTTO_LOGO, PATH_TO_DIFFERENT_LOGO
36
+ )
37
+ expect(
38
+ pxdoppelganger.difference.round(2)
39
+ ).to eq(1.38)
40
+ end
41
+
42
+ end
43
+
44
+ describe '#save_difference_image' do
45
+
46
+ after(:each) { FileUtils.rm DIFFERENCE_IMAGE if File.exist? (DIFFERENCE_IMAGE) }
47
+
48
+ it 'saves the difference image' do
49
+ pxdoppelganger = PXDoppelganger::Images.new(
50
+ PATH_TO_OTTO_LOGO, PATH_TO_DIFFERENT_LOGO
51
+ )
52
+ pxdoppelganger.save_difference_image(DIFFERENCE_IMAGE)
53
+ expect(
54
+ File.exist? (DIFFERENCE_IMAGE)
55
+ ).to be(true)
56
+ end
57
+
58
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: pxdoppelganger
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Finn
8
+ - Lorbeer
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-07-21 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: 'pXdoppelganger compares two images and can tell you the exact difference
15
+ (in % of pixels changed). If you compare two screenshots of you app before and after
16
+ a release, it will help you to automate your design regression tests. It follows
17
+ the suggestions of image comparison by in Jeff Kreeftmeijers blog: jeffkreeftmeijer.com/2011/comparing-images-and-creating-image-diffs/'
18
+ email:
19
+ - finn.von.friesland@googlemail.com
20
+ executables:
21
+ - pxdoppelganger
22
+ extensions: []
23
+ extra_rdoc_files: []
24
+ files:
25
+ - ".gitignore"
26
+ - Gemfile
27
+ - Gemfile.lock
28
+ - README.md
29
+ - bin/pxdoppelganger
30
+ - lib/controller/analyzer.rb
31
+ - lib/pxdoppelganger.rb
32
+ - lib/pxdoppelganger/version.rb
33
+ - pxdoppelganger.gemspec
34
+ - tests/images/ottologo.png
35
+ - tests/images/ottologo2.png
36
+ - tests/images/ottologosmall.png
37
+ - tests/rspec/analyzer_spec.rb
38
+ - tests/rspec/pxdoppelganger_spec.rb
39
+ homepage: https://www.otto.de
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.4.8
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: pXdoppelganger will help you in your automated design regression testing
63
+ test_files: []