Signup/Sign In

Scan or generate QR code with Go language

In this tutorial, we will create a program in Golang which can read an image file as input and write the text to standard output.

What exactly is QR code?

QR code or Quick Response code is a type of matrix or two dimensional (2D) barcode developed in 1994 that can be read easily by a digital machine/device, such as a cell phone, and which stores information as a series of pixels in a square-shaped grid.

Follow these steps to write a program which could read and generate QR code purely with Go language:

Make sure you have installed Golang and properly set up the environment variable. Check out Golang installation tutorial here.

1. Start by creating a file main.go and import the required Golang packages:

  • fmt - To print extracted html comments.
  • os - To read HTML files from standard input (stdin)
  • image - Read an image file.
  • io/ioutil - impliments package input output utility functions.
  • bytes - manipulation of byte slices
  • image/png - write encoded QR code to a PNG image binary file.
  • github.com/boombuler/barcode - a barcode creation library. (here used to scale the code.)
  • github.com/boombuler/barcode/qr - a qr code creation library
  • github.com/liyue201/goqr - QR Code recognition and decoding
package main

import (
	"image/png"
	"os"
	"image"
	"io/ioutil"
	"bytes"
	"fmt"

	// github. com liyue201 GOQR
	"github.com/liyue201/goqr"
	// barcode scale 
	"github.com/boombuler/barcode"
	// Build the QRcode for the text
	"github.com/boombuler/barcode/qr"
)

2. Generate QR code from text with Go language

Import required packages.

import (
	"image/png"
	"os"
	
	// barcode scale 
	"github.com/boombuler/barcode"
	// Build the QRcode for the text
	"github.com/boombuler/barcode/qr"
)

Let's create a function which generates QR code for given string and write it to a image file.

func qrCodeGen(t string, filename string) (error) {}

Use qr.Encode() function to encode given text into a QR code.

func qrCodeGen(t string, filename string) (error) {

	// Create the barcode
	qrCode, _ := qr.Encode(t, qr.M, qr.Auto)

}

Scale the QR code to the 200*200 pixels with barcode.Scale() function.

func qrCodeGen(t string, filename string) (error) {

	// Create the barcode
	qrCode, _ := qr.Encode(t, qr.M, qr.Auto)

	// Scale the barcode to 200x200 pixels
	qrCode, _ = barcode.Scale(qrCode, 2000, 2000)


}

Create a file to write QR code to it with os.Create() function.

func qrCodeGen(t string, filename string) (error) {

	// Create the barcode
	qrCode, _ := qr.Encode(t, qr.M, qr.Auto)

	// Scale the barcode to 200x200 pixels
	qrCode, _ = barcode.Scale(qrCode, 2000, 2000)

	// create the output file
	file, err := os.Create(filename)
	defer file.Close()

}

Write the encoded image into a PNG image file with png.Encode() function.

func qrCodeGen(t string, filename string) (error) {
	// Create the barcode
	qrCode, _ := qr.Encode(t, qr.M, qr.Auto)

	// Scale the barcode to 200x200 pixels
	qrCode, _ = barcode.Scale(qrCode, 2000, 2000)

	// create the output file
	file, err := os.Create(filename)
	defer file.Close()

	// encode the barcode as png
	png.Encode(file, qrCode)

	return err
}

Finally call the function in your code to Generate the QR code.

package main

import (
	"image/png"
	"os"
	
	// barcode scale 
	"github.com/boombuler/barcode"
	// Build the QRcode for the text
	"github.com/boombuler/barcode/qr"
)


func qrCodeGen(t string, filename string) (error) {
	// Create the barcode
	qrCode, _ := qr.Encode(t, qr.M, qr.Auto)

	// Scale the barcode to 200x200 pixels
	qrCode, _ = barcode.Scale(qrCode, 2000, 2000)

	// create the output file
	file, err := os.Create(filename)
	defer file.Close()

	// encode the barcode as png
	png.Encode(file, qrCode)

	return err
}

