js利用otsu算法将图像二值化后,去掉多于背景,实现精确选定区域,包裹有内容得区域,效果如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>使用canvas实现切图的效果 第二版</title>
<style>
body {
text-align: center;
}
canvas {
border: 1px solid;
}
.newcanvas {
width: 316px;
margin: auto;
}
.newpohoto,
.download {
width: 300px;
height: 40px;
line-height: 40px;
margin: auto;
background-color: cornflowerblue;
border-radius: 5px;
cursor: pointer;
margin: 10px auto;
color: white;
}
.box {
background: #f00;
width: 0px;
height: 0px;
position: absolute;
opacity: 0.5;
cursor: move;
}
.droptarget {
float: left;
width: 100px;
height: 1000px;
margin: 15px;
padding: 10px;
border: 1px solid #aaaaaa;
}
</style>
</head>
<body>
<div class="mycanvas">
<canvas id="mycnavas" onmousemove="cnvs_getCoordinates(event)" onmouseout="cnvs_clearCoordinates()"></canvas>
</div>
<div class="newcanvas">
<canvas id="img" width="200" height="50"></canvas>
</div>
<div style="margin: 10px;">
<span>二值化阈值:</span>
<span id="threshold"></span>
</div>
<div style="margin: 10px;">
<span>计算坐标:</span>
<span id="zuobiao"></span>
<span style="margin-left: 50px;">画坐标:</span>
<span id="x_y"></span>
</div>
<div style="margin: 10px;">
<span>鼠标当前位置:</span>
<span id="xycoordinates"></span>
</div>
<div class="newcanvas">
<canvas id="img2z" width="200" height="50"></canvas>
</div>
<script>
// startX, startY 为鼠标点击时初始坐标
// diffX, diffY 为鼠标初始坐标与 box 左上角坐标之差,用于拖动
let startX, startY, diffX, diffY;
// 是否拖动,初始为 false
let dragging = false;
let coordiv = document.getElementById('mycnavas');
let minlen = 10;
// 鼠标按下
document.onmousedown = function(e) {
startX = e.pageX;
startY = e.pageY;
// 如果鼠标在 box 上被按下,坐标判定防止在box之外
if( startY<=coordiv.offsetTop+coordiv.offsetHeight &&
startY>=coordiv.offsetTop &&
startX>=coordiv.offsetLeft &&
startX<=coordiv.offsetLeft+coordiv.offsetWidth) {
// 在页面创建 box
let active_box = document.createElement("div");
active_box.id = "active_box";
active_box.className = "box";
active_box.style.top = startY + 'px';
active_box.style.left = startX + 'px';
active_box.setAttribute("ondrop","drop(event)");
active_box.setAttribute("ondragover","allowDrop(event)");
document.body.appendChild(active_box);
active_box = null;
}
};
// 鼠标移动
document.onmousemove = function(e) {
if( e.pageY <= coordiv.offsetTop+coordiv.offsetHeight &&
e.pageY >= coordiv.offsetTop &&
e.pageX >= coordiv.offsetLeft &&
e.pageX <= coordiv.offsetLeft+coordiv.offsetWidth) {
// 更新 box 尺寸 如果document中有active_box,就改变box大
if(document.getElementById("active_box") !== null) {
let ab = document.getElementById("active_box");
ab.style.width = e.pageX - startX + 'px';
ab.style.height = e.pageY - startY + 'px';
}
}
};
// 鼠标抬起
document.onmouseup = function(e) {
// 禁止拖动
dragging = false;
if(document.getElementById("active_box") !== null) {
let ab = document.getElementById("active_box");
ab.removeAttribute("id");
// 如果长宽均小于 3px,移除 box
if(ab.offsetWidth < minlen || ab.offsetHeight < minlen) {
document.body.removeChild(ab);
}
if(ab.offsetHeight >= minlen && ab.offsetHeight >= minlen) {
let xy_div = "[" + (startX-coordiv.offsetLeft) + "," + (startY-coordiv.offsetTop) + "," + (e.pageX-coordiv.offsetLeft) + "," + (e.pageY-coordiv.offsetTop) + "]";
let input_div = document.getElementById("x_y")
input_div.innerHTML = xy_div
arr = [startX-coordiv.offsetLeft,startY-coordiv.offsetTop,e.pageX-coordiv.offsetLeft,e.pageY-coordiv.offsetTop];
let newarr = qie();
document.body.removeChild(ab);
let active_box = document.createElement("div");
active_box.id = "active_box";
active_box.className = "box";
active_box.style.left = newarr[0] + coordiv.offsetLeft + 'px';
active_box.style.top = newarr[1] + coordiv.offsetTop + 'px';
active_box.style.width = ( newarr[2] - newarr[0] ) + 'px';
active_box.style.height = ( newarr[3] - newarr[1] ) + 'px';
active_box.setAttribute("ondrop","drop(event)");
active_box.setAttribute("ondragover","allowDrop(event)");
document.body.appendChild(active_box);
active_box = null;
let ab2 = document.getElementById("active_box");
ab2.removeAttribute("id");
// 如果长宽均小于 3px,移除 box
if(ab2.offsetWidth < minlen || ab2.offsetHeight < minlen) {
document.body.removeChild(ab2);
}
}
}
};
//框内移动显示坐标
function cnvs_getCoordinates(e) {
//不能用clientX,pageX为文档坐标,clientX表示浏览器界面坐标,会随滚动条改变
x=e.pageX-e.target.offsetLeft;
y=e.pageY-e.target.offsetTop;
document.getElementById("xycoordinates").innerHTML="(" + x + "," + y + ")";
}
//出框后不显示坐标
function cnvs_clearCoordinates() {
document.getElementById("xycoordinates").innerHTML="";
}
function dragStart(event) {
event.dataTransfer.setData("Text", event.target.id);
}
function allowDrop(event) {
event.preventDefault();
}
function drop(event) {
event.preventDefault();
let data = event.dataTransfer.getData("Text");
event.target.appendChild(document.getElementById(data));
}
</script>
<script>
let mycnavas = document.getElementById("mycnavas"); //现将图片放上去
let cxt = mycnavas.getContext("2d");
let image = new Image();
image.src = "img/fp.jpg";
mycnavas.width = image.width;
mycnavas.height = image.height;
window.onload = function() {
cxt.drawImage(image, 0, 0); //画好图片的位置
}
let arr = [-1,-1,-1,-1]
function qie() {
//核心代码
......
}
</script>
<script src="js/otsu.js"></script>
</body>
</html>