<!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 = /\bon\b/;
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 = /\bon\b/;
if (re.test(this.className)) this.className = this.className.replace(re, '');
}; panel1.ondrop = panel2.ondrop = function (ev) {
var re = /\bon\b/;
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>

Canvas识别相似图片的更多相关文章

  1. 基于HTML5 Canvas实现的图片马赛克模糊特效

    效果请点击下面网址: http://hovertree.com/texiao/html5/1.htm 一.开门见山受美国肖像画家Chuck Close的启发,此脚本通过使用HTML5 canvas元素 ...

  2. Android实现OCR扫描识别数字图片之图片扫描识别

    [Android实例] Android实现OCR扫描识别数字图片之图片扫描识别 Android可以识别和扫描二维码,但是识别字符串呢? google提供了以下解决方案用的是原来HP的相关资料. 可以吧 ...

  3. canvas生成遮罩图片

         首先我们知道css3中增加了不少好用.好玩的css3样式可以使用.今天我们要说到是遮罩.        它的使用方式也不复杂,和background使用方式差不多.使用mask-image就 ...

  4. HTML5 Canvas前台压缩图片并上传到服务器

    1.前台代码: <input id="fileOne" type="file" /> <input id="btnOne" ...

  5. [js高手之路] html5 canvas系列教程 - 图片操作(drawImage,clip,createPattern)

    接着上文[js高手之路] html5 canvas系列教程 - 文本样式(strokeText,fillText,measureText,textAlign,textBaseline)继续,本文介绍的 ...

  6. 以API方式调用C# dll,使用OneNote2013 sp1实现OCR识别本地图片

    http://www.cnblogs.com/Charltsing/p/OneNoteOCRAPI.html OneNote2013 OCR API调用使用说明2019.4.17 使用说明:1.安装干 ...

  7. 用canvas给视频图片添加特效

    Canvas制作视频图片特效 1. Canvas介绍 1.1Canvas是html5上的一个画布标签,功能有点类似java的swing.可以在canvas上画线条 弧线, 文字 就是画布的功能. 具体 ...

  8. 微信小程序--canvas画布实现图片的编辑

    技术:微信小程序   概述 上传图片,编辑图片大小,添加文字,改变文字颜色等 详细 代码下载:http://www.demodashi.com/demo/14789.html 概述 微信小程序--ca ...

  9. canvas 2.0 图片绘制

    绘制图片drawImage 2013.02.21 by 十年灯·一条评论 本文属于<html5 Canvas画图系列教程> 这里的绘制图片是指把一张现成的图片,绘制到Canvas上面. 有 ...

随机推荐

  1. 边工作边刷题:70天一遍leetcode: day 85-1

    Inorder Successor in BST 要点:这题要注意的是如果不是BST,没法从树结构上从root向那边找p,只能遍历.而根据BST,可以只走正确方向 如果不检查right子树,可以从ro ...

  2. codeforces 711E E. ZS and The Birthday Paradox(数学+概率)

    题目链接: E. ZS and The Birthday Paradox. time limit per test 2 seconds memory limit per test 256 megaby ...

  3. Facebook或成云领域黑马 冲击亚马逊

    [摘要]目前,云计算领域最大的服务是亚马逊AWS,据称此服务年度营收约为100亿美元. 转播到腾讯微博 BI中文站 3月22日报道 如今,多数人认为亚马逊在云计算领域的发展势头无人可档,不过,这个市场 ...

  4. 使用javascript获取url中的参数

    方法一: //取url参数 var type = request("type") function request() { var query = location.search; ...

  5. C++容器的复制

    C++容器的复制不同于Java Java是引用复制,复制的仅仅是对象的引用, 在需要复制容器内对象的副本集合的情况,需要使用Clone方法,而且要注意clone方法的浅拷贝 深拷贝 C++的容器复制 ...

  6. 动态调用webservice,不需要添加Web References

    using System; using System.Collections.Generic; using System.Web; using System.Net; using System.IO; ...

  7. mac上一键配置和安装adb驱动或者环境

    最近才使用的mac,老实说mac上要配置adb的环境不那么复杂,但是还是会让一些心不细或者动手能力不强的同学望而却步.那么到底有没有一个一键完成mac上adb和fastboot环境搭配的软件或者脚本呢 ...

  8. Verilog学习笔记基本语法篇(九)········ 任务和函数

    task 和 function 说明语句分别用来定义任务和函数,利用任务和函数可以把函数模块分成许多小的任务和函数便于理解和调试.任务和函数往往还是大的程序模块在不同地点多次用到的相同的程序段.输入. ...

  9. 好用的SQLSERVER数据库自动备份工具SQLBackupAndFTP(功能全面)

    转载:http://www.cnblogs.com/lyhabc/p/3322437.html 挺好用的SQLSERVER数据库自动备份工具SQLBackupAndFTP(功能全面) 这个工具主要就是 ...

  10. Android Home键状态保存运用场景

    当我们在一个Activity中有接收Intent过来的值,或者当前Activity有保存数据时候,如果此时不小心按到了Home键,然后没有及时回来而是运行了其它应用程序,当你想起来的时候,恐怕已经是几 ...