1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
// +build !cv2,!cv4
// Package camera.
package camera
import (
"fmt"
"image"
"image/color"
"image/draw"
"time"
"github.com/disintegration/imaging"
"github.com/korandiz/v4l"
"github.com/korandiz/v4l/fmt/mjpeg"
"github.com/pbnjay/pixfont"
im "github.com/gen2brain/cam2ip/image"
)
// Camera represents camera.
type Camera struct {
opts Options
camera *v4l.Device
}
// New returns new Camera for given camera index.
func New(opts Options) (camera *Camera, err error) {
camera = &Camera{}
camera.opts = opts
devices := v4l.FindDevices()
if len(devices) < opts.Index+1 {
err = fmt.Errorf("camera: no camera at index %d", opts.Index)
return
}
camera.camera, err = v4l.Open(devices[opts.Index].Path)
if err != nil {
err = fmt.Errorf("camera: %s", err.Error())
return
}
if camera.camera == nil {
err = fmt.Errorf("camera: can not open camera %d", opts.Index)
return
}
config, err := camera.camera.GetConfig()
if err != nil {
err = fmt.Errorf("camera: %s", err.Error())
return
}
config.Format = mjpeg.FourCC
config.Width = int(opts.Width)
config.Height = int(opts.Height)
err = camera.camera.SetConfig(config)
if err != nil {
err = fmt.Errorf("camera: %s", err.Error())
return
}
err = camera.camera.TurnOn()
if err != nil {
err = fmt.Errorf("camera: %s", err.Error())
return
}
return
}
// Read reads next frame from camera and returns image.
func (c *Camera) Read() (img image.Image, err error) {
buffer, err := c.camera.Capture()
if err != nil {
err = fmt.Errorf("camera: can not grab frame: %s", err.Error())
return
}
img, err = im.NewDecoder(buffer).Decode()
if err != nil {
err = fmt.Errorf("camera: %s", err.Error())
return
}
switch c.opts.Rotate {
case 90:
img = imaging.Rotate90(img)
case 180:
img = imaging.Rotate180(img)
case 270:
img = imaging.Rotate270(img)
}
if c.opts.Timestamp {
dimg, ok := img.(draw.Image)
if !ok {
err = fmt.Errorf("camera: %T is not a drawable image type", img)
return
}
pixfont.DrawString(dimg, 10, 10, time.Now().Format("2006-01-02 15:04:05"), color.White)
img = dimg
}
return
}
// GetProperty returns the specified camera property.
func (c *Camera) GetProperty(id int) float64 {
ret, _ := c.camera.GetControl(uint32(id))
return float64(ret)
}
// SetProperty sets a camera property.
func (c *Camera) SetProperty(id int, value float64) {
c.camera.SetControl(uint32(id), int32(value))
}
// Close closes camera.
func (c *Camera) Close() (err error) {
if c.camera == nil {
err = fmt.Errorf("camera: camera is not opened")
return
}
c.camera.TurnOff()
c.camera.Close()
c.camera = nil
return
}
|