dhash-vips 0.0.0.1 → 0.0.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/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
|
- - '>='
|