fyne-widgets/pkg/multisyswebcam/multisyswebcam.go

137 lines
3.1 KiB
Go

package multisyswebcam
import (
"image"
"image/color"
"time"
"math/rand"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/widget"
"gocv.io/x/gocv"
)
var _ fyne.WidgetRenderer = (*multisysMultisysWebcamRenderer)(nil)
type WebcamSystem int64
const (
WebcamSystemDisabled WebcamSystem = iota
WebcamSystemGoCV
WebcamSystemWinAviCapDll
)
type MultisysWebcam struct {
widget.BaseWidget
System WebcamSystem
MultisysWebcamID int64
UpdateFPS int64
fpsTimer *time.Ticker
}
func NewMultisysWebcam() *MultisysWebcam {
w := &MultisysWebcam{}
w.ExtendBaseWidget(w)
w.MultisysWebcamID = 0
w.UpdateFPS = 25
w.System = WebcamSystemDisabled
return w
}
func (w *MultisysWebcam) Resize(s fyne.Size) {
w.BaseWidget.Resize(s)
}
func (w *MultisysWebcam) CreateRenderer() fyne.WidgetRenderer {
fpsTimer := time.NewTicker(time.Duration(1000/25) * time.Millisecond)
go func(w *MultisysWebcam) {
for {
_ = <-fpsTimer.C
if w != nil {
w.Refresh()
}
}
}(w)
return newMultisysWebcamRenderer(w)
}
func staticNoiseImage(w, h int) *image.RGBA {
i := image.NewRGBA(image.Rect(0, 0, w, h))
for x := 0; x < w; x++ {
for y := 0; y < h; y++ {
lum := uint8(rand.Float32() * 255)
i.Set(x, y, color.RGBA{lum, lum, lum, 255})
}
}
return i
}
func (w *MultisysWebcam) actualrenderframe(width, height int) image.Image {
switch w.System {
case WebcamSystemDisabled:
return staticNoiseImage(width,height)
case WebcamSystemGoCV:
gocvWebcam, _ := gocv.VideoCaptureDevice(int(w.MultisysWebcamID))
img := gocv.NewMat()
gocvWebcam.Read(&img)
frameImage, err := img.ToImage()
if err != nil {
frameImage = image.NewRGBA(image.Rect(0, 0, width, height))
}
return frameImage
}
return image.NewRGBA(image.Rect(0, 0, width, height))
}
func newMultisysWebcamRenderer(w *MultisysWebcam) *multisysMultisysWebcamRenderer {
renderer := &multisysMultisysWebcamRenderer{
multisysMultisysWebcam: w,
background: canvas.NewRectangle(color.RGBA{255, 0, 255, 255}),
}
renderer.currentframe = canvas.NewRaster(w.actualrenderframe)
return renderer
}
type multisysMultisysWebcamRenderer struct {
multisysMultisysWebcam *MultisysWebcam
background *canvas.Rectangle
currentframe *canvas.Raster
goCVVideoCapture *gocv.VideoCapture
}
func (r *multisysMultisysWebcamRenderer) Objects() []fyne.CanvasObject {
// The order is critical, rect is drawn first then currentframe
return []fyne.CanvasObject{r.background, r.currentframe}
}
func (r *multisysMultisysWebcamRenderer) Layout(s fyne.Size) {
r.background.Resize(s)
r.currentframe.Resize(s)
}
func (r *multisysMultisysWebcamRenderer) MinSize() fyne.Size {
return fyne.NewSize(200, 200)
}
func (r *multisysMultisysWebcamRenderer) Refresh() {
if r != nil {
if r.currentframe != nil {
r.currentframe.Refresh()
}
}
}
func (r *multisysMultisysWebcamRenderer) Destroy() {
if r.multisysMultisysWebcam != nil {
if r.multisysMultisysWebcam.fpsTimer != nil {
r.multisysMultisysWebcam.fpsTimer.Stop()
}
}
} // Called when the renderer is destroyed