优化代码

This commit is contained in:
hero920103 committed 2026-10-28 08:47:09 +08:00
1 parent 3553790475
commit eda7e8bc96
23 files changed
+3113 -342

No files matched your search

+118
View File
@@ -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)
}