dc4bc/qr/qr.go

102 lines
2.1 KiB
Go
Raw Normal View History

2020-07-22 04:53:06 -07:00
package qr
import (
"fmt"
2020-07-30 08:09:13 -07:00
"image"
2020-07-22 05:56:31 -07:00
"log"
2020-07-22 04:53:06 -07:00
"time"
2020-09-02 09:02:44 -07:00
"gocv.io/x/gocv"
2020-07-30 04:23:09 -07:00
encoder "github.com/skip2/go-qrcode"
2020-07-22 04:53:06 -07:00
"github.com/makiuchi-d/gozxing"
"github.com/makiuchi-d/gozxing/qrcode"
)
2020-08-04 00:45:32 -07:00
const (
timeToScan = time.Second * 5
)
2020-07-22 04:53:06 -07:00
2020-07-30 04:23:09 -07:00
type Processor interface {
2020-07-30 04:27:47 -07:00
ReadQR() ([]byte, error)
2020-07-30 04:23:09 -07:00
WriteQR(path string, data []byte) error
}
type CameraProcessor struct{}
func NewCameraProcessor() *CameraProcessor {
return &CameraProcessor{}
}
2020-07-30 04:27:47 -07:00
func (p *CameraProcessor) ReadQR() ([]byte, error) {
2020-07-22 04:53:06 -07:00
webcam, err := gocv.OpenVideoCapture(0)
if err != nil {
2020-07-29 06:20:39 -07:00
return nil, fmt.Errorf("failed to OpenVideoCapture: %w", err)
2020-07-22 04:53:06 -07:00
}
window := gocv.NewWindow("Please, show a qr code")
2020-07-22 04:53:06 -07:00
2020-07-22 05:56:31 -07:00
defer func() {
if err := webcam.Close(); err != nil {
log.Fatalf("failed to close camera: %v", err)
}
}()
defer func() {
if err := window.Close(); err != nil {
log.Fatalf("failed to close camera window: %v", err)
}
}()
2020-07-22 04:53:06 -07:00
img := gocv.NewMat()
2020-09-10 07:31:53 -07:00
defer img.Close()
2020-07-22 04:53:06 -07:00
for {
webcam.Read(&img)
window.IMShow(img)
window.WaitKey(1)
2020-07-22 04:53:06 -07:00
imgObject, err := img.ToImage()
if err != nil {
return nil, fmt.Errorf("failed to get image object: %w", err)
}
data, err := ReadDataFromQR(imgObject)
if err != nil {
if _, ok := err.(gozxing.NotFoundException); ok {
continue
}
return nil, err
}
return data, nil
2020-07-22 04:53:06 -07:00
}
}
2020-07-30 04:23:09 -07:00
func (p *CameraProcessor) WriteQR(path string, data []byte) error {
err := encoder.WriteFile(string(data), encoder.Medium, 512, path)
if err != nil {
return fmt.Errorf("failed to encode the data: %w", err)
}
return nil
}
2020-07-30 08:09:13 -07:00
2020-07-31 07:55:47 -07:00
func ReadDataFromQR(img image.Image) ([]byte, error) {
2020-07-30 08:09:13 -07:00
bmp, err := gozxing.NewBinaryBitmapFromImage(img)
if err != nil {
return nil, fmt.Errorf("failed to get NewBinaryBitmapFromImage: %w", err)
}
qrReader := qrcode.NewQRCodeReader()
2020-07-31 07:55:47 -07:00
result, err := qrReader.Decode(bmp, nil)
if err != nil {
if _, ok := err.(gozxing.NotFoundException); ok {
return nil, err
}
2020-07-31 07:55:47 -07:00
return nil, fmt.Errorf("failed to decode the QR-code contents: %w", err)
}
2020-09-01 08:06:37 -07:00
return []byte(result.String()), nil
2020-07-31 07:55:47 -07:00
}
func EncodeQR(data []byte) ([]byte, error) {
return encoder.Encode(string(data), encoder.Medium, 512)
2020-07-30 08:09:13 -07:00
}