Module: DHashVips::IDHash
- Defined in:
- lib/dhash-vips.rb
Class Method Summary collapse
Class Method Details
.distance(a, b) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/dhash-vips.rb', line 66 def self.distance a, b size_a, size_b = [a, b].map do |x| # TODO write a test about possible hash sizes # they were 32 and 128, 124, 120 for MRI 2.0 # but also 31, 30 happens for MRI 2.3 x.size <= 32 ? 8 : 16 end return distance3 a, b if [8, 8] == [size_a, size_b] fail "fingerprints were taken with different `power` param: #{size_a} and #{size_b}" if size_a != size_b ((a ^ b) & (a | b) >> 2 * size_a * size_a).to_s(2).count "1" end |
.distance3_ruby(a, b) ⇒ Object
34 35 36 |
# File 'lib/dhash-vips.rb', line 34 def self.distance3_ruby a, b ((a ^ b) & (a | b) >> 128).to_s(2).count "1" end |
.fingerprint(input, power = 3) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/dhash-vips.rb', line 99 def self.fingerprint input, power = 3 size = 2 ** power image = if input.is_a? Vips::Image input.thumbnail_image(size, height: size, size: :force) else Vips::Image.thumbnail(input, size, height: size, size: :force) end array = DHashVips.bw(image).to_enum.map &:flatten d1, i1, d2, i2 = [array, array.transpose].flat_map do |a| d = a.zip(a.rotate(1)).flat_map{ |r1, r2| r1.zip(r2).map{ |i, j| i - j } } m = median d.map(&:abs).sort [ d.map{ |c| c < 0 ? 1 : 0 }.join.to_i(2), d.map{ |c| c.abs >= m ? 1 : 0 }.join.to_i(2), ] end (((((i1 << size * size) + i2) << size * size) + d1) << size * size) + d2 end |