-
Notifications
You must be signed in to change notification settings - Fork 0
/
app.js
92 lines (89 loc) · 3.54 KB
/
app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
const MAX_DISTANCE = 12;
class App {
constructor() {
this.refMap = new Map();
this.files = [];
this.file = null;
this.upload = document.getElementById( 'file' );
this.upload.addEventListener( 'change', evt => this.doUpload( evt ) );
this.preview = document.getElementById( 'preview' );
this.result = document.getElementById( 'result' );
fetch("https://raw.githubusercontent.com/laqieer/FE-Mod-Face-Search/main/refMap.json")
.then(blob => blob.json())
.then(data => this.refMap = data);
fetch("https://raw.githubusercontent.com/laqieer/FE-Mod-Face-Search/main/files.json")
.then(blob => blob.json())
.then(data => this.files = data);
}
async doUpload( event ) {
this.file = event.target.files[0];
const bitmap = await createImageBitmap( this.file );
if ( bitmap.width <= 64 || bitmap.height <= 64 ) {
alert("Image dimension is too small!");
return;
}
if ( bitmap.width > 160 || bitmap.height > 160 ) {
alert("Image dimension is too big!");
return;
}
this.preview.width = bitmap.width;
this.preview.height = bitmap.height;
var ctx = this.preview.getContext("2d");
if ( this.preview.width == 160 && this.preview.height == 160 ) {
this.preview.width = 128;
this.preview.height = 128;
}
if ( this.preview.width == 128 && this.preview.height == 112 ) {
this.preview.width = 96;
this.preview.height = 80;
}
ctx.drawImage( bitmap, 0, 0 );
var imgData = ctx.getImageData( 0, 0, this.preview.width, this.preview.height );
var hash = bmvbhash( imgData, 8 );
console.log( 'Hash: ' + hash );
var imgs = this.refMap[hash];
var distance = 0;
if ( imgs == undefined ) {
imgs = [];
var hashes = [];
for ( var h in this.refMap ) {
var dis = hammingDistance( hash, h );
if ( dis > MAX_DISTANCE ) {
continue;
}
if ( hashes[dis] == undefined ) {
hashes[dis] = [ h ]
} else {
hashes[dis].push( h );
}
}
for ( var d in hashes ) {
if ( hashes[d] != undefined ) {
for ( var i in hashes[d] ) {
imgs.push( ...this.refMap[hashes[d][i]] );
}
distance = d;
break;
}
}
}
if ( distance > 0 ) {
this.result.innerHTML = '<b>' + imgs.length + ' similar results found. (Similarity: ' + 100 * ( 64 - distance ) / 64 + '%)</b>';
} else {
this.result.innerHTML = '<b>' + imgs.length + ' results found.' + '</b>';
}
for ( var i in imgs ) {
this.result.appendChild( document.createElement('br') );
var id = imgs[i].replace( /[^0-9]/ig, '' );
var file = this.files[id];
if ( file != undefined ) {
this.result.appendChild( document.createTextNode( file ) );
}
this.result.appendChild( document.createElement('br') );
var img = document.createElement( 'img' );
img.src = imgs[i];
this.result.appendChild( img );
}
};
}
let app = new App();