mirror of https://github.com/certusone/dc4bc.git
Merge pull request #3 from p2p-org/feat/qr
feat: added QR code functionality
This commit is contained in:
commit
c2deca547e
|
@ -0,0 +1,15 @@
|
|||
module p2p.org/dc4bc
|
||||
|
||||
go 1.13
|
||||
|
||||
require (
|
||||
github.com/makiuchi-d/gozxing v0.0.0-20190830103442-eaff64b1ceb7
|
||||
github.com/mattn/go-gtk v0.0.0-20191030024613-af2e013261f5
|
||||
github.com/mattn/go-pointer v0.0.0-20190911064623-a0a44394634f // indirect
|
||||
github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
|
||||
github.com/stretchr/testify v1.6.1 // indirect
|
||||
gocv.io/x/gocv v0.23.0
|
||||
golang.org/x/image v0.0.0-20200618115811-c13761719519
|
||||
golang.org/x/text v0.3.3 // indirect
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect
|
||||
)
|
|
@ -0,0 +1,56 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
_ "image/jpeg"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"p2p.org/dc4bc/qr"
|
||||
|
||||
_ "image/gif"
|
||||
_ "image/png"
|
||||
|
||||
_ "golang.org/x/image/bmp"
|
||||
_ "golang.org/x/image/tiff"
|
||||
_ "golang.org/x/image/webp"
|
||||
)
|
||||
|
||||
func main() {
|
||||
clearTerminal()
|
||||
var data = "Hello, world!"
|
||||
|
||||
log.Println("A QR code will be shown on your screen.")
|
||||
log.Println("Please take a photo of the QR code with your smartphone.")
|
||||
log.Println("When you close the image, you will have 5 seconds to" +
|
||||
"scan the QR code with your laptop's camera.")
|
||||
err := qr.ShowQR(data)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to show QR code: %v", err)
|
||||
}
|
||||
|
||||
var scannedData string
|
||||
for {
|
||||
clearTerminal()
|
||||
if err != nil {
|
||||
log.Printf("Failed to scan QR code: %v\n", err)
|
||||
}
|
||||
|
||||
log.Println("Please center the photo of the QR-code in front" +
|
||||
"of your web-camera...")
|
||||
|
||||
scannedData, err = qr.ReadQRFromCamera()
|
||||
if err == nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
clearTerminal()
|
||||
log.Printf("QR code successfully scanned; the data is: %s\n", scannedData)
|
||||
}
|
||||
|
||||
func clearTerminal() {
|
||||
c := exec.Command("clear")
|
||||
c.Stdout = os.Stdout
|
||||
_ = c.Run()
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package qr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/makiuchi-d/gozxing"
|
||||
"github.com/makiuchi-d/gozxing/qrcode"
|
||||
"gocv.io/x/gocv"
|
||||
)
|
||||
|
||||
const timeToScan = time.Second * 5
|
||||
|
||||
func ReadQRFromCamera() (string, error) {
|
||||
webcam, err := gocv.OpenVideoCapture(0)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to OpenVideoCapture: %w", err)
|
||||
}
|
||||
window := gocv.NewWindow("Hello")
|
||||
|
||||
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)
|
||||
}
|
||||
}()
|
||||
|
||||
img := gocv.NewMat()
|
||||
tk := time.NewTimer(timeToScan)
|
||||
|
||||
// This loop reads an image from the webcam every millisecond
|
||||
// for 5 seconds. The last image taken will be used as the final
|
||||
//one.
|
||||
loop:
|
||||
for {
|
||||
select {
|
||||
case <-tk.C:
|
||||
break loop
|
||||
default:
|
||||
webcam.Read(&img)
|
||||
window.IMShow(img)
|
||||
window.WaitKey(1)
|
||||
}
|
||||
}
|
||||
|
||||
imgObject, err := img.ToImage()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get image object: %w", err)
|
||||
}
|
||||
|
||||
bmp, err := gozxing.NewBinaryBitmapFromImage(imgObject)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to get NewBinaryBitmapFromImage: %w", err)
|
||||
}
|
||||
|
||||
qrReader := qrcode.NewQRCodeReader()
|
||||
result, err := qrReader.Decode(bmp, nil)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("failed to decode the QR-code contents: %w", err)
|
||||
}
|
||||
|
||||
return result.String(), err
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
package qr
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
_ "image/gif"
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"os"
|
||||
|
||||
"github.com/mattn/go-gtk/glib"
|
||||
"github.com/mattn/go-gtk/gtk"
|
||||
|
||||
encoder "github.com/skip2/go-qrcode"
|
||||
|
||||
_ "golang.org/x/image/bmp"
|
||||
_ "golang.org/x/image/tiff"
|
||||
)
|
||||
|
||||
const tmpImageFile = "/tmp/qr.png"
|
||||
|
||||
func ShowQR(data string) error {
|
||||
defer func() {
|
||||
_ = os.Remove(tmpImageFile)
|
||||
}()
|
||||
|
||||
err := encoder.WriteFile(data, encoder.Medium, 512, tmpImageFile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to encode the data: %w", err)
|
||||
}
|
||||
|
||||
showImage(tmpImageFile)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func showImage(imageFile string) {
|
||||
gtk.Init(nil)
|
||||
window := gtk.NewWindow(gtk.WINDOW_TOPLEVEL)
|
||||
window.SetPosition(gtk.WIN_POS_CENTER)
|
||||
window.SetTitle("p2p.org QR Viewer")
|
||||
window.SetIconName("p2p.org QR Viewer")
|
||||
window.Connect("destroy", func(ctx *glib.CallbackContext) {
|
||||
gtk.MainQuit()
|
||||
})
|
||||
|
||||
hbox := gtk.NewHBox(false, 1)
|
||||
hpaned := gtk.NewHPaned()
|
||||
hbox.Add(hpaned)
|
||||
frame1 := gtk.NewFrame("QR Code")
|
||||
framebox1 := gtk.NewHBox(false, 1)
|
||||
frame1.Add(framebox1)
|
||||
hpaned.Pack1(frame1, false, false)
|
||||
image := gtk.NewImageFromFile(imageFile)
|
||||
framebox1.Add(image)
|
||||
window.Add(hbox)
|
||||
imagePixBuffer := image.GetPixbuf()
|
||||
horizontalSize := imagePixBuffer.GetWidth()
|
||||
verticalSize := imagePixBuffer.GetHeight()
|
||||
|
||||
window.SetSizeRequest(horizontalSize, verticalSize)
|
||||
window.ShowAll()
|
||||
gtk.Main()
|
||||
}
|
Loading…
Reference in New Issue