Skip to content

Instantly share code, notes, and snippets.

@YuJianrong
Created June 25, 2024 00:29
Show Gist options
  • Save YuJianrong/a55d1cae0300bb34a59aa161a0f5ea7b to your computer and use it in GitHub Desktop.
Save YuJianrong/a55d1cae0300bb34a59aa161a0f5ea7b to your computer and use it in GitHub Desktop.
2048
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Image Test</title>
<style>
html,
body {
overflow-x: auto;
overflow-y: scroll;
height: 100%;
}
body,
dl,
dt,
dd,
ul,
ol,
li,
pre,
form,
fieldset,
input,
p,
blockquote,
th,
td {
font-weight: 400;
margin: 0;
padding: 0;
}
.left {
float: left;
left: 0px;
margin: 2px;
}
.leftCanvas {
background-color: aquamarine;
overflow: auto;
width: 500px;
display: none;
height: calc(100% - 30px);
}
input.number {
display: inline-block;
width: 72px;
height: 20px;
text-align: center;
line-height: 20px;
cursor: pointer;
}
</style>
<script type="text/javascript" src="opencv.js"></script>
</head>
<body>
<div>
<input id="imageSelect" type="file" accept="image/*" />
块宽:<input id="pieceWidth" class="number" type="number" min="0" max="999" value="0"/>
块高:<input id="pieceHeight" class="number" type="number" min="0" max="999" value="0"/>
<input id="imageProcess" type="button" value="执行" />
<input id="imageSave" type="button" value="保存图片" />
</div>
<div class="left leftCanvas">
<canvas id="imgCanvas" width="0" height="0"></canvas>
</div>
<div class="left">
<canvas id="imgResult" width="0" height="0"></canvas>
</div>
<div class="left">
<canvas id="imgSave" width="0" height="0"></canvas>
</div>
<script>
var pieceWidth = 0;
var pieceHeight = 0;
var canvasTemp = document.createElement('canvas');
var ctxTemp = canvasTemp.getContext('2d');
// 读取本地文件
var inputOne = document.getElementById('imageSelect');
inputOne.onchange = function () {
// 获取选中的文件列表
var fileList = inputOne.files;
var file = fileList[0];
// 读取文件内容
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function (e) {
// 将结果显示到canvas
showCanvas(reader.result);
}
}
// 块大小自动绑定
var inputWidth = document.getElementById('pieceWidth');
inputWidth.onchange=function(){
pieceWidth = inputWidth.value;
}
var inputHeight = document.getElementById('pieceHeight');
inputHeight.onchange=function(){
pieceHeight = inputHeight.value;
}
// 指定图片内容显示
function showCanvas1(dataUrl) {
var canvas = document.getElementById('imgCanvas');
var ctx = canvas.getContext('2d');
// 加载图片
var img = new Image();
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
setTimeout(() => {
let src = cv.imread(img);
var rgbaPlanes = new cv.MatVector();
cv.split(src, rgbaPlanes);
let red = rgbaPlanes.get(0);
let green = rgbaPlanes.get(1);
let blue = rgbaPlanes.get(2);
var t1 = new cv.Mat();
var t2 = new cv.Mat();
var t3 = new cv.Mat();
cv.add(red, green, t1);
cv.add(red, blue, t2);
cv.add(green, blue, t3);
var split_channel_images = [
red,
green,
blue,
t1,
t2,
t3
];
var size_candidates = [];
for (i in split_channel_images) {
var image = split_channel_images[i];
var thresh = new cv.Mat();
cv.threshold(image, thresh, 200, 255, cv.THRESH_BINARY);
var opened = new cv.Mat();
var element = cv.getStructuringElement(cv.MORPH_OPEN, new cv.Size(5, 5));
cv.morphologyEx(thresh, opened, cv.MORPH_OPEN, element)
var binary_image = new cv.Mat();
cv.bitwise_not(opened, binary_image);
var contours = new cv.MatVector();
var hierarchy = new cv.Mat();
cv.findContours(binary_image,
contours,
hierarchy,
cv.RETR_LIST,
cv.CHAIN_APPROX_SIMPLE);
cv.imshow('imgCanvas', thresh);
setTimeout(() => {
showCanvas3();
}, 100);
return;
for (var contourIndex = 0; contourIndex < contours.size(); contourIndex++) {
var contour = contours.get(contourIndex);
var bounding_rect = cv.boundingRect(contour);
var contour_area = cv.contourArea(contour);
var width = bounding_rect.width;
var height = bounding_rect.height;
var extent = contour_area / (width * height);
var lower_limit = 1
var upper_limit = 200 * 200
var is_square = Math.abs(width - height) < 300;
var is_extent_valid = extent >= 0.75;
if (is_square && is_extent_valid) {
var candidate = (bounding_rect.width + bounding_rect.height) / 2;
size_candidates.push(candidate);
}
}
}
console.info(size_candidates);
cv.imshow('imgCanvas', src);
}, 0);
}
img.src = dataUrl;
}
function showCanvas3() {
var canvas = document.getElementById('imgCanvas');
var ctx = canvas.getContext('2d');
console.info(ctx);
var imgData = ctx.getImageData(0, 0, canvas.width, canvas.height);
console.info("*** 开始识别高度 ***");
imgData = imgFindY(imgData, canvas.width, canvas.height);
console.info("*** 完成识别高度 ***");
ctx.putImageData(imgData, 0, 0)
}
function showCanvas(dataUrl) {
var canvas = document.getElementById('imgCanvas');
var ctx = canvas.getContext('2d');
// 加载图片
var img = new Image();
img.onload = function () {
canvas.width = img.width;
canvas.height = img.height;
canvasTemp.width = img.width;
canvasTemp.height = img.height;
// 改变canvas大小后延迟绘图,避免空白
setTimeout(() => {
ctx.drawImage(img, 0, 0, img.width, img.height);
ctxTemp.drawImage(img, 0, 0, img.width, img.height);
var imgData = ctx.getImageData(0, 0, img.width, img.height);
var imgDataCopy = new ImageData(img.width, img.height);
imgDataCopy.data.set(imgData.data);
console.info("*** 灰度化 ***");
imgData = imgToGray(imgDataCopy);
// console.info("*** 开始二值化 ***");
// imgData = imgTo2Value(imgData)
// console.info("*** 开始腐蚀 ***");
// imgData = erode(imgData, img.width, img.height);
// console.info("*** 开始膨胀 ***");
// imgData = dilate(imgData, img.width, img.height);
console.info("*** 识别高度 ***");
var maxHeight = imgFindY(imgDataCopy, img.width, img.height);
console.info("*** 识别宽度 ***");
var maxWidth = imgFindX(imgDataCopy, img.width, img.height);
// var maxWidth = 0;
// var imgDataCopy = imgFindX(imgDataCopy, img.width, img.height);
// ctx.putImageData(imgDataCopy, 0, 0)
console.info("maxWidth=" + maxWidth);
console.info("maxHeight=" + maxHeight);
if (maxHeight <= 1 || maxWidth <= 1) {
return;
}
pieceWidth = 96;//maxWidth
pieceHeight = 128;//maxHeight
inputWidth.value = pieceWidth;
inputHeight.value = pieceHeight;
// 增加画板宽度和高度
canvas.width = img.width + 5 * Math.ceil(img.width / maxWidth) - 5;
canvas.height = img.height + 5 * Math.ceil(img.height / maxHeight) - 5;
setTimeout(() => {
for (var y = 0; y < Math.ceil(img.height / maxHeight); y++) {
for (var x = 0; x < Math.ceil(img.width / maxWidth); x++) {
var startX = x * maxWidth;
var startY = y * maxHeight;
var canvasX = x * (maxWidth + 5);
var canvasY = y * (maxHeight + 5);
var width = maxWidth;
var height = maxHeight;
if (x == Math.ceil(img.width / maxWidth) - 1 && img.width % maxWidth != 0) {
width = img.width % maxWidth;
}
if (y == Math.ceil(img.height / maxHeight) - 1 && img.height % maxWidth != 0) {
height = img.height % maxHeight;
}
ctx.drawImage(img, startX, startY, width, height, canvasX, canvasY, width, height);
}
}
if (canvas.width > 500) {
reSetCanvasSize();
}
}, 0);
// ctx.putImageData(imgDataCopy, 0, 0)
}, 0);
}
img.src = dataUrl;
}
// 灰度化
function imgToGray(imgData) {
for (var i = 0; i < imgData.data.length; i += 4) {
var R = imgData.data[i]; //R(0-255)
var G = imgData.data[i + 1]; //G(0-255)
var B = imgData.data[i + 2]; //G(0-255)
var Alpha = imgData.data[i + 3]; //Alpha(0-255)
//var gray = R*0.299 + G*0.587 + B*0.114;
var gray = (R + G + B) / 3;
imgData.data[i] = gray;
imgData.data[i + 1] = gray;
imgData.data[i + 2] = gray;
imgData.data[i + 3] = Alpha;
}
return imgData;
}
// 二值化
function imgTo2Value(imgData) {
// 平均值
var s = 0;
var c = 0;
for (var i = 0; i < imgData.data.length; i += 4) {
s += imgData.data[i];
c++;
}
var a = s / c;
for (var i = 0; i < imgData.data.length; i += 4) {
var R = imgData.data[i];
var gray = 0;
if (R > a) {
gray = 255;
}
imgData.data[i] = gray;
imgData.data[i + 1] = gray;
imgData.data[i + 2] = gray;
}
return imgData;
}
// 膨胀
function dilate(dst, width, height) {
var size = 3;
var dstData = dst.data;
var mData = JSON.parse(JSON.stringify(dstData));
var newOffset, total, nowX, offsetY, offsetI, nowOffset, i, j;
for (i = height; i--;) {
offsetI = i * width;
for (j = width; j--;) {
newOffset = 0;
total = 0;
for (y = size; y--;) {
offsetY = (y + i) * width * 4;
for (x = size; x--;) {
nowX = (x + j) * 4;
nowOffset = offsetY + nowX;
(mData[nowOffset] + mData[nowOffset + 1] + mData[nowOffset + 2] > total) && (total = mData[nowOffset] + mData[nowOffset + 1] + mData[nowOffset + 2]) && (newOffset = nowOffset);
}
}
dstData[(j + offsetI) * 4] = mData[newOffset];
dstData[(j + offsetI) * 4 + 1] = mData[newOffset + 1];
dstData[(j + offsetI) * 4 + 2] = mData[newOffset + 2];
dstData[(j + offsetI) * 4 + 3] = mData[newOffset + 3];
}
}
return dst;
};
// 腐蚀
function erode(dst, width, height) {
var size = 3;
var dstData = dst.data;
var mData = JSON.parse(JSON.stringify(dstData));
var newOffset, total, nowX, offsetY, offsetI, nowOffset, i, j;
for (i = height; i--;) {
offsetI = i * width;
for (j = width; j--;) {
newOffset = 0;
total = 765;
for (y = size; y--;) {
offsetY = (y + i) * width * 4;
for (x = size; x--;) {
nowX = (x + j) * 4;
nowOffset = offsetY + nowX;
(mData[nowOffset] + mData[nowOffset + 1] + mData[nowOffset + 2] < total) && (total = mData[nowOffset] + mData[nowOffset + 1] + mData[nowOffset + 2]) && (newOffset = nowOffset);
}
}
dstData[(j + offsetI) * 4] = mData[newOffset];
dstData[(j + offsetI) * 4 + 1] = mData[newOffset + 1];
dstData[(j + offsetI) * 4 + 2] = mData[newOffset + 2];
dstData[(j + offsetI) * 4 + 3] = mData[newOffset + 3];
}
}
return dst;
};
// 寻找Y轴高度
function imgFindY(imgData, width, height) {
var yCount = [0];
var ySum = 0;
var yAvg = 0;
var hCount = {};
var imgDataCopy = new ImageData(width, height);
imgDataCopy.data.set(imgData.data);
var mData = imgDataCopy.data;
for (var y = 1; y < height - 2; y += 1) {
var count = 0
for (var x = 1; x < width - 2; x += 1) {
var i = y * width * 4 + x * 4;
var i1 = i - 4;
var i2 = i + 4;
var i3 = i - width * 4;
var j = i + width * 4;
var j1 = j - 4;
var j2 = j + 4;
var j3 = j + width * 4;
var pa = (mData[i] + mData[i1] + mData[i2] + mData[i3]) / 4;
var pb = (mData[j] + mData[j1] + mData[j2] + mData[j3]) / 4;
if (Math.abs(pa - pb) > 25) {
count += 1;
// imgData.data[i] = 255;
// imgData.data[i + 1] = 0;
// imgData.data[i + 2] = 0;
}
}
yCount.push(count);
ySum += count;
}
yAvg = ySum / yCount.length;
// 相互之间最多高度
for (var i = 0; i < yCount.length; i++) {
if (yCount[i] > yAvg * 0.7 + width * 0.3) {
yCount[i] = 1;
} else {
yCount[i] = 0;
}
}
var yNum = [];
for (var i = 0; i < yCount.length; i++) {
if (yCount[i] == 1) {
yNum.push(i);
}
}
for (var i = 0; i < yNum.length; i++) {
for (var j = 0; j < i; j++) {
if (!hCount[yNum[i] - yNum[j]]) {
hCount[yNum[i] - yNum[j]] = 1;
} else {
hCount[yNum[i] - yNum[j]]++;
}
}
}
// 最多高度
var maxCount = 0;
var maxHeight = 0;
for (var i in hCount) {
if (hCount[i] > maxCount && parseInt(i) > 10) {
maxCount = hCount[i];
maxHeight = parseInt(i);
}
}
// console.info(hCount);
// console.info(maxHeight);
return maxHeight;
// if (maxHeight <= 1) {
// return imgData;
// }
// for (var y = 0; y < height; y++) {
// if ((y + 1) % maxHeight != 0) {
// continue;
// }
// for (var x = 0; x < width; x++) {
// var i = y * width * 4 + x * 4
// imgData.data[i] = 255;
// }
// }
// return imgData;
}
// 寻找X轴高度
function imgFindX(imgData, width, height) {
var xCount = [];
var xSum = 0;
var xAvg = 0;
var wCount = {};
var imgDataCopy = new ImageData(width, height);
imgDataCopy.data.set(imgData.data);
var mData = imgDataCopy.data;
for (var x = 20; x < width - 2; x += 1) {
var count = 0
for (var y = 20; y < height; y += 1) {
var i = y * width * 4 + x * 4;
var i1 = i - 4;
var i2 = i + width * 4;
var i3 = i - width * 4;
var j = i + 4;
var j1 = j + 4;
var j2 = j - width * 4;
var j3 = j + width * 4;
var pa = (mData[i] + mData[i1] + mData[i2] + mData[i3]) / 4;
var pb = (mData[j] + mData[j1] + mData[j2] + mData[j3]) / 4;
if (Math.abs(pa - pb) > 25) {
count += 1;
// imgData.data[i] = 255;
// imgData.data[i + 1] = 0;
// imgData.data[i + 2] = 0;
}
}
xCount.push(count);
xSum += count;
}
xAvg = xSum / xCount.length;
// 相互之间最多高度
for (var i = 0; i < xCount.length; i++) {
if (xCount[i] > xAvg * 0.7 + height * 0.3) {
xCount[i] = 1;
} else {
xCount[i] = 0;
}
}
var xNum = [];
for (var i = 0; i < xCount.length; i++) {
if (xCount[i] == 1) {
xNum.push(i);
}
}
for (var i = 0; i < xNum.length; i++) {
for (var j = 0; j < i; j++) {
if (!wCount[xNum[i] - xNum[j]]) {
wCount[xNum[i] - xNum[j]] = 1;
} else {
wCount[xNum[i] - xNum[j]]++;
}
}
}
// 最多宽度
var maxCount = 0;
var maxWidth = 0;
for (var i in wCount) {
if (wCount[i] > maxCount && parseInt(i) > 1) {
maxCount = wCount[i];
maxWidth = parseInt(i);
}
}
// console.info(xCount);
// console.info(wCount);
// console.info(maxWidth);
// return imgData;
return maxWidth;
// if (maxWidth <= 1) {
// return imgData;
// }
// for (var y = 0; y < height; y++) {
// for (var x = 0; x < width; x++) {
// if ((x + 1) % maxWidth != 0) {
// continue;
// }
// var i = y * width * 4 + x * 4
// imgData.data[i] = 255;
// }
// }
// return imgData;
}
function reSetCanvasSize() {
var canvas = document.getElementById('imgCanvas');
var ctx = canvas.getContext('2d');
var img = new Image();
img.onload = function () {
var width = canvas.width;
var height = canvas.height;
var imgScale = 500 / canvas.width;
canvas.width = 500;
canvas.height = canvas.height * imgScale;
setTimeout(() => {
ctx.drawImage(img, 0, 0, width, height, 0, 0, canvas.width, canvas.height);
}, 0);
}
img.src = canvas.toDataURL("image/png");
}
var imageProcess = document.getElementById('imageProcess');
var resultCanvas = document.getElementById('imgResult');
var resultCtx = resultCanvas.getContext('2d');
var lastPieceX = -1;
var lastPieceY = -1;
var lastPieceImageData;
resultCanvas.onclick = function (e) {
var x = e.offsetX;
var y = e.offsetY;
var pieceX = Math.floor(x / pieceWidth);
var pieceY = Math.floor(y / pieceHeight);
if (lastPieceX == -1) {
lastPieceX = pieceX;
lastPieceY = pieceY;
lastPieceImageData = resultCtx.getImageData(lastPieceX * pieceWidth + lastPieceX, lastPieceY * pieceHeight + lastPieceY, pieceWidth, pieceHeight);
// 边框
var imgDataCopy = new ImageData(pieceWidth, pieceHeight);
imgDataCopy.data.set(lastPieceImageData.data);
console.info(imgDataCopy.data[0] + "," + imgDataCopy.data[1] + "," + imgDataCopy.data[2]);
for (var py = 0; py < pieceHeight; py++) {
for (var px = 0; px < pieceWidth; px++) {
if (px == 0 || py == 0 || px == pieceWidth - 1 || py == pieceHeight - 1) {
for (var i = 0; i < 3; i++) {
imgDataCopy.data[py * pieceWidth * 4 + px * 4 + i] = 0;
}
}
}
}
resultCtx.putImageData(imgDataCopy, lastPieceX * pieceWidth + lastPieceX, lastPieceY * pieceHeight + lastPieceY);
console.info(imgDataCopy.data[0] + "," + imgDataCopy.data[1] + "," + imgDataCopy.data[2]);
} else if (lastPieceX == pieceX && lastPieceY == pieceY) {
// 取消选择
resultCtx.putImageData(lastPieceImageData, lastPieceX * pieceWidth + lastPieceX, lastPieceY * pieceHeight + lastPieceY);
lastPieceX = -1;
lastPieceY = -1;
} else {
// 互换位置
var newPieceImageData = resultCtx.getImageData(pieceX * pieceWidth + pieceX, pieceY * pieceHeight + pieceY, pieceWidth, pieceHeight);
resultCtx.putImageData(lastPieceImageData, pieceX * pieceWidth + pieceX, pieceY * pieceHeight + pieceY);
resultCtx.putImageData(newPieceImageData, lastPieceX * pieceWidth + lastPieceX, lastPieceY * pieceHeight + lastPieceY);
lastPieceX = -1;
lastPieceY = -1;
}
}
imageProcess.onclick = function () {
var canvas = document.getElementById('imgResult');
var ctx = canvas.getContext('2d');
canvas.width = canvasTemp.width + Math.ceil(canvasTemp.width / pieceWidth) - 1;
canvas.height = canvasTemp.height + Math.ceil(canvasTemp.height / pieceHeight) - 1;
setTimeout(() => {
// 除不尽则将最后块之间放入结果
if (canvas.width % pieceWidth != 0) {
for (var i = 0; i < Math.ceil(canvas.height / pieceHeight); i++) {
var imgData = ctxTemp.getImageData(Math.floor(canvas.width / pieceWidth) * pieceWidth, i * pieceHeight, pieceWidth, pieceHeight);
ctx.putImageData(imgData, Math.floor(canvas.width / pieceWidth) * pieceWidth + Math.ceil(canvas.width / pieceWidth) - 1, i * pieceHeight + i)
}
}
if (canvas.height % pieceHeight != 0) {
for (var i = 0; i < Math.ceil(canvas.height / pieceHeight); i++) {
var imgData = ctxTemp.getImageData(i * pieceWidth, Math.floor(canvas.height / pieceHeight) * pieceHeight, pieceWidth, pieceHeight);
ctx.putImageData(imgData, i * pieceWidth + i, Math.floor(canvas.height / pieceHeight) * pieceHeight + Math.ceil(canvas.height / pieceHeight) - 1)
}
}
// 剩余块转换为ImageData数组
var imageDatas = [];
for (var y = 0; y < Math.floor(canvas.height / pieceHeight); y++) {
for (var x = 0; x < Math.floor(canvas.width / pieceWidth); x++) {
var imgData = ctxTemp.getImageData(x * pieceWidth, y * pieceHeight, pieceWidth, pieceHeight);
// imgToGray(imgData);
imageDatas.push(imgData);
}
}
// 从右下角开始识别
var maxDiffRatios = [];
var isHasPiece = {};
console.info("块数量:" + Math.floor(canvas.width / pieceWidth) + "," + Math.floor(canvas.height / pieceHeight));
for (var px = Math.floor(canvas.width / pieceWidth) - 1; px >= 0; px--) {
var bottomImageData = ctxTemp.getImageData(px * pieceWidth, Math.floor(canvas.height / pieceHeight) * pieceHeight, pieceWidth, canvas.height % pieceHeight);
for (var py = Math.floor(canvas.height / pieceHeight) - 1; py >= 0; py--) {
var rightImageData = ctxTemp.getImageData(Math.floor(canvas.width / pieceWidth) * pieceWidth, py * pieceHeight, canvas.width % pieceWidth, pieceHeight);
var rightWidth = canvas.width % pieceWidth;
if (px < Math.floor(canvas.width / pieceWidth) - 1) {
rightImageData = ctx.getImageData(px * pieceWidth + pieceWidth + px + 1, py * pieceHeight + py, pieceWidth, pieceHeight);
rightWidth = pieceWidth;
// console.info(px + "," + py+" "+(py * Math.floor(canvas.width / pieceWidth) + px + 1));
}
var diffRatios = [];
var maxDiffRatio = 256 * pieceWidth * pieceHeight;
var maxDiffRatioImageData;
var maxDiffRatioIndex = 0;
for (var i = 0; i < imageDatas.length; i++) {
var diffRatio1 = 2500
if (((px + 1) + "," + py) in isHasPiece || px == Math.floor(canvas.width / pieceWidth) - 1) {
diffRatio1 = getDiffRatio(imageDatas[i].data, pieceWidth, pieceHeight, rightImageData.data, rightWidth, pieceHeight, PieceType.PIECE_RIGHT);
}
var diffRatio2 = 2500
if ((px + "," + (py + 1)) in isHasPiece || py == Math.floor(canvas.height / pieceHeight) - 1) {
diffRatio2 = getDiffRatio(imageDatas[i].data, pieceWidth, pieceHeight, bottomImageData.data, pieceWidth, canvas.height % pieceHeight, PieceType.PIECE_BOTTOM);
}
var diffRatio = diffRatio1 + diffRatio2;
diffRatios.push([diffRatio, diffRatio1, diffRatio2]);
if (maxDiffRatio > diffRatio) {
maxDiffRatio = diffRatio;
maxDiffRatioImageData = imageDatas[i];
maxDiffRatioIndex = i;
}
}
if (px == 8 && py == 2) {
console.info(px + "," + py);
console.info(diffRatios);
console.info(maxDiffRatioIndex);
}
// 总差异超过5000则使用单边匹配方式
if (maxDiffRatio >= 5000) {
diffRatios = [];
maxDiffRatio = 256 * pieceWidth * pieceHeight;
for (var i = 0; i < imageDatas.length; i++) {
var diffRatio1 = 2500
if (((px + 1) + "," + py) in isHasPiece || px == Math.floor(canvas.width / pieceWidth) - 1) {
diffRatio1 = getDiffRatio(imageDatas[i].data, pieceWidth, pieceHeight, rightImageData.data, rightWidth, pieceHeight, PieceType.PIECE_RIGHT);
}
var diffRatio2 = 2500
if ((px + "," + (py + 1)) in isHasPiece || py == Math.floor(canvas.height / pieceHeight) - 1) {
diffRatio2 = getDiffRatio(imageDatas[i].data, pieceWidth, pieceHeight, bottomImageData.data, pieceWidth, canvas.height % pieceHeight, PieceType.PIECE_BOTTOM);
}
var diffRatio = diffRatio1 + diffRatio2;
diffRatios.push([diffRatio, diffRatio1, diffRatio2]);
if (maxDiffRatio > diffRatio1) {
maxDiffRatio = diffRatio1;
maxDiffRatioImageData = imageDatas[i];
maxDiffRatioIndex = i;
}
if (maxDiffRatio > diffRatio2) {
maxDiffRatio = diffRatio2;
maxDiffRatioImageData = imageDatas[i];
maxDiffRatioIndex = i;
}
}
}
// 差异超过3000则认为不匹配
// if (maxDiffRatio >= 5000) {
// bottomImageData = null;
// } else {
ctx.putImageData(maxDiffRatioImageData, px * pieceWidth + px, py * pieceHeight + py);
imageDatas.splice(maxDiffRatioIndex, 1);
bottomImageData = maxDiffRatioImageData;
isHasPiece[px + "," + py] = 1;
//}
maxDiffRatios.push(maxDiffRatio);
}
}
console.info(maxDiffRatios);
}, 0);
}
// 获取差异大小
function getDiffRatio(sImgData, sWidth, sHeight, dImgData, dWidth, dHeight, pieceType) {
var count = 0;
switch (pieceType) {
case PieceType.PIECE_LEFT:
for (var i = 1; i < sHeight - 2; i++) {
var s01 = i * sWidth * 4;
var s02 = s01 - sWidth * 4;
var s03 = s01 + sWidth * 4;
var s04 = s01 + 4;
var d01 = i * dWidth * 4 + dWidth * 4 - 4;
var d02 = d01 - sWidth * 4;
var d03 = d01 + sWidth * 4;
var d04 = d01 - 4;
var numbers = [];
numbers.push(Math.abs(dImgData[d01] - sImgData[s01]) + Math.abs(dImgData[d01 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d01 + 2] - sImgData[s01 + 2]));
numbers.push(Math.abs(dImgData[d02] - sImgData[s01]) + Math.abs(dImgData[d02 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d02 + 2] - sImgData[s01 + 2]));
numbers.push(Math.abs(dImgData[d03] - sImgData[s01]) + Math.abs(dImgData[d03 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d03 + 2] - sImgData[s01 + 2]));
var minNumber = Math.min.apply(Math, numbers);
count += numbers[0];
}
break;
case PieceType.PIECE_TOP:
for (var i = 1; i < sWidth - 2; i++) {
var s01 = i * 4;
var s02 = s01 - 4;
var s03 = s01 + 4;
var s04 = s01 + sWidth * 4;
var d01 = i * 4 + (dHeight - 1) * dWidth * 4;
var d02 = d01 - 4;
var d03 = d01 + 4;
var d04 = d01 - dWidth * 4;
var numbers = [];
numbers.push(Math.abs(dImgData[d01] - sImgData[s01]) + Math.abs(dImgData[d01 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d01 + 2] - sImgData[s01 + 2]));
numbers.push(Math.abs(dImgData[d02] - sImgData[s01]) + Math.abs(dImgData[d02 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d02 + 2] - sImgData[s01 + 2]));
numbers.push(Math.abs(dImgData[d03] - sImgData[s01]) + Math.abs(dImgData[d03 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d03 + 2] - sImgData[s01 + 2]));
var minNumber = Math.min.apply(Math, numbers);
count += numbers[0];
}
break;
case PieceType.PIECE_RIGHT:
for (var i = 1; i < sHeight - 2; i++) {
var s01 = i * sWidth * 4 + sWidth * 4 - 4;
var s02 = s01 - sWidth * 4;
var s03 = s01 + sWidth * 4;
var s04 = s01 - 4;
var d01 = i * dWidth * 4;
var d02 = d01 - dWidth * 4;
var d03 = d01 + dWidth * 4;
var d04 = d01 + 4;
var numbers = [];
numbers.push(Math.abs(dImgData[d01] - sImgData[s01]) + Math.abs(dImgData[d01 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d01 + 2] - sImgData[s01 + 2]));
numbers.push(Math.abs(dImgData[d02] - sImgData[s01]) + Math.abs(dImgData[d02 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d02 + 2] - sImgData[s01 + 2]));
numbers.push(Math.abs(dImgData[d03] - sImgData[s01]) + Math.abs(dImgData[d03 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d03 + 2] - sImgData[s01 + 2]));
var minNumber = Math.min.apply(Math, numbers);
count += numbers[0];
}
break;
case PieceType.PIECE_BOTTOM:
for (var i = 1; i < sWidth - 2; i++) {
var s01 = i * 4 + (sHeight - 1) * sWidth * 4;
var s02 = s01 - 4;
var s03 = s01 + 4;
var s04 = s01 - sWidth * 4;
var d01 = i * 4;
var d02 = d01 - 4;
var d03 = d01 + 4;
var d04 = d01 - dWidth * 4;
var numbers = [];
numbers.push(Math.abs(dImgData[d01] - sImgData[s01]) + Math.abs(dImgData[d01 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d01 + 2] - sImgData[s01 + 2]));
numbers.push(Math.abs(dImgData[d02] - sImgData[s01]) + Math.abs(dImgData[d02 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d02 + 2] - sImgData[s01 + 2]));
numbers.push(Math.abs(dImgData[d03] - sImgData[s01]) + Math.abs(dImgData[d03 + 1] - sImgData[s01 + 1]) + Math.abs(dImgData[d03 + 2] - sImgData[s01 + 2]));
var minNumber = Math.min.apply(Math, numbers);
count += numbers[0];
}
break;
}
return count;
}
var imageSave = document.getElementById('imageSave');
imageSave.onclick = function () {
// 判断是否已有图片
if (resultCanvas.width <= 0 || resultCanvas.height <= 0) {
alert("请先执行后再保存图片");
return;
}
// 去除中间空白
var canvasSave = document.createElement('canvas');
// var canvasSave = document.getElementById('imgSave');
var ctxSave = canvasSave.getContext('2d');
canvasSave.width = canvasTemp.width;
canvasSave.height = canvasTemp.height;
for (var px = 0; px < Math.ceil(canvasSave.width / pieceWidth); px++) {
for (var py = 0; py < Math.ceil(canvasSave.height / pieceHeight); py++) {
var newPieceImageData = resultCtx.getImageData(px * pieceWidth + px, py * pieceHeight + py, pieceWidth, pieceHeight);
ctxSave.putImageData(newPieceImageData, px * pieceWidth, py * pieceHeight);
}
}
// 保存图片
var MIME_TYPE = "image/jpeg";
var imgURL = canvasSave.toDataURL(MIME_TYPE);
var dlLink = document.createElement('a');
dlLink.download = formatDate(Date()) + ".jpg";
dlLink.href = imgURL;
dlLink.dataset.downloadurl = [MIME_TYPE, dlLink.download, dlLink.href].join(':');
document.body.appendChild(dlLink);
dlLink.click();
document.body.removeChild(dlLink);
}
var PieceType = {
PIECE_LEFT: 1,
PIECE_TOP: 2,
PIECE_RIGHT: 3,
PIECE_BOTTOM: 4
}
var formatDate = function (date) {
var date = new Date(date);
var y = date.getFullYear();
var m = date.getMonth() + 1;
m = m < 10 ? ('0' + m) : m;
var d = date.getDate();
d = d < 10 ? ('0' + d) : d;
var h = date.getHours();
var minute = date.getMinutes();
minute = minute < 10 ? ('0' + minute) : minute;
var second = date.getSeconds();
second = minute < 10 ? ('0' + second) : second;
return y + m + d + h + minute + second;
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment