平铺元素ui更改
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
<template>
|
||||
<div class="test" ref="testRef">
|
||||
<!-- <div class="canvas-container">
|
||||
<div class="canvas-container">
|
||||
<canvas id="canvas"></canvas>
|
||||
</div> -->
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -35,53 +35,104 @@
|
||||
canvas1.height = height;
|
||||
const ctx1 = canvas1.getContext("2d");
|
||||
ctx1.drawImage(image, 0, 0, width, height);
|
||||
const data = ctx1.getImageData(0, 0, width, height);
|
||||
testRef.value.appendChild(canvas1);
|
||||
const testData = test(data);
|
||||
const canvas2 = document.createElement("canvas");
|
||||
canvas2.width = width;
|
||||
canvas2.height = height;
|
||||
const ctx2 = canvas2.getContext("2d");
|
||||
ctx2.putImageData(testData, 0, 0);
|
||||
testRef.value.appendChild(canvas2);
|
||||
const arr = traceImageContour(canvas1);
|
||||
const str = arr.map((v) => `${v.x} ${v.y}`).join(" L ");
|
||||
const path = new fabric.Path(`M ${str} z`);
|
||||
path.set({
|
||||
fill: "rgba(127, 255, 127, 0.3)",
|
||||
stroke: "#2AA81B",
|
||||
strokeWidth: 2,
|
||||
strokeDashArray: [8, 4],
|
||||
strokeLineCap: "round",// 折线端点样式
|
||||
strokeLineJoin: "bevel", // 折线连接样式
|
||||
strokeUniform: true, // 保持描边宽度不随缩放改变
|
||||
});
|
||||
canvas.add(path);
|
||||
};
|
||||
});
|
||||
// 获取图片轮廓点位
|
||||
function test(data) {
|
||||
// 找过的点位
|
||||
const visited = [];
|
||||
// 轮廓点位
|
||||
const contours = [];
|
||||
const { width, height } = data;
|
||||
function cd(x, y) {
|
||||
const arr = [
|
||||
[x, y], // 当前
|
||||
[x, y - 1], // 上
|
||||
[x + 1, y], // 右
|
||||
[x, y + 1], // 下
|
||||
[x - 1, y], // 左
|
||||
];
|
||||
for (let i = 0; i < arr.length; i++) {
|
||||
let [x1, y1] = arr[i];
|
||||
if (x1 < 0 || x1 >= width || y1 < 0 || y1 >= height) continue;
|
||||
let key = `${x1},${y1}`;
|
||||
if (visited.includes(key)) continue;
|
||||
visited.push(key);
|
||||
let index = (y1 * width + x1) * 4;
|
||||
let r = data.data[index];
|
||||
let g = data.data[index + 1];
|
||||
let b = data.data[index + 2];
|
||||
let a = data.data[index + 3];
|
||||
if ((r || g || b) && a) {
|
||||
contours.push({ x: x1, y: y1 });
|
||||
} else {
|
||||
if (i > 0) cd(x1, y1);
|
||||
// 边界追踪
|
||||
function traceImageContour(canvas) {
|
||||
const ctx = canvas.getContext("2d");
|
||||
const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
const data = imageData.data;
|
||||
const width = canvas.width;
|
||||
const height = canvas.height;
|
||||
|
||||
// 查找起始点(第一个不透明像素)
|
||||
let startX = -1;
|
||||
let startY = -1;
|
||||
|
||||
outer: for (let y = 0; y < height; y++) {
|
||||
for (let x = 0; x < width; x++) {
|
||||
const index = (y * width + x) * 4;
|
||||
if (data[index + 3] > 0) {
|
||||
startX = x;
|
||||
startY = y;
|
||||
break outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
cd(0, 0);
|
||||
console.log(contours);
|
||||
return data;
|
||||
|
||||
if (startX === -1) return []; // 没有不透明像素
|
||||
|
||||
// Moore-Neighbor边界跟踪算法
|
||||
const contour = [];
|
||||
const visited = new Set();
|
||||
const directions = [
|
||||
[-1, 0],
|
||||
[-1, -1],
|
||||
[0, -1],
|
||||
[1, -1],
|
||||
[1, 0],
|
||||
[1, 1],
|
||||
[0, 1],
|
||||
[-1, 1],
|
||||
];
|
||||
|
||||
let currentX = startX;
|
||||
let currentY = startY;
|
||||
let backtrackDir = 4; // 起始方向:右
|
||||
|
||||
do {
|
||||
const pointKey = `${currentX},${currentY}`;
|
||||
if (!visited.has(pointKey)) {
|
||||
contour.push({ x: currentX, y: currentY });
|
||||
visited.add(pointKey);
|
||||
}
|
||||
|
||||
// 从右方向开始顺时针查找
|
||||
let found = false;
|
||||
for (let i = 0; i < 8; i++) {
|
||||
const dir = (backtrackDir + i) % 8;
|
||||
const dx = directions[dir][0];
|
||||
const dy = directions[dir][1];
|
||||
const checkX = currentX + dx;
|
||||
const checkY = currentY + dy;
|
||||
|
||||
if (
|
||||
checkX >= 0 &&
|
||||
checkX < width &&
|
||||
checkY >= 0 &&
|
||||
checkY < height
|
||||
) {
|
||||
const index = (checkY * width + checkX) * 4;
|
||||
if (data[index + 3] > 0) {
|
||||
currentX = checkX;
|
||||
currentY = checkY;
|
||||
backtrackDir = (dir + 5) % 8; // 下一个开始查找的方向
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) break;
|
||||
} while (
|
||||
!(currentX === startX && currentY === startY) &&
|
||||
visited.size < width * height
|
||||
);
|
||||
|
||||
return contour;
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user