Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
electron-printer
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
zhuzhequan
electron-printer
Commits
01554976
Commit
01554976
authored
Mar 10, 2026
by
linjinhong
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
添加检测方法
parent
b44635e8
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
136 additions
and
1 deletions
+136
-1
src/server/utils/setImage.js
+111
-0
src/views/design/main/index.vue
+25
-1
No files found.
src/server/utils/setImage.js
View file @
01554976
...
@@ -419,6 +419,116 @@ function applyPadding(bounds, padding, imgWidth, imgHeight) {
...
@@ -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
=
{
module
.
exports
=
{
...
@@ -426,4 +536,5 @@ module.exports = {
...
@@ -426,4 +536,5 @@ module.exports = {
cropImageTransparentEdges
,
cropImageTransparentEdges
,
processImages
,
processImages
,
cropImage
,
cropImage
,
checkImageOutsideGrid
,
};
};
src/views/design/main/index.vue
View file @
01554976
...
@@ -5,7 +5,7 @@ import ImgSetting from "./imgSetting.vue";
...
@@ -5,7 +5,7 @@ import ImgSetting from "./imgSetting.vue";
import
bus
from
"@/bus"
;
import
bus
from
"@/bus"
;
import
PrintDialog
from
"@/views/design/head/printDialog.vue"
;
import
PrintDialog
from
"@/views/design/head/printDialog.vue"
;
import
{
mmToPx
,
extractValue
}
from
"@/utils"
;
import
{
mmToPx
,
extractValue
}
from
"@/utils"
;
const
{
checkImageOutsideGrid
}
=
require
(
"../../../server/utils/setImage"
);
const
path
=
require
(
"path"
);
const
path
=
require
(
"path"
);
const
fs
=
require
(
"fs"
);
const
fs
=
require
(
"fs"
);
const
uuid
=
require
(
"uuid"
);
const
uuid
=
require
(
"uuid"
);
...
@@ -220,6 +220,8 @@ export default {
...
@@ -220,6 +220,8 @@ export default {
localeData
:
getOrderInfoMap
(),
localeData
:
getOrderInfoMap
(),
faceType
:
""
,
faceType
:
""
,
expandStatus
:
{},
expandStatus
:
{},
detectResult
:
null
,
// 检测结果
imgNaturalSize
:
{
width
:
0
,
height
:
0
},
// 图片原始尺寸
};
};
},
},
watch
:
{
watch
:
{
...
@@ -1265,6 +1267,15 @@ export default {
...
@@ -1265,6 +1267,15 @@ export default {
// 自动保留 Value 内部的所有 key,美化缩进
// 自动保留 Value 内部的所有 key,美化缩进
return
JSON
.
stringify
(
data
,
null
,
2
);
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
()
{
mounted
()
{
this
.
imgHeight
=
window
.
screen
.
height
+
"px"
;
this
.
imgHeight
=
window
.
screen
.
height
+
"px"
;
...
@@ -1753,12 +1764,14 @@ export default {
...
@@ -1753,12 +1764,14 @@ export default {
class=
"sucaitu-img img element"
class=
"sucaitu-img img element"
>
>
<img
<img
ref=
"targetImg"
crossOrigin=
"anonymous"
crossOrigin=
"anonymous"
:src=
"item.url"
:src=
"item.url"
id=
"imgBox"
id=
"imgBox"
alt=
""
alt=
""
style=
"width: 100%;height: 100%"
style=
"width: 100%;height: 100%"
class=
"sucaitu-img"
class=
"sucaitu-img"
@
load=
"onImageLoad"
/>
/>
<i
<i
...
@@ -1772,6 +1785,17 @@ export default {
...
@@ -1772,6 +1785,17 @@ export default {
></div>
></div>
</div>
</div>
</vue-drag-resize-rotate>
</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>
<div
<div
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment