fyne-widgets/pkg/gocvwebcam/gocvwebcam.go

93 lines
2.1 KiB
Go

package gocvwebcam
import (
"image"
"image/color"
"time"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/canvas"
"fyne.io/fyne/v2/widget"
"gocv.io/x/gocv"
)
var _ fyne.WidgetRenderer = (*gocvGocvWebcamRenderer)(nil)
type GocvWebcam struct {
widget.BaseWidget
GocvWebcamID int64
UpdateFPS int64
fpsTimer *time.Ticker
}
func NewGocvWebcam() *GocvWebcam {
w := &GocvWebcam{}
w.ExtendBaseWidget(w)
w.GocvWebcamID = 0
w.UpdateFPS = 25
return w
}
func (w *GocvWebcam) Resize(s fyne.Size) {
w.BaseWidget.Resize(s)
}
func (w *GocvWebcam) CreateRenderer() fyne.WidgetRenderer {
fpsTimer := time.NewTicker(time.Duration(1000/25) * time.Millisecond)
go func(w *GocvWebcam) {
for {
_ = <-fpsTimer.C
w.Refresh()
}
}(w)
return newGocvWebcamRenderer(w)
}
type gocvGocvWebcamRenderer struct {
gocvGocvWebcam *GocvWebcam
background *canvas.Rectangle
currentframe *canvas.Raster
goCVVideoCapture *gocv.VideoCapture
}
func (r *gocvGocvWebcamRenderer) actualrenderframe(w, h int) image.Image {
gocvGocvWebcam, _ := gocv.VideoCaptureDevice(int(r.gocvGocvWebcam.GocvWebcamID))
img := gocv.NewMat()
gocvGocvWebcam.Read(&img)
frameImage, _ := img.ToImage() //no point doing anything other than returning anyway!
return frameImage
}
func newGocvWebcamRenderer(w *GocvWebcam) *gocvGocvWebcamRenderer {
renderer := &gocvGocvWebcamRenderer{
gocvGocvWebcam: w,
background: canvas.NewRectangle(color.RGBA{255, 0, 255, 255}),
}
renderer.currentframe = canvas.NewRaster(renderer.actualrenderframe)
return renderer
}
func (r *gocvGocvWebcamRenderer) Objects() []fyne.CanvasObject {
// The order is critical, rect is drawn first then currentframe
return []fyne.CanvasObject{r.background, r.currentframe}
}
func (r *gocvGocvWebcamRenderer) Layout(s fyne.Size) {
r.background.Resize(s)
r.currentframe.Resize(s)
}
func (r *gocvGocvWebcamRenderer) MinSize() fyne.Size {
return fyne.NewSize(200, 200)
}
func (r *gocvGocvWebcamRenderer) Refresh() {
r.currentframe.Refresh()
}
func (r *gocvGocvWebcamRenderer) Destroy() {
r.gocvGocvWebcam.fpsTimer.Stop()
} // Called when the renderer is destroyed