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