Change image library

This commit is contained in:
Milan Nikolic
2025-06-12 21:58:20 +02:00
parent 074d14ad01
commit 948fe29079
7 changed files with 37 additions and 38 deletions

View File

@@ -1,5 +1,4 @@
//go:build android //go:build android
// +build android
// Package camera. // Package camera.
package camera package camera
@@ -241,7 +240,7 @@ func New(opts Options) (camera *Camera, err error) {
camera.img = image.NewYCbCr(image.Rect(0, 0, int(opts.Width), int(opts.Height)), image.YCbCrSubsampleRatio420) camera.img = image.NewYCbCr(image.Rect(0, 0, int(opts.Width), int(opts.Height)), image.YCbCrSubsampleRatio420)
ret := C.openCamera(C.int(opts.Index), C.int(opts.Width), C.int(opts.Height)) ret := C.openCamera(C.int(opts.Index), C.int(opts.Width), C.int(opts.Height))
if bool(int(ret) != 0) { if int(ret) != 0 {
err = fmt.Errorf("camera: can not open camera %d: error %d", opts.Index, int(ret)) err = fmt.Errorf("camera: can not open camera %d: error %d", opts.Index, int(ret))
return return
} }
@@ -252,13 +251,15 @@ func New(opts Options) (camera *Camera, err error) {
// Read reads next frame from camera and returns image. // Read reads next frame from camera and returns image.
func (c *Camera) Read() (img image.Image, err error) { func (c *Camera) Read() (img image.Image, err error) {
ret := C.captureCamera() ret := C.captureCamera()
if bool(int(ret) != 0) { if int(ret) != 0 {
err = fmt.Errorf("camera: can not grab frame: error %d", int(ret)) err = fmt.Errorf("camera: can not grab frame: error %d", int(ret))
return return
} }
if C.image == nil { if C.image == nil {
err = fmt.Errorf("camera: can not retrieve frame") err = fmt.Errorf("camera: can not retrieve frame")
return return
} }
@@ -295,8 +296,9 @@ func (c *Camera) SetProperty(id int, value float64) {
// Close closes camera. // Close closes camera.
func (c *Camera) Close() (err error) { func (c *Camera) Close() (err error) {
ret := C.closeCamera() ret := C.closeCamera()
if bool(int(ret) != 0) { if int(ret) != 0 {
err = fmt.Errorf("camera: can not close camera %d: error %d", c.opts.Index, int(ret)) err = fmt.Errorf("camera: can not close camera %d: error %d", c.opts.Index, int(ret))
return return
} }

View File

@@ -10,7 +10,7 @@ import (
"image/draw" "image/draw"
"time" "time"
"github.com/disintegration/imaging" "github.com/anthonynsimon/bild/transform"
"github.com/korandiz/v4l" "github.com/korandiz/v4l"
"github.com/korandiz/v4l/fmt/mjpeg" "github.com/korandiz/v4l/fmt/mjpeg"
"github.com/pbnjay/pixfont" "github.com/pbnjay/pixfont"
@@ -102,11 +102,11 @@ func (c *Camera) Read() (img image.Image, err error) {
switch c.opts.Rotate { switch c.opts.Rotate {
case 90: case 90:
img = imaging.Rotate90(img) img = transform.Rotate(img, 90, &transform.RotationOptions{ResizeBounds: true})
case 180: case 180:
img = imaging.Rotate180(img) img = transform.Rotate(img, 180, &transform.RotationOptions{ResizeBounds: true})
case 270: case 270:
img = imaging.Rotate270(img) img = transform.Rotate(img, 270, &transform.RotationOptions{ResizeBounds: true})
} }
if c.opts.Timestamp { if c.opts.Timestamp {
@@ -131,7 +131,7 @@ func (c *Camera) GetProperty(id int) float64 {
// SetProperty sets a camera property. // SetProperty sets a camera property.
func (c *Camera) SetProperty(id int, value float64) { func (c *Camera) SetProperty(id int, value float64) {
c.camera.SetControl(uint32(id), int32(value)) _ = c.camera.SetControl(uint32(id), int32(value))
} }
// Close closes camera. // Close closes camera.

View File

@@ -10,7 +10,7 @@ import (
"image/draw" "image/draw"
"time" "time"
"github.com/disintegration/imaging" "github.com/anthonynsimon/bild/transform"
"github.com/pbnjay/pixfont" "github.com/pbnjay/pixfont"
"gocv.io/x/gocv" "gocv.io/x/gocv"
) )
@@ -105,11 +105,11 @@ func (c *Camera) Read() (img image.Image, err error) {
switch c.opts.Rotate { switch c.opts.Rotate {
case 90: case 90:
img = imaging.Rotate90(img) img = transform.Rotate(img, 90, &transform.RotationOptions{ResizeBounds: true})
case 180: case 180:
img = imaging.Rotate180(img) img = transform.Rotate(img, 180, &transform.RotationOptions{ResizeBounds: true})
case 270: case 270:
img = imaging.Rotate270(img) img = transform.Rotate(img, 270, &transform.RotationOptions{ResizeBounds: true})
} }
if c.opts.Timestamp { if c.opts.Timestamp {

View File

@@ -3,7 +3,6 @@ package camera
import ( import (
"fmt" "fmt"
"image/jpeg" "image/jpeg"
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"testing" "testing"
@@ -18,15 +17,15 @@ func TestCamera(t *testing.T) {
defer camera.Close() defer camera.Close()
tmpdir, err := ioutil.TempDir(os.TempDir(), "cam2ip") tmpdir, err := os.MkdirTemp(os.TempDir(), "cam2ip*")
if err != nil { if err != nil {
t.Error(err) t.Error(err)
} }
defer os.RemoveAll(tmpdir) defer os.RemoveAll(tmpdir)
var i int var i int64
var n int = 10 var n = 10
timeout := time.After(time.Duration(n) * time.Second) timeout := time.After(time.Duration(n) * time.Second)

View File

@@ -9,14 +9,19 @@ import (
"image" "image"
"image/color" "image/color"
"image/draw" "image/draw"
"runtime"
"syscall" "syscall"
"time" "time"
"unsafe" "unsafe"
"github.com/disintegration/imaging" "github.com/anthonynsimon/bild/transform"
"github.com/pbnjay/pixfont" "github.com/pbnjay/pixfont"
) )
func init() {
runtime.LockOSThread()
}
// Camera represents camera. // Camera represents camera.
type Camera struct { type Camera struct {
opts Options opts Options
@@ -44,7 +49,7 @@ func New(opts Options) (camera *Camera, err error) {
fn := func(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) uintptr { fn := func(hwnd syscall.Handle, msg uint32, wparam, lparam uintptr) uintptr {
switch msg { switch msg {
case wmClose: case wmClose:
destroyWindow(hwnd) _ = destroyWindow(hwnd)
case wmDestroy: case wmDestroy:
postQuitMessage(0) postQuitMessage(0)
default: default:
@@ -71,7 +76,7 @@ func New(opts Options) (camera *Camera, err error) {
} }
ret := sendMessage(c.camera, wmCapDriverConnect, uintptr(c.opts.Index), 0) ret := sendMessage(c.camera, wmCapDriverConnect, uintptr(c.opts.Index), 0)
if bool(int(ret) == 0) { if int(ret) == 0 {
err = fmt.Errorf("camera: can not open camera %d", c.opts.Index) err = fmt.Errorf("camera: can not open camera %d", c.opts.Index)
return return
} }
@@ -84,7 +89,7 @@ func New(opts Options) (camera *Camera, err error) {
bi.BmiHeader.BiHeight = int32(c.opts.Height) bi.BmiHeader.BiHeight = int32(c.opts.Height)
ret = sendMessage(c.camera, wmCapSetVideoformat, size, uintptr(unsafe.Pointer(&bi))) ret = sendMessage(c.camera, wmCapSetVideoformat, size, uintptr(unsafe.Pointer(&bi)))
if bool(int(ret) == 0) { if int(ret) == 0 {
err = fmt.Errorf("camera: can not set video format") err = fmt.Errorf("camera: can not set video format")
return return
} }
@@ -136,11 +141,11 @@ func (c *Camera) Read() (img image.Image, err error) {
switch c.opts.Rotate { switch c.opts.Rotate {
case 90: case 90:
img = imaging.Rotate90(img) img = transform.Rotate(img, 90, &transform.RotationOptions{ResizeBounds: true})
case 180: case 180:
img = imaging.Rotate180(img) img = transform.Rotate(img, 180, &transform.RotationOptions{ResizeBounds: true})
case 270: case 270:
img = imaging.Rotate270(img) img = transform.Rotate(img, 270, &transform.RotationOptions{ResizeBounds: true})
} }
if c.opts.Timestamp { if c.opts.Timestamp {
@@ -172,13 +177,14 @@ func (c *Camera) Close() (err error) {
sendMessage(c.camera, wmCapSetCallbackFrame, 0, 0) sendMessage(c.camera, wmCapSetCallbackFrame, 0, 0)
unregisterClass(c.className, c.instance) unregisterClass(c.className, c.instance)
sendMessage(c.camera, wmCapDriverDisconnect, 0, 0) sendMessage(c.camera, wmCapDriverDisconnect, 0, 0)
destroyWindow(c.camera)
return return destroyWindow(c.camera)
} }
// callback function. // callback function.
func (c *Camera) callback(hwvd syscall.Handle, hdr *videoHdr) uintptr { func (c *Camera) callback(hwnd syscall.Handle, hdr *videoHdr) uintptr {
c.hdr = hdr c.hdr = hdr
return 0 return 0
} }

4
go.mod
View File

@@ -2,10 +2,9 @@ module github.com/gen2brain/cam2ip
require ( require (
github.com/abbot/go-http-auth v0.4.0 github.com/abbot/go-http-auth v0.4.0
github.com/anthonynsimon/bild v0.14.0
github.com/antonini/golibjpegturbo v0.0.0-20141208033414-c03a2fa1e89a github.com/antonini/golibjpegturbo v0.0.0-20141208033414-c03a2fa1e89a
github.com/disintegration/imaging v1.6.2
github.com/gen2brain/base64 v0.0.0-20221015184129-317a5c93030c github.com/gen2brain/base64 v0.0.0-20221015184129-317a5c93030c
github.com/gen2brain/go-opencv v0.0.0-20191005190506-bf186fc94f7a
github.com/jamiealquiza/envy v1.1.0 github.com/jamiealquiza/envy v1.1.0
github.com/korandiz/v4l v1.1.0 github.com/korandiz/v4l v1.1.0
github.com/pbnjay/pixfont v0.0.0-20200714042608-33b744692567 github.com/pbnjay/pixfont v0.0.0-20200714042608-33b744692567
@@ -18,7 +17,6 @@ require (
github.com/spf13/cobra v1.8.0 // indirect github.com/spf13/cobra v1.8.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/crypto v0.18.0 // indirect golang.org/x/crypto v0.18.0 // indirect
golang.org/x/image v0.15.0 // indirect
golang.org/x/net v0.20.0 // indirect golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect golang.org/x/sys v0.16.0 // indirect
) )

10
go.sum
View File

@@ -1,14 +1,12 @@
github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0= github.com/abbot/go-http-auth v0.4.0 h1:QjmvZ5gSC7jm3Zg54DqWE/T5m1t2AfDu6QlXJT0EVT0=
github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM= github.com/abbot/go-http-auth v0.4.0/go.mod h1:Cz6ARTIzApMJDzh5bRMSUou6UMSp0IEXg9km/ci7TJM=
github.com/anthonynsimon/bild v0.14.0 h1:IFRkmKdNdqmexXHfEU7rPlAmdUZ8BDZEGtGHDnGWync=
github.com/anthonynsimon/bild v0.14.0/go.mod h1:hcvEAyBjTW69qkKJTfpcDQ83sSZHxwOunsseDfeQhUs=
github.com/antonini/golibjpegturbo v0.0.0-20141208033414-c03a2fa1e89a h1:+Q4qlzO9KeavJSvWgRKckT3ViTSQ8rR6GroSiXPRXhs= github.com/antonini/golibjpegturbo v0.0.0-20141208033414-c03a2fa1e89a h1:+Q4qlzO9KeavJSvWgRKckT3ViTSQ8rR6GroSiXPRXhs=
github.com/antonini/golibjpegturbo v0.0.0-20141208033414-c03a2fa1e89a/go.mod h1:UOX4aiVZ5WVUBY3D/31H4m6Z8UHgBj5Qr/oldRBBUMY= github.com/antonini/golibjpegturbo v0.0.0-20141208033414-c03a2fa1e89a/go.mod h1:UOX4aiVZ5WVUBY3D/31H4m6Z8UHgBj5Qr/oldRBBUMY=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/disintegration/imaging v1.6.2 h1:w1LecBlG2Lnp8B3jk5zSuNqd7b4DXhcjwek1ei82L+c=
github.com/disintegration/imaging v1.6.2/go.mod h1:44/5580QXChDfwIclfc/PCwrr44amcmDAg8hxG0Ewe4=
github.com/gen2brain/base64 v0.0.0-20221015184129-317a5c93030c h1:TUjjeJ2rV4KZxH6hIEi/boEQB3v6aKvwdakUJR3AwiE= github.com/gen2brain/base64 v0.0.0-20221015184129-317a5c93030c h1:TUjjeJ2rV4KZxH6hIEi/boEQB3v6aKvwdakUJR3AwiE=
github.com/gen2brain/base64 v0.0.0-20221015184129-317a5c93030c/go.mod h1:VG58IUyxPWojCtGwqwoZ/6LLXwClu1tssqa5ktOxI9o= github.com/gen2brain/base64 v0.0.0-20221015184129-317a5c93030c/go.mod h1:VG58IUyxPWojCtGwqwoZ/6LLXwClu1tssqa5ktOxI9o=
github.com/gen2brain/go-opencv v0.0.0-20191005190506-bf186fc94f7a h1:0arrt5Ke40opD5glNdh9ltrkZ0jaqPWsquGPSE3ukug=
github.com/gen2brain/go-opencv v0.0.0-20191005190506-bf186fc94f7a/go.mod h1:pOLh42huXUuMoJWvD2K+EeXzvQ9GZ5HN6gdFk5ZwIuU=
github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs= github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@@ -28,14 +26,10 @@ gocv.io/x/gocv v0.35.0 h1:Qaxb5KdVyy8Spl4S4K0SMZ6CVmKtbfoSGQAxRD3FZlw=
gocv.io/x/gocv v0.35.0/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU= gocv.io/x/gocv v0.35.0/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc= golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg= golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.15.0 h1:kOELfmgrmJlw4Cdb7g/QGuB3CvDrXbqEIww/pNtNBm8=
golang.org/x/image v0.15.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo= golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY= golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU= golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q= nhooyr.io/websocket v1.8.10 h1:mv4p+MnGrLDcPlBoWsvPP7XCzTYMXP9F9eIGoKbgx7Q=