Webcam with working ticker

This commit is contained in:
Martyn 2021-12-12 01:12:03 +01:00
parent 899918e85d
commit d1b78ca038
2 changed files with 147 additions and 0 deletions

50
examples/webcam/main.go Normal file
View File

@ -0,0 +1,50 @@
package main
import (
"strconv"
"fyne.io/fyne/v2"
"fyne.io/fyne/v2/app"
"fyne.io/fyne/v2/container"
"fyne.io/fyne/v2/widget"
"git.martyn.berlin/martyn/fyne-widgets/pkg/layouts"
"git.martyn.berlin/martyn/fyne-widgets/pkg/webcam"
)
var webcamID int
var webcamLabel *widget.Label
var webcamWidget *webcam.Webcam
func switchWebcam(id int) {
webcamLabel.Text = "Webcam: " + strconv.Itoa(id)
webcamLabel.Refresh()
webcamWidget.WebcamID = int64(id)
webcamWidget.Refresh()
}
func incWebCamID() {
webcamID = webcamID + 1
switchWebcam(webcamID)
}
func decWebCamID() {
webcamID = webcamID - 1
switchWebcam(webcamID)
}
func main() {
a := app.New()
w := a.NewWindow("Webcam")
webcamWidget = webcam.NewWebcam()
layout := layouts.NewFloatingControlsLayout()
layout.FloatingControlsLocation = layouts.FloatingControlsCenter
webcamID = 0
webcamLabel = widget.NewLabel("Webcam: 0")
buttons := container.NewHBox(webcamLabel, widget.NewButton("-", decWebCamID), widget.NewButton("+", incWebCamID))
w.SetContent(container.New(&layout, webcamWidget, buttons))
w.Resize(fyne.NewSize(640, 480))
w.ShowAndRun()
}

97
pkg/webcam/webcam.go Normal file
View File

@ -0,0 +1,97 @@
package webcam
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 = (*webcamRenderer)(nil)
type Webcam struct {
widget.BaseWidget
WebcamID int64
UpdateFPS int64
fpsTimer *time.Ticker
}
func NewWebcam() *Webcam {
w := &Webcam{}
w.ExtendBaseWidget(w)
w.WebcamID = 0
w.UpdateFPS = 25
return w
}
func (w *Webcam) Resize(s fyne.Size) {
w.BaseWidget.Resize(s)
}
func (w *Webcam) CreateRenderer() fyne.WidgetRenderer {
fpsTimer := time.NewTicker(time.Duration(1000/25) * time.Millisecond)
go func(w *Webcam) {
for {
_ = <-fpsTimer.C
w.Refresh()
}
}(w)
return newWebcamRenderer(w)
}
type webcamRenderer struct {
webcam *Webcam
background *canvas.Rectangle
currentframe *canvas.Raster
goCVVideoCapture *gocv.VideoCapture
}
func renderframe(w, h int) image.Image {
frameImage := image.NewRGBA(image.Rect(0, 0, w, h))
return frameImage
}
func (r *webcamRenderer) actualrenderframe(w, h int) image.Image {
webcam, _ := gocv.VideoCaptureDevice(int(r.webcam.WebcamID))
img := gocv.NewMat()
webcam.Read(&img)
frameImage, _ := img.ToImage() //no point doing anything other than returning anyway!
return frameImage
}
func newWebcamRenderer(w *Webcam) *webcamRenderer {
renderer := &webcamRenderer{
webcam: w,
background: canvas.NewRectangle(color.RGBA{255, 0, 255, 255}),
}
renderer.currentframe = canvas.NewRaster(renderer.actualrenderframe)
return renderer
}
func (r *webcamRenderer) Objects() []fyne.CanvasObject {
// The order is critical, rect is drawn first then currentframe
return []fyne.CanvasObject{r.background, r.currentframe}
}
func (r *webcamRenderer) Layout(s fyne.Size) {
r.background.Resize(s)
r.currentframe.Resize(s)
}
func (r *webcamRenderer) MinSize() fyne.Size {
return fyne.NewSize(200, 200)
}
func (r *webcamRenderer) Refresh() {
r.currentframe.Refresh()
}
func (r *webcamRenderer) Destroy() {
r.webcam.fpsTimer.Stop()
} // Called when the renderer is destroyed