// ============================================================================ // screenshot.go — 屏幕截图 // // 截取全部或指定显示器,多屏拼接为一张图,返回 PNG base64 data URI。 // ============================================================================ package main import ( "bytes" "encoding/base64" "fmt" "image" "image/png" "github.com/kbinani/screenshot" ) // captureScreen 截取整个主屏幕(或指定显示器),返回 PNG 的 base64 数据 URI。 // displayIndex 为显示器索引,-1 表示全部屏幕拼接;越界自动回退主屏。 func captureScreen(displayIndex int) (string, error) { n := screenshot.NumActiveDisplays() if n <= 0 { return "", fmt.Errorf("未检测到可用显示器") } bounds := image.Rect(0, 0, 0, 0) if displayIndex >= 0 && displayIndex < n { bounds = screenshot.GetDisplayBounds(displayIndex) } else { // 全部屏幕拼接:合并所有显示器的边界 for i := 0; i < n; i++ { b := screenshot.GetDisplayBounds(i) if b.Min.X < bounds.Min.X { bounds.Min.X = b.Min.X } if b.Min.Y < bounds.Min.Y { bounds.Min.Y = b.Min.Y } if b.Max.X > bounds.Max.X { bounds.Max.X = b.Max.X } if b.Max.Y > bounds.Max.Y { bounds.Max.Y = b.Max.Y } } } if bounds.Dx() <= 0 || bounds.Dy() <= 0 { return "", fmt.Errorf("显示器尺寸无效") } img, err := screenshot.CaptureRect(bounds) if err != nil { return "", fmt.Errorf("截屏失败: %w", err) } var buf bytes.Buffer if err := png.Encode(&buf, img); err != nil { return "", fmt.Errorf("编码 PNG 失败: %w", err) } return "data:image/png;base64," + base64.StdEncoding.EncodeToString(buf.Bytes()), nil }