优化代码
This commit is contained in:
1 parent
3553790475
commit
eda7e8bc96
23 files changed
+3113
-342
No files matched your search
@@ -0,0 +1,118 @@
|
||||
//go:build windows
|
||||
|
||||
package win32_test
|
||||
|
||||
import (
|
||||
"image"
|
||||
"image/png"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"viewsagent/internal/capture"
|
||||
"viewsagent/internal/win32"
|
||||
)
|
||||
|
||||
// TestFrameVisibleButNotCaptured 验证取景框的两个关键性质:
|
||||
// 1. 它确实显示在屏幕上(截屏能看到红框);
|
||||
// 2. 打开"排除截屏"后,它不会被抓屏录进去(模型看到的画面里没有红框)。
|
||||
//
|
||||
// 这是个需要桌面会话的集成测试,默认跳过:
|
||||
//
|
||||
// VIEWSAGENT_UI_TEST=1 go test ./internal/win32/ -run Frame
|
||||
func TestFrameVisibleButNotCaptured(t *testing.T) {
|
||||
if os.Getenv("VIEWSAGENT_UI_TEST") == "" {
|
||||
t.Skip("需要桌面会话,设置 VIEWSAGENT_UI_TEST=1 后运行")
|
||||
}
|
||||
|
||||
f, err := win32.NewFrame()
|
||||
if err != nil {
|
||||
t.Skipf("无法创建取景框窗口(可能没有桌面会话): %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
region := capture.Region{X: 120, Y: 120, W: 420, H: 300}
|
||||
f.SetRegion(win32.Rect{
|
||||
Left: region.X, Top: region.Y,
|
||||
Right: region.X + region.W, Bottom: region.Y + region.H,
|
||||
})
|
||||
time.Sleep(400 * time.Millisecond)
|
||||
|
||||
// 关闭排除:截屏里应该能看到红框,说明它真的贴在屏幕上。
|
||||
f.SetCaptureExclusion(false)
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
visible := grabRegion(t, region)
|
||||
saveShot(t, "frame-visible.png", visible)
|
||||
if n := countRedInBorder(visible, 3); n == 0 {
|
||||
t.Fatal("取景框没有出现在屏幕上:关掉排除后截屏里也找不到红线")
|
||||
} else {
|
||||
t.Logf("边框窄带里有 %d 个红像素,取景框已显示在屏幕上", n)
|
||||
}
|
||||
|
||||
// 打开排除:截屏里不应再有红线。
|
||||
f.SetCaptureExclusion(true)
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
hidden := grabRegion(t, region)
|
||||
saveShot(t, "frame-excluded.png", hidden)
|
||||
if n := countRedInBorder(hidden, 3); n != 0 {
|
||||
t.Fatalf("取景框被录进截屏了,边框窄带里有 %d 个红像素", n)
|
||||
}
|
||||
t.Log("取景框已被排除在截屏之外")
|
||||
}
|
||||
|
||||
// grabRegion 抓取一块屏幕区域。
|
||||
func grabRegion(t *testing.T, r capture.Region) image.Image {
|
||||
t.Helper()
|
||||
img, err := (capture.Screen{}).Grab(r)
|
||||
if err != nil {
|
||||
t.Fatalf("抓屏失败: %v", err)
|
||||
}
|
||||
return img
|
||||
}
|
||||
|
||||
// countRedInBorder 只统计区域四边 band 像素宽的窄带里的红色像素。
|
||||
// 取景框只画在这一圈上,这样不会把页面里本来就有的红色(图标之类)算进来。
|
||||
func countRedInBorder(img image.Image, band int) int {
|
||||
b := img.Bounds()
|
||||
isRed := func(x, y int) bool {
|
||||
r, g, bl, _ := img.At(x, y).RGBA()
|
||||
return r > 0xB000 && g < 0x5000 && bl < 0x5000
|
||||
}
|
||||
n := 0
|
||||
for y := b.Min.Y; y < b.Max.Y; y++ {
|
||||
for x := b.Min.X; x < b.Max.X; x++ {
|
||||
nearEdge := x < b.Min.X+band || x >= b.Max.X-band ||
|
||||
y < b.Min.Y+band || y >= b.Max.Y-band
|
||||
if nearEdge && isRed(x, y) {
|
||||
n++
|
||||
}
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// saveShot 把截图写到 VIEWSAGENT_FRAME_SHOT_DIR 指定的目录,方便肉眼核对。
|
||||
func saveShot(t *testing.T, name string, img image.Image) {
|
||||
t.Helper()
|
||||
dir := os.Getenv("VIEWSAGENT_FRAME_SHOT_DIR")
|
||||
if dir == "" {
|
||||
return
|
||||
}
|
||||
if err := os.MkdirAll(dir, 0o755); err != nil {
|
||||
t.Logf("创建截图目录失败: %v", err)
|
||||
return
|
||||
}
|
||||
path := filepath.Join(dir, name)
|
||||
f, err := os.Create(path)
|
||||
if err != nil {
|
||||
t.Logf("创建截图文件失败: %v", err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
if err := png.Encode(f, img); err != nil {
|
||||
t.Logf("写入截图失败: %v", err)
|
||||
return
|
||||
}
|
||||
t.Logf("截图已保存: %s", path)
|
||||
}
|
||||
Reference in new issue
Block a user