go_qr

package module
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 22, 2023 License: MIT Imports: 9 Imported by: 5

README

go-qr

Mentioned in Awesome Go Go Report Card Build Status Codecov GoDoc

🎶 Go Community Minimalist QR Code Generator Library.

Overview

This library is native, high quality and minimalistic. Generate QR code from string text

It is mostly a translation of project Nayuki's Java version of the QR code generator.

Features

  • Minimalist native code implementation
  • Based on QR Code Model 2 standard, supports all 40 versions and all 4 error correction levels
  • Output format: Raw modules/pixels of the QR symbol
  • Detects finder-like penalty patterns more accurately than other implementations
  • Encoding space optimisation for numeric and special alphanumeric texts
  • Japanese Unicode Text Encoding Optimisation
  • For mixed numeric/alphanumeric/general/kanji text, computes optimal segment mode switching
  • Good test coverage
  • MIT's Open Source License

Installation

go get github.com/piglig/go-qr

Examples

package main

import (
	"errors"
	"fmt"
	go_qr "github.com/piglig/go-qr"
	"image"
	"image/color"
	"image/png"
	"math"
	"os"
	"strings"
)

func main() {
	doBasicDemo()
}

func doBasicDemo() {
	text := "Hello, world!"
	errCorLvl := go_qr.Low
	qr, err := go_qr.EncodeText(text, errCorLvl)
	if err != nil {
		return
	}
	img := toImageStandard(qr, 10, 4)
	err = writePng(img, "hello-world-QR.png")
	if err != nil {
		return
	}

	svg, err := toSvgString(qr, 4, "#FFFFFF", "#000000")
	if err != nil {
		return
	}

	svgFile, err := os.Create("hello-world-QR.svg")
	if err != nil {
		return
	}
	defer svgFile.Close()
	_, err = svgFile.WriteString(svg)
	if err != nil {
		return
	}
}

func toImageStandard(qr *go_qr.QrCode, scale, border int) *image.RGBA {
	return toImage(qr, scale, border, color.White, color.Black)
}

func toImage(qr *go_qr.QrCode, scale, border int, lightColor, darkColor color.Color) *image.RGBA {
	if scale <= 0 || border < 0 || qr == nil {
		panic("Invalid input")
	}

	if border > (math.MaxInt32/2) || int64(qr.GetSize())+int64(border)*2 > math.MaxInt32/int64(scale) {
		panic("Scale or border too large")
	}

	size := qr.GetSize() + border*2
	imageWidth := size * scale
	imageHeight := size * scale
	result := image.NewRGBA(image.Rect(0, 0, imageWidth, imageHeight))
	for y := 0; y < imageHeight; y++ {
		for x := 0; x < imageWidth; x++ {
			moduleX := x/scale - border
			moduleY := y/scale - border
			isDark := qr.GetModule(moduleX, moduleY)
			if isDark {
				result.Set(x, y, darkColor)
			} else {
				result.Set(x, y, lightColor)
			}
		}
	}
	return result
}

func writePng(img *image.RGBA, filepath string) error {
	file, err := os.Create(filepath)
	if err != nil {
		return err
	}
	defer file.Close()

	err = png.Encode(file, img)
	if err != nil {
		return err
	}

	return nil
}

func toSvgString(qr *go_qr.QrCode, border int, lightColor, darkColor string) (string, error) {
	if border < 0 {
		return "", errors.New("border must be non-negative")
	}

	if qr == nil {
		return "", errors.New("qr is nil")
	}

	var brd = int64(border)
	sb := strings.Builder{}
	sb.WriteString("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n")
	sb.WriteString("<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n")
	sb.WriteString(fmt.Sprintf("<svg xmlns=\"http://www.w3.org/2000/svg\" version=\"1.1\" viewBox=\"0 0 %d %d\" stroke=\"none\">\n",
		int64(qr.GetSize())+brd*2, int64(qr.GetSize())+brd*2))
	sb.WriteString("\t<rect width=\"100%\" height=\"100%\" fill=\"" + lightColor + "\"/>\n")
	sb.WriteString("\t<path d=\"")

	for y := 0; y < qr.GetSize(); y++ {
		for x := 0; x < qr.GetSize(); x++ {
			if qr.GetModule(x, y) {
				if x != 0 || y != 0 {
					sb.WriteString(" ")
				}
				sb.WriteString(fmt.Sprintf("M%d,%dh1v1h-1z", int64(x)+brd, int64(y)+brd))
			}
		}
	}
	sb.WriteString("\" fill=\"" + darkColor + "\"/>\n")
	sb.WriteString("</svg>\n")

	return sb.String(), nil
}

Command Line Tool

generator command line tool to generate the QR Code.

Installation

In order to use the tool, compile it using the following command

go install github.com/piglig/go-qr/tools/generator@latest
Usage
generator [options] [arguments]
  -content string
        Content to encode in the QR code
  -png string
        Output PNG file name
  -svg string
        Output SVG file name
Example
  • Text Art
generator -content hello

Gif

  • Image Type
generator -content hello -png hello.png -svg hello.svg

Gif

License

See the LICENSE file for license rights and limitations (MIT).

