diff --git a/camera/camera.go b/camera/camera.go index c97b1ad..3e3e062 100644 --- a/camera/camera.go +++ b/camera/camera.go @@ -1,6 +1,6 @@ package camera -// Options. +// Options . type Options struct { Index int Rotate int diff --git a/camera/camera_android.go b/camera/camera_android.go index a862a60..db643a0 100644 --- a/camera/camera_android.go +++ b/camera/camera_android.go @@ -32,7 +32,7 @@ ACaptureSessionOutput *captureSessionOutput; ACaptureSessionOutputContainer *captureSessionOutputContainer; void device_on_disconnected(void *context, ACameraDevice *device) { - LOGI("camera %s is diconnected.\n", ACameraDevice_getId(device)); + LOGI("camera %s is disconnected.\n", ACameraDevice_getId(device)); } void device_on_error(void *context, ACameraDevice *device, int error) { @@ -242,6 +242,7 @@ func New(opts Options) (camera *Camera, err error) { ret := C.openCamera(C.int(opts.Index), C.int(opts.Width), C.int(opts.Height)) if int(ret) != 0 { err = fmt.Errorf("camera: can not open camera %d: error %d", opts.Index, int(ret)) + return } @@ -253,7 +254,7 @@ func (c *Camera) Read() (img image.Image, err error) { ret := C.captureCamera() if int(ret) != 0 { err = fmt.Errorf("camera: can not grab frame: error %d", int(ret)) - + return } diff --git a/camera/camera_linux.go b/camera/camera_linux.go index 51fba1f..410a44c 100644 --- a/camera/camera_linux.go +++ b/camera/camera_linux.go @@ -6,14 +6,9 @@ package camera import ( "fmt" "image" - "image/color" - "image/draw" - "time" - "github.com/anthonynsimon/bild/transform" "github.com/korandiz/v4l" "github.com/korandiz/v4l/fmt/mjpeg" - "github.com/pbnjay/pixfont" im "github.com/gen2brain/cam2ip/image" ) @@ -46,23 +41,27 @@ func New(opts Options) (camera *Camera, err error) { 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()) + err = fmt.Errorf("camera: %w", err) + 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()) + err = fmt.Errorf("camera: %w", err) + return } @@ -72,13 +71,15 @@ func New(opts Options) (camera *Camera, err error) { err = camera.camera.SetConfig(config) if err != nil { - err = fmt.Errorf("camera: %s", err.Error()) + err = fmt.Errorf("camera: %w", err) + return } err = camera.camera.TurnOn() if err != nil { - err = fmt.Errorf("camera: %s", err.Error()) + err = fmt.Errorf("camera: %w", err) + return } @@ -87,37 +88,26 @@ func New(opts Options) (camera *Camera, err error) { // 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()) + err = fmt.Errorf("camera: can not grab frame: %w", err) + return } img, err = im.NewDecoder(buffer).Decode() if err != nil { - err = fmt.Errorf("camera: %s", err.Error()) + err = fmt.Errorf("camera: %w", err) + return } - switch c.opts.Rotate { - case 90: - img = transform.Rotate(img, 90, &transform.RotationOptions{ResizeBounds: true}) - case 180: - img = transform.Rotate(img, 180, &transform.RotationOptions{ResizeBounds: true}) - case 270: - img = transform.Rotate(img, 270, &transform.RotationOptions{ResizeBounds: true}) + if c.opts.Rotate != 0 { + img = im.Rotate(img, c.opts.Rotate) } 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 + img, err = im.Timestamp(img, "") } return @@ -126,6 +116,7 @@ func (c *Camera) Read() (img image.Image, err error) { // GetProperty returns the specified camera property. func (c *Camera) GetProperty(id int) float64 { ret, _ := c.camera.GetControl(uint32(id)) + return float64(ret) } @@ -138,12 +129,13 @@ func (c *Camera) SetProperty(id int, value float64) { 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 } diff --git a/camera/camera_opencv.go b/camera/camera_opencv.go index b757b23..6cc7902 100644 --- a/camera/camera_opencv.go +++ b/camera/camera_opencv.go @@ -1,4 +1,4 @@ -//go:build opencv +//go:build opencv && !android // Package camera. package camera @@ -6,13 +6,10 @@ package camera import ( "fmt" "image" - "image/color" - "image/draw" - "time" - "github.com/anthonynsimon/bild/transform" - "github.com/pbnjay/pixfont" "gocv.io/x/gocv" + + im "github.com/gen2brain/cam2ip/image" ) // Property identifiers. @@ -75,7 +72,7 @@ func New(opts Options) (camera *Camera, err error) { camera.camera, err = gocv.VideoCaptureDevice(opts.Index) if err != nil { - err = fmt.Errorf("camera: can not open camera %d: %s", opts.Index, err.Error()) + err = fmt.Errorf("camera: can not open camera %d: %w", opts.Index, err) } camera.SetProperty(PropFrameWidth, opts.Width) @@ -92,9 +89,9 @@ func (c *Camera) Read() (img image.Image, err error) { return } - img, e := c.frame.ToImage() - if e != nil { - err = fmt.Errorf("camera: %v", e) + img, err = c.frame.ToImage() + if err != nil { + err = fmt.Errorf("camera: %w", err) return } @@ -103,24 +100,12 @@ func (c *Camera) Read() (img image.Image, err error) { return } - switch c.opts.Rotate { - case 90: - img = transform.Rotate(img, 90, &transform.RotationOptions{ResizeBounds: true}) - case 180: - img = transform.Rotate(img, 180, &transform.RotationOptions{ResizeBounds: true}) - case 270: - img = transform.Rotate(img, 270, &transform.RotationOptions{ResizeBounds: true}) + if c.opts.Rotate != 0 { + img = im.Rotate(img, c.opts.Rotate) } 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 + img, err = im.Timestamp(img, "") } return @@ -140,11 +125,19 @@ func (c *Camera) SetProperty(id int, value float64) { func (c *Camera) Close() (err error) { if c.camera == nil { err = fmt.Errorf("camera: camera is not opened") + + return + } + + err = c.frame.Close() + if err != nil { + err = fmt.Errorf("camera: %w", err) + return } - c.frame.Close() err = c.camera.Close() c.camera = nil + return } diff --git a/camera/camera_windows.go b/camera/camera_windows.go index c0a40ad..587308c 100644 --- a/camera/camera_windows.go +++ b/camera/camera_windows.go @@ -7,15 +7,11 @@ import ( "bytes" "fmt" "image" - "image/color" - "image/draw" "runtime" "syscall" - "time" "unsafe" - "github.com/anthonynsimon/bild/transform" - "github.com/pbnjay/pixfont" + im "github.com/gen2brain/cam2ip/image" ) func init() { @@ -105,7 +101,7 @@ func New(opts Options) (camera *Camera, err error) { // Read reads next frame from camera and returns image. func (c *Camera) Read() (img image.Image, err error) { ret := sendMessage(c.camera, wmCapGrabFrameNoStop, 0, 0) - if bool(int(ret) == 0) { + if int(ret) == 0 { err = fmt.Errorf("camera: can not grab frame") return } @@ -123,7 +119,7 @@ func (c *Camera) Read() (img image.Image, err error) { for y := height - 1; y >= 0; y-- { _, err = r.Read(b) if err != nil { - err = fmt.Errorf("camera: can not retrieve frame: %v", err) + err = fmt.Errorf("camera: can not retrieve frame: %w", err) return } @@ -139,24 +135,12 @@ func (c *Camera) Read() (img image.Image, err error) { img = c.frame - switch c.opts.Rotate { - case 90: - img = transform.Rotate(img, 90, &transform.RotationOptions{ResizeBounds: true}) - case 180: - img = transform.Rotate(img, 180, &transform.RotationOptions{ResizeBounds: true}) - case 270: - img = transform.Rotate(img, 270, &transform.RotationOptions{ResizeBounds: true}) + if c.opts.Rotate != 0 { + img = im.Rotate(img, c.opts.Rotate) } 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 + img, err = im.Timestamp(img, "") } return diff --git a/image/image.go b/image/image.go new file mode 100644 index 0000000..ca91f73 --- /dev/null +++ b/image/image.go @@ -0,0 +1,40 @@ +package image + +import ( + "fmt" + "image" + "image/color" + "image/draw" + "time" + + "github.com/anthonynsimon/bild/transform" + "github.com/pbnjay/pixfont" +) + +func Rotate(img image.Image, angle int) image.Image { + switch angle { + case 90: + img = transform.Rotate(img, 90, &transform.RotationOptions{ResizeBounds: true}) + case 180: + img = transform.Rotate(img, 180, &transform.RotationOptions{ResizeBounds: true}) + case 270: + img = transform.Rotate(img, 270, &transform.RotationOptions{ResizeBounds: true}) + } + + return img +} + +func Timestamp(img image.Image, format string) (image.Image, error) { + if format == "" { + format = "2006-01-02 15:04:05" + } + + dimg, ok := img.(draw.Image) + if !ok { + return img, fmt.Errorf("camera: %T is not a drawable image type", img) + } + + pixfont.DrawString(dimg, 10, 10, time.Now().Format(format), color.White) + + return dimg, nil +}