83 lines
1.9 KiB
Go
83 lines
1.9 KiB
Go
//go:build windows || linux || darwin
|
|
|
|
package utils
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"image"
|
|
"image/jpeg"
|
|
|
|
"github.com/kbinani/screenshot"
|
|
)
|
|
|
|
// CaptureScreenshot captures the primary display.
|
|
func CaptureScreenshot(quality int) ([]byte, int, int, error) {
|
|
if quality <= 0 || quality > 100 {
|
|
quality = 75
|
|
}
|
|
|
|
n := screenshot.NumActiveDisplays()
|
|
if n == 0 {
|
|
return nil, 0, 0, fmt.Errorf("no active display found")
|
|
}
|
|
|
|
bounds := screenshot.GetDisplayBounds(0)
|
|
if bounds.Empty() {
|
|
return nil, 0, 0, fmt.Errorf("failed to get display bounds")
|
|
}
|
|
|
|
img, err := screenshot.CaptureRect(bounds)
|
|
if err != nil {
|
|
return nil, 0, 0, fmt.Errorf("capture screen: %w", err)
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
opts := &jpeg.Options{Quality: quality}
|
|
if err := jpeg.Encode(&buf, img, opts); err != nil {
|
|
return nil, 0, 0, fmt.Errorf("encode jpeg: %w", err)
|
|
}
|
|
|
|
return buf.Bytes(), bounds.Dx(), bounds.Dy(), nil
|
|
}
|
|
|
|
// CaptureAllScreens captures all active displays and stitches them together.
|
|
func CaptureAllScreens(quality int) ([]byte, int, int, error) {
|
|
if quality <= 0 || quality > 100 {
|
|
quality = 75
|
|
}
|
|
|
|
n := screenshot.NumActiveDisplays()
|
|
if n == 0 {
|
|
return nil, 0, 0, fmt.Errorf("no active display found")
|
|
}
|
|
|
|
var totalBounds image.Rectangle
|
|
for i := 0; i < n; i++ {
|
|
bounds := screenshot.GetDisplayBounds(i)
|
|
totalBounds = totalBounds.Union(bounds)
|
|
}
|
|
|
|
totalImg := image.NewRGBA(totalBounds)
|
|
for i := 0; i < n; i++ {
|
|
bounds := screenshot.GetDisplayBounds(i)
|
|
img, err := screenshot.CaptureRect(bounds)
|
|
if err != nil {
|
|
continue
|
|
}
|
|
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
|
|
for x := bounds.Min.X; x < bounds.Max.X; x++ {
|
|
totalImg.Set(x, y, img.At(x-bounds.Min.X, y-bounds.Min.Y))
|
|
}
|
|
}
|
|
}
|
|
|
|
var buf bytes.Buffer
|
|
opts := &jpeg.Options{Quality: quality}
|
|
if err := jpeg.Encode(&buf, totalImg, opts); err != nil {
|
|
return nil, 0, 0, fmt.Errorf("encode jpeg: %w", err)
|
|
}
|
|
|
|
return buf.Bytes(), totalBounds.Dx(), totalBounds.Dy(), nil
|
|
}
|