Documentation

Index

Constants

View Source
const (
	MinVersion = 1
	MaxVersion = 40
)

Minimum(1) and Maximum(40) version numbers based on the QR Code Model 2 standard

Variables

View Source
var (
	// Numeric mode is typically used for decimal digits (0 through 9).
	Numeric = newMode(0x1, 10, 12, 14)

	// Alphanumeric mode includes digits 0-9, uppercase letters A-Z and nine special characters.
	Alphanumeric = newMode(0x2, 9, 11, 13)

	// Byte mode can encode binary/byte data(default: ISO-8859-1)
	Byte = newMode(0x4, 8, 16, 16) // Byte mode: binary/byte data (default: ISO-8859-1)

	// Kanji mode is used for encoding Japanese Kanji characters.
	Kanji = newMode(0x8, 8, 10, 12)

	// Eci mode is designed for providing a method of extending features and functions
	// in bar code symbols beyond those envisioned by the original standard.
	Eci = newMode(0x7, 0, 0, 0)
)

Predefined Mode values as defined by the QR Code standard.

Functions

This section is empty.

Types

type BitBuffer

type BitBuffer []bool

type BitSet

type BitSet interface {
	// contains filtered or unexported methods
}

BitSet defines an interface that allows manipulation of a bitset.

type DataTooLongException

type DataTooLongException struct {
	Msg string
}

func (*DataTooLongException) Error

func (d *DataTooLongException) Error() string

type Ecc

type Ecc int

Ecc is the representation of an error correction level in a QR Code symbol.

const (
	Low      Ecc = iota // 7% of codewords can be restored
	Medium              // 15% of codewords can be restored
	Quartile            // 25% of codewords can be restored
	High                // 30% of codewords can be restored
)

func (Ecc) FormatBits

func (e Ecc) FormatBits() int

FormatBits method gets the format bits associated with the error correction level.

type Mode

type Mode struct {
	// contains filtered or unexported fields
}

Mode is the representation of the mode of a QR code character.

type QrCode

type QrCode struct {
	// contains filtered or unexported fields
}

QrCode is the representation of a QR code

func EncodeBinary

func EncodeBinary(data []byte, ecl Ecc) (*QrCode, error)

EncodeBinary takes a byte array and an error correction level (ecl), converts the bytes to QR code segments and returns a QR code or an error.

func EncodeSegments

func EncodeSegments(segs []*QrSegment, ecl Ecc, minVer, maxVer, mask int, boostEcl bool) (*QrCode, error)

EncodeSegments is a more flexible version of EncodeStandardSegments. It allows the specification of minVer, maxVer, mask in addition to the regular parameters. Returns a QR code object or an error.

func EncodeStandardSegments

func EncodeStandardSegments(segs []*QrSegment, ecl Ecc) (*QrCode, error)

EncodeStandardSegments takes QR code segments and an error correction level, creates a standard QR code using these parameters and returns it or an error.

func EncodeText

func EncodeText(text string, ecl Ecc) (*QrCode, error)

EncodeText takes a string and an error correction level (ecl), encodes the text to segments and returns a QR code or an error.

func (*QrCode) GetModule

func (q *QrCode) GetModule(x, y int) bool

GetModule checks if a module is dark at given coordinates.

func (*QrCode) GetSize

func (q *QrCode) GetSize() int

GetSize returns the size of the QR code

type QrSegment

type QrSegment struct {
	// contains filtered or unexported fields
}

QrSegment is the representation of a segment of a QR code.

func MakeAlphanumeric

func MakeAlphanumeric(text string) (*QrSegment, error)

MakeAlphanumeric converts a string into a QR code segment in Alphanumeric mode It returns an error if the string contains non-alphanumeric characters.

func MakeBytes

func MakeBytes(data []byte) (*QrSegment, error)

MakeBytes converts a byte slice into a QR segment in Byte mode. It returns an error if the input data is nil.

func MakeEci

func MakeEci(val int) (*QrSegment, error)

MakeEci converts an integer into a QR code segment in Eci mode It returns an error if the integer value is out of range.

func MakeKanji

func MakeKanji(text string) (*QrSegment, error)

MakeKanji converts a string into a QR code segment in Kanji mode It returns an error if the string contains non-kanji characters.

func MakeNumeric

func MakeNumeric(digits string) (*QrSegment, error)

MakeNumeric converts a string of digits into a QR code segment in Numeric mode It returns an error if the string contains non-numeric characters.

func MakeSegments

func MakeSegments(text string) ([]*QrSegment, error)

MakeSegments converts data into QR segments based on the mode of text (Numeric, Alphanumeric or Byte, etc).

func MakeSegmentsOptimally

func MakeSegmentsOptimally(text string, ecl Ecc, minVersion, maxVersion int) ([]*QrSegment, error)

MakeSegmentsOptimally takes a string and error correction level, and attempts to make QR segments in the most efficient way possible. It validates the version range and converts the input text into code points. Then, it loops through each version, attempting to make segments until the data fits within the capacity of the version. Returns an array of pointers to QrSegment or an error.

Directories

Path Synopsis
example module
tools module

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL