dhash-vips 0.0.0.1 → 0.0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +15 -4
- data/dhash.gemspec +3 -2
- data/lib/dhash-vips.rb +5 -4
- data/lib/dhash-vips/version.rb +1 -1
- data/spec/_spec.rb +50 -14
- metadata +17 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 91c7be59e88216898e8a6dfa9cb3eeccf88cd9d6
|
4
|
+
data.tar.gz: 76e55f4d301b274ee37a95c236ebe7d884164490
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9d6d563744fe3b72502b5827ef072af1b816866e30374b1ff18e312157cc646776c352560e4c3c7ec52b436d5833f3731455d5429b9d0051d0491943b718f860
|
7
|
+
data.tar.gz: 92054de250d05c1a93ffb178c85ccc8ac2132e110869789d2097fe8c8f03c1f4f0c280a1b3b941fa72e10f333d7adac389d10b96deb967387cd0501e01d69fff
|
data/README.md
CHANGED
@@ -6,19 +6,30 @@ Read "Kind of Like That" blog post (21 January 2013): http://www.hackerfactor.co
|
|
6
6
|
|
7
7
|
It does not automatically detect very shifted crops and rotated images but you may make a wrapper that would call the comparison function iteratively.
|
8
8
|
|
9
|
-
This implementation is powered by Vips and was forked from https://github.com/maccman/dhash
|
9
|
+
This implementation is powered by Vips and was forked from https://github.com/maccman/dhash that used ImageMagick.
|
10
10
|
|
11
11
|
# Installation
|
12
12
|
|
13
|
+
brew install vips
|
14
|
+
|
15
|
+
If you have troubles with above, see https://jcupitt.github.io/libvips/install.html
|
16
|
+
Then:
|
17
|
+
|
13
18
|
gem install dhash-vips
|
14
19
|
|
20
|
+
If you have troubles with the `gem vips` dependency, see https://github.com/jcupitt/ruby-vips
|
21
|
+
|
15
22
|
# Usage
|
16
23
|
|
17
|
-
hash1 = DhashVips.calculate "
|
18
|
-
hash2 = DhashVips.calculate "
|
24
|
+
hash1 = DhashVips.calculate "photo1.jpg"
|
25
|
+
hash2 = DhashVips.calculate "photo2.jpg"
|
19
26
|
|
20
27
|
if 10 > DhashVips.hamming(hash1, hash2)
|
21
28
|
puts "Images are very similar"
|
29
|
+
elsif 20 > DhashVips.hamming(hash1, hash2)
|
30
|
+
puts "Images are slightly similar"
|
22
31
|
else
|
23
|
-
puts "
|
32
|
+
puts "Images are different"
|
24
33
|
end
|
34
|
+
|
35
|
+
These `10` and `20` numbers are found empirically and just work enough well for 8-byte hashes.
|
data/dhash.gemspec
CHANGED
@@ -14,7 +14,8 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.add_dependency "vips"
|
15
15
|
|
16
16
|
spec.add_development_dependency "dhash"
|
17
|
-
|
17
|
+
|
18
18
|
spec.add_development_dependency "rake"
|
19
|
-
spec.add_development_dependency "rspec"
|
19
|
+
spec.add_development_dependency "rspec-core"
|
20
|
+
spec.add_development_dependency "mll"
|
20
21
|
end
|
data/lib/dhash-vips.rb
CHANGED
@@ -5,24 +5,25 @@ module DhashVips
|
|
5
5
|
extend self
|
6
6
|
|
7
7
|
def hamming a, b
|
8
|
-
(a^b).to_s(2).count
|
8
|
+
(a ^ b).to_s(2).count "1"
|
9
9
|
end
|
10
10
|
|
11
11
|
def calculate file, hash_size = 8
|
12
12
|
image = Vips::Image.new_from_file file
|
13
13
|
image = image.resize((hash_size + 1).fdiv(image.width), vscale: hash_size.fdiv(image.height)).colourspace "b-w"
|
14
14
|
|
15
|
-
difference =
|
15
|
+
difference = 0
|
16
16
|
|
17
17
|
hash_size.times do |row|
|
18
18
|
hash_size.times do |col|
|
19
19
|
pixel_left = image.getpoint(col, row).first
|
20
20
|
pixel_right = image.getpoint(col + 1, row).first
|
21
|
-
difference
|
21
|
+
difference <<= 1
|
22
|
+
difference += 1 if pixel_left > pixel_right
|
22
23
|
end
|
23
24
|
end
|
24
25
|
|
25
|
-
difference
|
26
|
+
difference
|
26
27
|
end
|
27
28
|
|
28
29
|
end
|
data/lib/dhash-vips/version.rb
CHANGED
data/spec/_spec.rb
CHANGED
@@ -1,24 +1,60 @@
|
|
1
1
|
require "dhash-vips"
|
2
2
|
|
3
3
|
describe DhashVips do
|
4
|
-
it 'should have similar hashes for low/high of same image' do
|
5
|
-
hash1 = DhashVips.calculate(File.expand_path('../images/face-high.jpg', __FILE__))
|
6
|
-
hash2 = DhashVips.calculate(File.expand_path('../images/face-low.jpg', __FILE__))
|
7
4
|
|
8
|
-
|
9
|
-
|
5
|
+
require "tmpdir"
|
6
|
+
require "fileutils"
|
7
|
+
require "open-uri"
|
8
|
+
require "digest"
|
9
|
+
require "mll"
|
10
|
+
example do |example|
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
12
|
+
images = %w{
|
13
|
+
1d468d064d2e26b5b5de9a0241ef2d4b.jpg
|
14
|
+
92d90b8977f813af803c78107e7f698e.jpg
|
15
|
+
309666c7b45ecbf8f13e85a0bd6b0a4c.jpg
|
16
|
+
3f9f3db06db20d1d9f8188cd753f6ef4.jpg
|
17
|
+
df0a3b93e9412536ee8a11255f974141.jpg
|
18
|
+
679634ff89a31279a39f03e278bc9a01.jpg
|
19
|
+
} # these images a consecutive pairs of slightly (but enough for nice asserts) silimar images
|
14
20
|
|
15
|
-
|
16
|
-
|
21
|
+
example.metadata[:extra_failure_lines] = []
|
22
|
+
FileUtils.mkdir_p dir = Dir.tmpdir + "/dhash-vips-spec"
|
23
|
+
images.each do |image|
|
24
|
+
"#{dir}/#{image}".tap do |filename|
|
25
|
+
unless File.exist?(filename) && Digest::MD5.file(filename) == File.basename(filename, ".jpg")
|
26
|
+
example.metadata[:extra_failure_lines] << "copying image from web to #{filename}"
|
27
|
+
open("https://storage.googleapis.com/dhash-vips.nakilon.pro/#{image}") do |link|
|
28
|
+
File.open(filename, "wb") do |file|
|
29
|
+
IO.copy_stream link, file
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
17
35
|
|
18
|
-
|
19
|
-
|
20
|
-
|
36
|
+
hashes = images.map &DhashVips.method(:calculate)
|
37
|
+
table = MLL::table[DhashVips.method(:hamming), [hashes], [hashes]]
|
38
|
+
# require "pp"
|
39
|
+
# pp table
|
40
|
+
# [[0, 17, 29, 27, 22, 29],
|
41
|
+
# [17, 0, 30, 26, 33, 36],
|
42
|
+
# [29, 30, 0, 18, 39, 30],
|
43
|
+
# [27, 26, 18, 0, 35, 30],
|
44
|
+
# [22, 33, 39, 35, 0, 17],
|
45
|
+
# [29, 36, 30, 30, 17, 0]]
|
21
46
|
|
22
|
-
|
47
|
+
hashes.size.times.to_a.combination(2) do |i, j|
|
48
|
+
case
|
49
|
+
when i == j
|
50
|
+
expect(table[i][j]).to eq 0
|
51
|
+
when (j - i).abs == 1 && (i + j - 1) % 4 == 0
|
52
|
+
expect(table[i][j]).to be > 0
|
53
|
+
expect(table[i][j]).to be < 19
|
54
|
+
else
|
55
|
+
expect(table[i][j]).to be > 21
|
56
|
+
end
|
57
|
+
end
|
23
58
|
end
|
59
|
+
|
24
60
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dhash-vips
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.0.
|
4
|
+
version: 0.0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Maslov
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-09-
|
11
|
+
date: 2017-09-21 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: vips
|
@@ -53,7 +53,21 @@ dependencies:
|
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
|
-
name: rspec
|
56
|
+
name: rspec-core
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: mll
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
73
|
- - '>='
|