137 lines
3.1 KiB
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
|