func main() {
	
	// This is a text to encode
	t := "This is a text"
	// file to read from 
	filenameR := "qrcode.png"
	// qrCodeGen generates a QR Code
	qrCodeGen(t, filenameR)


}

3. Scan QR code - Go language

Import required packages.

package main

import (
	"image"
	"io/ioutil"
	"bytes"
	"fmt"

	// github. com liyue201 GOQR
	"github.com/liyue201/goqr"
)

Let's create a function to scan provided file, as a path, for QR code and extract text out of it.

func scanQRCode(path string) {}

Read the provided file (path) with ioutil.ReadFile() function.

func scanQRCode(path string) {
	
	// Reads imgdata from a file.
	imgdata, err := ioutil.ReadFile(path)
	if err != nil {
		fmt.Printf("%v\n", err)
		return
	}

}

Try to decode the file as image:

func scanQRCode(path string) {
	
	// Reads imgdata from a file.
	imgdata, err := ioutil.ReadFile(path)
	if err != nil {
		fmt.Printf("%v\n", err)
		return
	}

	// Decodes an image.
	img, _, err := image.Decode(bytes.NewReader(imgdata))
	if err != nil {
		fmt.Printf("image.Decode error: %v\n", err)
		return
	}

}

Check if any QR code exist in the provided image.

func scanQRCode(path string) {
	
	// Reads imgdata from a file.
	imgdata, err := ioutil.ReadFile(path)
	if err != nil {
		fmt.Printf("%v\n", err)
		return
	}

	// Decodes an image.
	img, _, err := image.Decode(bytes.NewReader(imgdata))
	if err != nil {
		fmt.Printf("image.Decode error: %v\n", err)
		return
	}

	// Recognize QR Codes.
	qrCodes, err := goqr.Recognize(img)
	if err != nil {
		fmt.Printf("Recognize failed: %v\n", err)
		return
	}

}

Extract data from the image and print it to standard output.

func scanQRCode(path string) {
	
	// Reads imgdata from a file.
	imgdata, err := ioutil.ReadFile(path)
	if err != nil {
		fmt.Printf("%v\n", err)
		return
	}

	// Decodes an image.
	img, _, err := image.Decode(bytes.NewReader(imgdata))
	if err != nil {
		fmt.Printf("image.Decode error: %v\n", err)
		return
	}

	// Recognize QR Codes.
	qrCodes, err := goqr.Recognize(img)
	if err != nil {
		fmt.Printf("Recognize failed: %v\n", err)
		return
	}
	
	// Prints a list of QR Codes.
	for _, qrCode := range qrCodes {
		fmt.Printf("qrCode text: %s\n", qrCode.Payload)
	}
	return
}

Finally, call the function in your code and provide the image file to decode.

package main

import (
	"image"
	"io/ioutil"
	"bytes"
	"fmt"

	// github. com liyue201 GOQR
	"github.com/liyue201/goqr"
)


func scanQRCode(path string) {
	
	// Reads imgdata from a file.
	imgdata, err := ioutil.ReadFile(path)
	if err != nil {
		fmt.Printf("%v\n", err)
		return
	}

	// Decodes an image.
	img, _, err := image.Decode(bytes.NewReader(imgdata))
	if err != nil {
		fmt.Printf("image.Decode error: %v\n", err)
		return
	}

	// Recognize QR Codes.
	qrCodes, err := goqr.Recognize(img)
	if err != nil {
		fmt.Printf("Recognize failed: %v\n", err)
		return
	}
	
	// Prints a list of QR Codes.
	for _, qrCode := range qrCodes {
		fmt.Printf("qrCode text: %s\n", qrCode.Payload)
	}
	return
}

func main() {
	

	// file to write to
	filenameW := "qrcode.png"
	// scanQRCode scans a QR code image file.
	scanQRCode(filenameW)

}

Conclusion

In this tutorial, we used Golang to write a program which can encode or decode QR code image files. You can modify the code to use other types of bar codes.



About the author:
Pradeep has expertise in Linux, Go, Nginx, Apache, CyberSecurity, AppSec and various other technical areas. He has contributed to numerous publications and websites, providing his readers with insightful and informative content.