Commit 01554976 by linjinhong

添加检测方法

parent b44635e8
......@@ -419,6 +419,116 @@ function applyPadding(bounds, padding, imgWidth, imgHeight) {
}
}
async function checkImageOutsideGrid() {
try {
// ===================== 第一步:获取 DOM 几何信息(核心!)=====================
// 1. 网格 DOM 信息(位置+尺寸,基于视口的绝对位置)
const lineDom = document.getElementById("line");
if (!lineDom) throw new Error("未找到网格元素(id=line)");
const lineRect = lineDom.getBoundingClientRect(); // 网格的位置+尺寸
const grid = {
left: lineRect.left, // 网格左边界(视口坐标)
top: lineRect.top, // 网格上边界(视口坐标)
right: lineRect.right, // 网格右边界
bottom: lineRect.bottom, // 网格下边界
width: lineRect.width, // 网格宽度
height: lineRect.height, // 网格高度
};
if (grid.width === 0 || grid.height === 0)
throw new Error("网格尺寸为0,请确认网格已渲染");
// 2. 图片 DOM 信息(位置+尺寸+原始尺寸)
const imgDom = document.getElementById("imgBox");
if (!imgDom || !imgDom.complete)
throw new Error("图片未加载完成或未找到imgBox元素");
const imgRect = imgDom.getBoundingClientRect(); // 图片的位置+尺寸(视口坐标)
const imgDisplayInfo = {
left: imgRect.left, // 图片左边界(视口坐标)
top: imgRect.top, // 图片上边界(视口坐标)
width: imgRect.width, // 图片显示宽度(页面渲染尺寸)
height: imgRect.height, // 图片显示高度(页面渲染尺寸)
naturalWidth: imgDom.naturalWidth, // 图片原始宽度
naturalHeight: imgDom.naturalHeight, // 图片原始高度
};
if (imgDisplayInfo.width === 0 || imgDisplayInfo.height === 0)
throw new Error("图片显示尺寸为0");
// ===================== 第二步:Sharp 读取图片原始像素 =====================
// 1. 处理图片 URL(Electron 中兼容本地/远程图片)
let imgSource = imgDom.src;
// 本地图片:转换为绝对路径(sharp 支持本地路径)
if (imgSource.startsWith("file://")) {
imgSource = new URL(imgSource).pathname;
// Windows 路径兼容
if (process.platform === "win32") {
imgSource = imgSource.slice(1); // 去掉开头的 /
}
}
// 2. Sharp 读取图片并获取原始像素(RGBA 格式)
const sharpImg = sharp(imgSource);
const imgMetadata = await sharpImg.metadata(); // 获取图片元信息
const { data: pixels } = await sharpImg
.raw() // 转为原始像素 Buffer(RGBA,每个像素4字节)
.toBuffer({ resolveWithObject: true }); // 返回像素 Buffer + 信息
// ===================== 第三步:坐标映射 + 像素检测 =====================
// 1. 计算缩放比例:原始像素 → 页面显示坐标
const scaleX = imgDisplayInfo.width / imgDisplayInfo.naturalWidth; // 水平缩放比
const scaleY = imgDisplayInfo.height / imgDisplayInfo.naturalHeight; // 垂直缩放比
// 2. 遍历像素检测(步长=1,测试阶段;正式可改为2/4优化性能)
let hasOutsideValidPixel = false;
const alphaThreshold = 1; // 有效像素阈值(Alpha > 1 即为有效)
const imgNaturalWidth = imgMetadata.width;
const imgNaturalHeight = imgMetadata.height;
for (let y = 0; y < imgNaturalHeight; y++) {
if (hasOutsideValidPixel) break; // 找到有效像素后终止遍历
for (let x = 0; x < imgNaturalWidth; x++) {
// a. 原始像素 → 页面显示坐标(图片在视口中的绝对位置)
const imgDisplayX = imgDisplayInfo.left + x * scaleX;
const imgDisplayY = imgDisplayInfo.top + y * scaleY;
// b. 判断当前像素是否超出网格边界
const isOutside =
imgDisplayX < grid.left || // 超出网格左边界
imgDisplayX > grid.right || // 超出网格右边界
imgDisplayY < grid.top || // 超出网格上边界
imgDisplayY > grid.bottom; // 超出网格下边界
if (isOutside) {
// c. 获取当前像素的 Alpha 值(RGBA 的第4个字节)
const pixelIndex = (y * imgNaturalWidth + x) * 4;
const alpha = pixels[pixelIndex + 3]; // Alpha 通道(0-255)
// d. 检测有效像素
if (alpha > alphaThreshold) {
hasOutsideValidPixel = true;
console.log(
`找到超出网格的有效像素:原始坐标(${x},${y}) → 页面坐标(${imgDisplayX.toFixed(
2,
)},${imgDisplayY.toFixed(2)}) → Alpha=${alpha}`,
);
break; // 终止内层循环
}
}
}
}
// ===================== 第四步:返回结果 =====================
console.log(
"检测结果:",
hasOutsideValidPixel ? "超出网格有有效像素" : "超出网格无有效像素",
);
return hasOutsideValidPixel;
} catch (error) {
console.error("图片超出网格检测失败:", error);
alert(`检测失败:${error.message}`);
return false;
}
}
// 分区边界检测实现
module.exports = {
......@@ -426,4 +536,5 @@ module.exports = {
cropImageTransparentEdges,
processImages,
cropImage,
checkImageOutsideGrid,
};
......@@ -5,7 +5,7 @@ import ImgSetting from "./imgSetting.vue";
import bus from "@/bus";
import PrintDialog from "@/views/design/head/printDialog.vue";
import { mmToPx, extractValue } from "@/utils";
const { checkImageOutsideGrid } = require("../../../server/utils/setImage");
const path = require("path");
const fs = require("fs");
const uuid = require("uuid");
......@@ -220,6 +220,8 @@ export default {
localeData: getOrderInfoMap(),
faceType: "",
expandStatus: {},
detectResult: null, // 检测结果
imgNaturalSize: { width: 0, height: 0 }, // 图片原始尺寸
};
},
watch: {
......@@ -1265,6 +1267,15 @@ export default {
// 自动保留 Value 内部的所有 key,美化缩进
return JSON.stringify(data, null, 2);
},
async checkOutsidePixel() {
const bool = await checkImageOutsideGrid();
console.log(bool);
},
onImageLoad(e) {
this.imgNaturalSize.width = e.target.naturalWidth;
this.imgNaturalSize.height = e.target.naturalHeight;
console.log("图片原始尺寸:", this.imgNaturalSize);
},
},
mounted() {
this.imgHeight = window.screen.height + "px";
......@@ -1753,12 +1764,14 @@ export default {
class="sucaitu-img img element"
>
<img
ref="targetImg"
crossOrigin="anonymous"
:src="item.url"
id="imgBox"
alt=""
style="width: 100%;height: 100%"
class="sucaitu-img"
@load="onImageLoad"
/>
<i
......@@ -1772,6 +1785,17 @@ export default {
></div>
</div>
</vue-drag-resize-rotate>
<div style="position: relative;">
<button @click="checkOutsidePixel" class="detect-btn">
检测超出区域是否有像素
</button>
<div class="result" v-if="detectResult !== null">
检测结果:{{ detectResult ? "有" : "无" }}
</div>
</div>
<!-- 隐藏的Canvas(用于像素检测) -->
<canvas ref="pixelCanvas" style="display: none"></canvas>
</div>
<div
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment