<!doctype html> <html> <head> <meta charset="utf-8"> <title>识别相似图片</title> <style> html { background:#F0F0F0; } body { margin:0; padding:0; } img { display:block; } .panel { width:300px; height:200px; border:1px solid #CCC; background:#F5F5F5; float:left; display:-webkit-box; -webkit-box-pack:center; -webkit-box-align:center; color:#CCC; font-size:14px; position:relative; -webkit-transition:.5s opacity ease; margin:20px; margin-right:0; } .panel img { width:100%; position:absolute; left:0; top:0; width:100%; } .on { border:1px dashed #FFF; background-color:#369; color:#FFF; } .similar { float:left; margin:20px; border:1px solid #4896D5; background:#D3EEFA; color:#4896D5; font-size:14px; border-radius:5px; padding:10px; opacity:.9; display:none; } </style> <script> window.onload = function () { var panel1 = document.querySelectorAll('.panel')[0]; var panel2 = document.querySelectorAll('.panel')[1]; panel1.ondragover = panel2.ondragover = function (ev) { return false; }; panel1.ondragenter = panel2.ondragenter = function (ev) { var span = this.querySelectorAll('span')[0]; span.innerHTML = '松开按键将图片放入此框'; this.style.opacity = .8; var re = /on/; if (!re.test(this.className)) this.className += ' on'; }; panel1.ondragleave = panel2.ondragleave = function (ev) { var span = this.querySelectorAll('span')[0]; span.innerHTML = '请拖拽原始图片至此框内'; this.style.opacity = 1; var re = /on/; if (re.test(this.className)) this.className = this.className.replace(re, ''); }; panel1.ondrop = panel2.ondrop = function (ev) { var re = /on/; if (re.test(this.className)) this.className = this.className.replace(re, ''); this.style.opacity = 1; var self = this, file = ev.dataTransfer.files[0], reader = new FileReader(); reader.onload = function (ev) { var img = self.querySelectorAll('img')[0]; if (!img) { img = new Image(); self.appendChild(img); } img.onload = function () { self.style.width = this.width + 'px'; self.style.height = this.height + 'px'; var img1 = panel1.querySelectorAll('img')[0]; var img2 = panel2.querySelectorAll('img')[0]; if (img1 && img2) { document.querySelectorAll('.similar')[0].innerHTML = '相似度:' + searchImage(img1, img2) + '%'; document.querySelectorAll('.similar')[0].style.display = 'block'; } }; img.src = this.result; }; reader.readAsDataURL(file); return false; }; }; function searchImage(image1, image2, tmplw, tmplh) { var canvas = document.createElement('canvas'), ctx = canvas.getContext('2d'), sw = image1.width, // 原图宽度 sh = image1.height, // 原图高度 tw = tmplw || 8, // 模板宽度 th = tmplh || 8; // 模板高度 canvas.width = tw; canvas.height = th; ctx.drawImage(image1, 0, 0, sw, sh, 0, 0, tw, th); var pixels = ctx.getImageData(0, 0, tw, th); pixels = toGrayBinary(pixels, true, null, true); var canvas2 = document.createElement('canvas'); var ctx2 = canvas2.getContext('2d'); canvas2.width = tw; canvas2.height = th; ctx2.drawImage(image2, 0, 0, image2.width, image2.height, 0, 0, tw, th); var pixels2 = ctx2.getImageData(0, 0, tw, th); pixels2 = toGrayBinary(pixels2, true, null, true); var similar = 0; for (var i = 0, len = tw * th; i < len; i++) { if (pixels[i] == pixels2[i]) similar++; } similar = (similar / (tw * th)) * 100; return similar; } // 像素数据,是否二值化(bool),二值化闵值(0-255),是否返回二值化后序列(bool) function toGrayBinary(pixels, binary, value, sn) { var r, g, b, g, avg = 0, len = pixels.data.length, s = ''; for (var i = 0; i < len; i += 4) { avg += (.299 * pixels.data[i] + .587 * pixels.data[i + 1] + .114 * pixels.data[i + 2]); } avg /= (len / 4); for (var i = 0; i < len; i += 4) { r = .299 * pixels.data[i], g = .587 * pixels.data[i + 1], b = .114 * pixels.data[i + 2]; if (binary) { if ((r + g + b) >= (value || avg)) { g = 255; if (sn) s += '1'; } else { g = 0; if (sn) s += '0'; } g = (r + g + b) > (value || avg) ? 255 : 0; } else { g = r + g + b; } pixels.data[i] = g, pixels.data[i + 1] = g, pixels.data[i + 2] = g; } if (sn) return s; else return pixels; } </script> </head> <body> <div class="panel"><span>请拖拽图片一至此框内</span></div> <div class="panel"><span>请拖拽图片二至此框内</span></div> <div class="similar"></div> </body> </html>