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