Git Product home page Git Product logo

go-qrcode's Introduction

go-qrcode

Go Report Card go.dev reference Go GitHub release (latest SemVer) GitHub go.mod Go version License

QR code (abbreviated from Quick Response Code) is the trademark for a type of matrix barcode (or two-dimensional barcode) first designed in 1994 for the automotive industry in Japan. A barcode is a machine-readable optical label that contains information about the item to which it is attached. A QR code uses four standardized encoding modes (numeric, alphanumeric, byte/binary, and kanji) to store data efficiently; extensions may also be used

Features

  • Normally generate QR code across version 1 to version 40.
  • Automatically analyze QR version by source text.
  • Specifying cell shape allowably with WithCustomShape, WithCircleShape (default is rectangle)
  • Specifying output file's format with WithBuiltinImageEncoder, WithCustomImageEncoder (default is JPEG)
  • Not only shape of cell, but also color of QR Code background and foreground color.
  • WithLogoImage, WithLogoImageFilePNG, WithLogoImageFileJPEG help you add an icon at the central of QR Code.
  • WithBorderWidth allows to specify any width of 4 sides around the qrcode.
  • WebAssembly support, check out the Example and README for more detail.
  • support Halftone QR Codes, check out the Example.

Install

go get -u github.com/yeqown/go-qrcode/v2

Quick Start

link to CODE

package main

import (
	"github.com/yeqown/go-qrcode/v2"
	"github.com/yeqown/go-qrcode/writer/standard"
)

func main() {
	qrc, err := qrcode.New("https://github.com/yeqown/go-qrcode")
	if err != nil {
		fmt.Printf("could not generate QRCode: %v", err)
		return
	}
	
	w, err := standard.New("../assets/repo-qrcode.jpeg")
	if err != nil {
		fmt.Printf("standard.New failed: %v", err)
		return
	}
	
	// save file
	if err = qrc.Save(w); err != nil {
		fmt.Printf("could not save image: %v", err)
	}
}

Options

const (
	// EncModeNone mode ...
	EncModeNone encMode = 1 << iota
	// EncModeNumeric mode ...
	EncModeNumeric
	// EncModeAlphanumeric mode ...
	EncModeAlphanumeric
	// EncModeByte mode ...
	EncModeByte
	// EncModeJP mode ...
	EncModeJP
)

// WithEncodingMode sets the encoding mode.
func WithEncodingMode(mode encMode) EncodeOption {}

const (
	// ErrorCorrectionLow :Level L: 7% error recovery.
	ErrorCorrectionLow ecLevel = iota + 1
	
	// ErrorCorrectionMedium :Level M: 15% error recovery. Good default choice.
	ErrorCorrectionMedium
	
	// ErrorCorrectionQuart :Level Q: 25% error recovery.
	ErrorCorrectionQuart
	
	// ErrorCorrectionHighest :Level H: 30% error recovery.
	ErrorCorrectionHighest
)

// WithErrorCorrectionLevel sets the error correction level.
func WithErrorCorrectionLevel(ecLevel ecLevel) EncodeOption {}

following are some shots:


Built-in Writers

Of course, you can also code your own writer, just implement Writer interface.

Migrating from v1

go-qrcode.v2 is a major upgrade from v1, and it is not backward compatible. v2 redesigned the API, and it is more flexible and powerful. Features are split into different modules (according to functionality).

  • github.com/yeqown/go-qrcode/v2 core
  • github.com/yeqown/go-qrcode/writer/standard writer/imageFile
  • github.com/yeqown/go-qrcode/writer/terminal writer/terminal

Check example/migrating-from-v1 for more details.

Links

go-qrcode's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

go-qrcode's Issues

Quality?

Hi, neat project

Is there a setting to control QA parameters?

should close fd in QRCode.Save method

without closing the fd create in QRCode.Save(saveToPath string), the qrcode image file is always used and cannot be processed

should add

defer fd.Close()

before return statement

WithCustomShape 该如何使用

  • 虽然支持WithCustomShape,但IShape.Draw依赖DrawContext,但DrawContext中的变量全部为私有,自定义后无法读取相关变量,定位像素点位置。
  • 请问是否有相关示例可参考,如将WithCircleShape中的圆半径缩小至80%。

Saving QR to file for the second time gives different (corrupted) output

When I create a QR code (doesn't matter is it with option, custom shape etc) and save it to file two (or more) times only 1st output is correct. Second (and third) output file is corrupted - few 'pixels' near finder areas are different.

Sample code:

	plainQr, err := qrcode.New("https://github.com/")
	if err != nil {
		panic(err)
	}
	err = plainQr.Save("./out1.png")
	if err != nil {
		log.Println(err)
	}
	err = plainQr.Save("./out2.png")
	if err != nil {
		log.Println(err)
	}

QR code out1.png reads OK, out2.png doesn't read at all.

You may ask why I'm saving same QR for the second time 😄 I'm doing custom multi colour codes and need to obtain width and height of the QR code - found this as solution: generate it for the first time to save maxH and maxW in my custom-shape object, then generate it for the second time to produce my coloured QR.

编译二进制 qrcode 失败

进入 github.com/yeqown/go-qrcode/cmd/qrcode,然后执行 go build 进行编译时,报错了,提示

main module (github.com/yeqown/go-qrcode/v2) does not contain package github.com/yeqown/go-qrcode/v2/cmd/qrcode

qrcode 目录拷贝到其它非 go-qrcode 目录(以及子目录)下,就没问题了。

制作出来的二维码图片比较大

使用 python-qrcode 制作出来的二维码图片只有 702 个字节,但使用本项目 go-qrcode 制作出来的二维码图片却有 13298 个字节,大小相差了将近 19 倍。有什么办法缩小二维码尺寸大小吗?

说明: 使用相同的文本,其它配置几乎一样(或者都按默认配置)。

cannot install package on go 1.12 because of math.MaxInt

I couldn't install the package on vscode with go 1.12. got the following error message:

go get -u github.com/yeqown/go-qrcode
# github.com/yeqown/go-qrcode
..\..\go\src\github.com\yeqown\go-qrcode\mask_evaluation.go:35:10: undefined: math.MaxInt
..\..\go\src\github.com\yeqown\go-qrcode\mask_evaluation.go:113:10: undefined: math.MaxInt
..\..\go\src\github.com\yeqown\go-qrcode\mask_evaluation.go:148:10: undefined: math.MaxInt

I guess the problem is similar to the bug which described here:
buger/goterm@b630d37

could not analyze the data: could not analyzeVersion: could not match version! check the versionCfg.json file

url := "https://openapi.alipaydev.com/gateway.do?app_id=2016091200494382&biz_content=%7B%22out_trade_no%22%3A%22GZ201901301040361014%22%2C%22product_code%22%3A%22QUICK_WAP_WAY%22%2C%22quit_url%22%3A%22https%3A%2F%2Fwww.gopay.ink%22%2C%22subject%22%3A%22%E6%89%8B%E6%9C%BA%E7%BD%91%E7%AB%99%E6%B5%8B%E8%AF%95%E6%94%AF%E6%8C%81%22%2C%22total_amount%22%3A%220.01%22%7D&charset=utf-8&format=JSON&method=alipay.trade.wap.pay&notify_url=https%3A%2F%2Fwww.gopay.ink&sign=kD1ezhNwjkA6PZzYOvvNd5wTtOeAo5kgCxXaeZ6nhNyB4g3nDndy5hAwQeWVBVlTJiL9MD%2Bn%2BhOTghZVqizNrmA2MB4eTAIMFjmM6yk0jAG6Rug3updNtDLBD30sDP%2FEwhi2lsliEg6Z3L0wfYgXdjpR%2B%2Bl1xCP2t3Bs8LYbiDPLBSibatDpLv7HZErH0jA5nMqolYj%2F92Fsdb%2BxS%2Fdcz7aqUHcEeVzdG%2FV8bQxRt0VzPe5hOO173BpPtolsrYZCVJrVoH3aYa5fW%2BDxTo3BVZkroCtjsh4mkdPaXac6RGhAE%2BR7H%2BF514OlzaxiDHNKMQaktfO6haipRYta3ejo2g%3D%3D&sign_type=RSA2&timestamp=2021-01-07+17%3A24%3A52&version=1.0"

		qrc, err := qr.New(payUrl)
		if err != nil {
			log.Error().Err(err).Msg("")
			return
		}

Would failed with

5:26PM ERR cmd/alipay.go:73 >  error="could not analyze the data: could not analyzeVersion: could not match version! check the versionCfg.json file"

Setting output size?

I realize I'm able to set the QRWidth using:

standard.WithQRWidth(255)

However, how can I specify that I want a total image output of say, 1024x1024?

QR WithLogoImage behaviour - expected or bug?

Hi @yeqown, question regarding QR with logo inside: when I create one, it seems that the logo image just covers inner part of QR code, the inner/center part is not empty and then logo image is put on it.
Is that expected behaviour?

I guess the error correction makes that OK, but still, in my opinion it would be better if QR code would be generated with keeping that space empty (and having all the information not in this center area) and putting logo there.

BTW I was really glad seeing v2 coming, I really like your work!
Hubert

Example for how to encode []byte

Hello again @yeqown 😁

I am doing more testing and have a question. Suppose I have some binary data in a []byte like this:

someBinaryDataToEncode := []byte{8, 48, 37, 237, 187, 89, 0}

Since qrcode.New() and qrcode.NewWith() takes string type for the input, how can we encode this byte data? I see qrcode.sourceRawBytes on the struct but it is private and I do not see a public func to populate it.

If you could help me, I can write something up for /example folder. Thank you @yeqown

Feat: expose QR Code image attributes before saving it as image

attribute design as following:

type Attribute struct {
  W, H     int      // width and height of image
  Borders [4]int // in the order of "top, right, bottom, left"
  BlockWidth int      // the length of  block edges
}

Usage like this:

qrc := qrcode.New("source content", options...)
attr := qrc.Attribute()
fmt.Printf("attrbute is: %+v", attr)

[BUG] Terminal writer not working on MacOS.

Describe the bug
Running the use-terminal-writer example results in nothing being printed to the Terminal at all.

To Reproduce
Just run the example, it shows nothing.

Expected behavior
I was expecting to see a text mode version of the QRCode showing up in the terminal.

Screenshots
N/A as the result is nothing is printed.

Additional context
N/A

Save (stream) to []byte

Thank you for this library. I have it working just fine in PNG file mode.

I would like to save the image to a []byte and not save it to disk. Can you provide an example of how to create your own Writer to do this?

I attempted to use newWriter but its not exposed (private function). I tried to implement a Write() method but this requires knowledge about matrix.Matrix which is quite QR code technical.

I have a hunch there is an easier way but I don't see it. Perhaps a new StreamWriter in addition to the provided Standard and Terminal writers would be just as easy as writing an example here? I'd be happy to contribute once I see the path forward.

Implementing EncModeJP

Is your feature request related to a problem? Please describe.
Some low end smartphones (especially chineses brands) do not recognize URL links automatically when they are UTF8 encoded. So the user has to copy paste the URL from the scanner to the browser to open the page and it degrads the user experience...

Describe the solution you'd like
From my testing kanji encoded URLs are recognized on theses phones (at least some of them) and allows the user to open the navigator right away from the camera app.

Describe alternatives you've considered

Additional context
It works with the qrencode cli (ex: qrencode -o qrcode.kanji.png --kanji MyURL)

Why is jpeg is used by default?

The jpg format is a loosing compression and was developed for photos. But for qr codes the ideal format is PNG and resulting files are about 10 times smaller.
Could you please switch the defaults to PNG?

Because now I started working a big project that generates thousands of QR codes daily. Each of them about 23-25kb and uploaded to S3 buckets. This is just gigantic waste of money and bandwidth.
I'll change all this but wondered how this might happen in first place.
And now I see that even in the sample in README the output format is JPEG.

Also please add an example of resizing the resulted image. Because I see in code that my colleges just resizing the generated QR code. But I guess the minimal qr must be generated by default wit only a pixel for a dot. And latter if it can be resized by a browser or app itself on view

A few questions

Hi,

Thank you for making this library available.

I have a few questions:

  • Why do some QR codes generated have no borders to the bottom and right? Example -> this one
  • Can you provide an example of SaveTo that can save to a PNG file?
  • Do you plan to support HEIF? i.e. SaveTo HEIF

I am trying to use SaveTo to write to a buffer first because my container is locked down and I am POSTing the data to another URL.

Example code:

       qrc, _ := qrcode.New("https://www.google.com")
	
       // save file
	var file bytes.Buffer
        _ = qrc.SaveTo(&file)

	var payload bytes.Buffer
	writer := multipart.NewWriter(&payload)

        part, _ := writer.CreateFormFile("file", "google")

	fileBytes, _ := ioutil.ReadAll(&file)

	_, _ = part.Write(fileBytes)
	writer.Close()

	request, _ := http.NewRequest("POST", "<another_service>", &payload)

	request.Header.Add("Content-Type", writer.FormDataContentType())
	client := &http.Client{}
	response, _ := client.Do(request)
	defer response.Body.Close()

The file that is produced by SaveTo is always of type image/jpeg.

Would be nice to support type of image/png and image/heif.

How can I find which version is for Go 1.16?

With some SSL issues, I cannot upgrade to use latest golang version. I still strict with go 1.16. In this case, How can I find which go-qrcode version that I can use with go 1.16?

Thank you

[FEATURE] Terminal v2 suggestion

Hello! Thanks for working on this very helpful package and for keeping the QR code stuff active in the Go ecosystem.
I have a proposal and I'd like to hear your thoughts.

The current terminal writer uses Termbox, which is nice but difficult to integrate with for better control over CLI tools. It's especially challenging to display a QR code in the terminal without creating a whole new screen. Additionally, Termbox is no longer maintained.

I'm proposing a terminal v2 writer that uses *os.File for output. I chose *os.File instead of io.Writer because it has a better chance of displaying correctly. I also added a Bitmap() method, which I found useful when working with the skip2 package.

using this writer should be as simple as doing that

func main() {
	QRCodeItem, _ := qrcode.New("Hello!")
	termV2 := New(os.Stdout)
	_ = QRCodeItem.Save(termV2)
}

full example

package main

import (
	"errors"
	"os"

	"github.com/yeqown/go-qrcode/v2"
)

const (
	upRune     = '▀'
	downRune   = '▄'
	upDownRune = '█'
)

var _ qrcode.Writer = (*terminalv2)(nil)

func main() {
	QRCodeItem, _ := qrcode.New("Hello!")
	termV2 := New(os.Stdout)
	_ = QRCodeItem.Save(termV2)
}

type terminalv2 struct {
	out    *os.File
	bitmap [][]bool
}

func (a *terminalv2) Close() error { return nil }
func (a *terminalv2) Write(mat qrcode.Matrix) error {
	if a.out == nil {
		return errors.New("nil file")
	}

	a.bitmap = make([][]bool, mat.Height())
	for i := range a.bitmap {
		a.bitmap[i] = make([]bool, mat.Width())
	}
	mat.Iterate(qrcode.IterDirection_ROW, func(row, col int, s qrcode.QRValue) {
		a.bitmap[col][row] = s.IsSet()
	})

	bm := a.bitmap

	output := make([][]string, len(bm)/2+len(bm)%2)
	for i := range output {
		output[i] = make([]string, len(bm[0]))
	}

	for col := range output {
		for row := range output[col] {
			var selectedRune rune = ' '

			if bm[col*2][row] {
				selectedRune = upRune
			}

			if col*2+1 < len(bm) {
				if bm[col*2+1][row] && !bm[col*2][row] {
					selectedRune = downRune
				}

				if bm[col*2+1][row] && bm[col*2][row] {
					selectedRune = upDownRune
				}

				if !bm[col*2+1][row] && !bm[col*2][row] {
					selectedRune = ' '
				}
			}

			output[col][row] = string(selectedRune)
		}
	}

	for _, col := range output {
		for _, row := range col {
			_, err := a.out.WriteString(row)
			if err != nil {
				return err
			}
		}
		_, err := a.out.WriteString("\n")
		if err != nil {
			return err
		}
	}

	return nil
}

func (a *terminalv2) Bitmap() [][]bool {
	return a.bitmap
}

func New(f *os.File) *terminalv2 {
	return &terminalv2{out: f}
}

Screenshot from 2024-05-20 16-53-24

If you're happy with it, I can raise a PR.

[BUG] Transparent background

Describe the bug
standard.WithBgTransparent() doesn't set the background as transparent!

To Reproduce
customWriter := &customWriteCloser{}
standard.NewWithWriter(
customWriter,
standard.WithBgTransparent(),
)

Expected behavior
Black foreground with transparent background image
Screenshots
image

[QUESTION] How i can use differnt colors?

How i can realize a qrcode like this one:

Schermata del 2024-06-13 11-50-56

If is not possible, how i can use different colors for the 3 big angle squares (or cicles) and the inside elements?

Tanks

Borderless QRCode

How can I generate a QRcode jpeg buffer without QRcode having borders?

I want to generate something like this:
sample_qr_code

Swedish letter in QR code

Try to generate QR code, try add Swedish letter and got wrong QR code (with red pixels LOL)
qr

generateQR("Övrigt asdasd asdas djaskl djaslk djaslkj dlaiodqjwiodjaskldj aksldjlk Övrigt")

    func generateQR(QRText string) {
        qrc, err := qrcode.New(QRText)
        if err != nil {
	        fmt.Printf("could not generate QRCode: %v", err)
        }
    
        // save file
        if err := qrc.Save("qr.png"); err != nil {
	        fmt.Printf("could not save image: %v", err)
        }
    }

Once you apply some ImageOptions, it will remain the same for other QR codes

Some code to show this.

package main

import (
	"github.com/yeqown/go-qrcode"
)

func main() {
	// start with square
	a, _ := qrcode.New("This is a test")
	a.Save("test1.jpg") // <- square QR code

	// make circle
	var qroptions = []qrcode.ImageOption{}
	qroptions = append(qroptions, qrcode.WithCircleShape())
	b, _ := qrcode.New("This is a test", qroptions...)
	b.Save("test2.jpg") // <- circle QR code

	// go back to square
	c, _ := qrcode.New("This is a test")
	c.Save("test3.jpg") // <- this should be a square but is actually also a circle
}

v2 proposal: redesign API and separate an Writer

Now, go-qrcode supports more and more features since v1.0.0 and it contains some unreasonable design, such as:

  1. NewWithConfig to support cutomized ECLevel and encoding quality, an compromise in order to keep API compatible
  2. New receive output options, but there's a Save-like methods to draw picture actually.
  3. Save and SaveTo limited developer to draw pictures only with io.Writer, but actually it should be unlimited

v2 want to refactor these API, and it looks like:

Step 1: generate qrcode matrix

qrc := qrcode.New("source", EncodeOptions...)

Step 2: build your writer

here, you can use buitin and customized writer to decide how to instance matrix into a picture (file / stream / console)

writer := newWriter(WriterOptions)

// writer must in form of Writer interface:
type Writer interface {
    // mat is encoded qrcode matrix, each point in matrix is matrix.State (enum type)
    Write(mat matrix.Matrix) error
}

Step 3: save qrcode

if err := qrc.SaveTo(writer); err != nil {
    panic(err)
}

built-in writers

  • To keep supports to v1, we provide built-in writers to save qrcode into image files.
  • And new support to write qrcode into the terminal.

they are held in a separate module named writers/standard and writers/terminal

clean strcuture

  • move useful testdata/files into assets
  • remove scripts folder

Support for exporting to raw bitmap, or adding text to the bottom or top of the QR Code

Quite a few javascript libraries support adding a custom text like "Scan this code on your phone to open the app,,," etc.
It's easy to do this on javascript as fonts are inbuilt. But even on Go there are many libraries available that allow using system/custom fonts to do the same.

I request support for either:

  1. Exporting the output image to raw Bitmap in-memory so my program can then blit the image onto another in-memory canvas which I can then add my custom text or other borders etc. into.
  2. Add support within the program itself for "margin" so each QR code has "n" blank/white pixels all around, and within this margin the library supports printing text onto the image before exporting it using another font rendering library.

Test with icon doesnt work

I'm running tests and doesnt generate a qr with icon.
I added logo.png image to testdata directory but doesnt work.

The generated qrtest_icon.jpeg doesn't have icon and doesn't fail

go pkg versioning for writer/standard

Hi! Right now, to use the package we still have to use this import path "github.com/yeqown/go-qrcode/writer/standard"

but the qrcode package is on v2 "github.com/yeqown/go-qrcode/v2"

shouldn't the versioning for writer should also be something like this "github.com/yeqown/go-qrcode/v2/writer/standard"

it's because writer/standard has its own go.mod, is there a reason for it? ideally it should all be in a root go.mod file

go panic when using single character string

_, err := qrcode.New("a")
if err != nil {
log.Fatal(err)
}
2021/07/05 16:43:46 encodeAlphanumericCharacter() with non alphanumeric char a
panic: encodeAlphanumericCharacter() with non alphanumeric char a

goroutine 1 [running]:
log.Panicf(0x6bd5c8, 0x3b, 0xc00010fb20, 0x1, 0x1)
C:/Users/storm/dev/go/src/log/log.go:361 +0xc7
github.com/yeqown/go-qrcode.encodeAlphanumericCharacter(0xc000048561, 0xc000014180)
C:/Users/storm/go/pkg/mod/github.com/yeqown/[email protected]/encoder.go:266 +0x110
github.com/yeqown/go-qrcode.(*encoder).encodeAlphanumeric(0xc000120000)
C:/Users/storm/go/pkg/mod/github.com/yeqown/[email protected]/encoder.go:146 +0x54
github.com/yeqown/go-qrcode.(*encoder).Encode(0xc000120000, 0xc0000140f8, 0x1, 0x8, 0x40, 0x2030000, 0x2030000)
C:/Users/storm/go/pkg/mod/github.com/yeqown/[email protected]/encoder.go:100 +0x18d
github.com/yeqown/go-qrcode.(*QRCode).dataEncoding(0xc00011e000, 0xc000120000, 0x15, 0xc00000aae0, 0x1, 0x8)
C:/Users/storm/go/pkg/mod/github.com/yeqown/[email protected]/qrcode.go:173 +0x74
github.com/yeqown/go-qrcode.(*QRCode).init(0xc00011e000, 0xc00011e000, 0xc000006088)
C:/Users/storm/go/pkg/mod/github.com/yeqown/[email protected]/qrcode.go:128 +0x305
github.com/yeqown/go-qrcode.New(0x6b2f3a, 0x1, 0xc00010ff68, 0x1, 0x1, 0x595acb, 0xc000046058, 0x5a9801)
C:/Users/storm/go/pkg/mod/github.com/yeqown/[email protected]/qrcode.go:40 +0x1e5
main.main()
C:/Users/storm/projects/go/qrcbug/main.go:10 +0x7d

[BUG] DATA RACE Issue When Calling qrcode.New from Multiple Goroutines

Describe the bug

I am experiencing a data race issue when invoking qrcode.New concurrently from multiple goroutines.
I have confirmed that this issue occurs in version v2.2.2.

To Reproduce

package main

import (
	"fmt"
	"sync"

	"github.com/yeqown/go-qrcode/v2"
)

func main() {
	var wg sync.WaitGroup

	for i := 0; i < 10; i++ {
		wg.Add(1)

		u := fmt.Sprintf("http://example.com/dummy?id=%04d", i)
		go func(u string) {
			defer wg.Done()
			_, err := qrcode.New(u)
			if err != nil {
				panic(err)
			}
		}(u)
	}

	wg.Wait()
}
go run -race ./
go run -race ./
==================
WARNING: DATA RACE
Read at 0x00c000000168 by goroutine 13:
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/version.go:371 +0x60
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Previous write at 0x00c000000168 by goroutine 7:
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/version.go:389 +0x1c0
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Goroutine 13 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50

Goroutine 7 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50
==================
==================
WARNING: DATA RACE
Read at 0x00c00000ed10 by goroutine 12:
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:335 +0x538
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Previous write at 0x00c00000ed10 by goroutine 7:
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/version.go:386 +0x33c
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Goroutine 12 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50

Goroutine 7 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50
==================
==================
WARNING: DATA RACE
Read at 0x00c00009c180 by goroutine 8:
  runtime.mapaccess1_fast64()
      .local/share/mise/installs/go/1.22.1/go/src/runtime/map_fast64.go:13 +0x1bc
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/version.go:371 +0x54
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Previous write at 0x00c00009c180 by goroutine 7:
  runtime.mapaccess2_fast64()
      .local/share/mise/installs/go/1.22.1/go/src/runtime/map_fast64.go:53 +0x1cc
  github.com/yeqown/go-qrcode/v2.loadAlignmentPatternLoc()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/version.go:389 +0x1b4
  github.com/yeqown/go-qrcode/v2.(*QRCode).prefillMatrix()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:335 +0x380
  github.com/yeqown/go-qrcode/v2.(*QRCode).init()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:124 +0x5dc
  github.com/yeqown/go-qrcode/v2.build()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:42 +0x1d8
  github.com/yeqown/go-qrcode/v2.New()
      pkg/mod/github.com/yeqown/go-qrcode/[email protected]/qrcode.go:16 +0x7c
  main.main.func1()
      work/qrcodedatarace/main.go:19 +0x78
  main.main.gowrap1()
      work/qrcodedatarace/main.go:23 +0x54

Goroutine 8 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50

Goroutine 7 (running) created at:
  main.main()
      work/qrcodedatarace/main.go:17 +0x50
==================
Found 3 data race(s)
exit status 66

Expected behavior

I expect that no data races occur.

Screenshots

Additional context

Feature(image-compression): PNG bit depth must be 1

The QR codes generated by https://github.com/skip2/go-qrcode are much smaller.
I compared and the main difference is that bit depth is 24 while it's enough only 1 bit (black/white).

Also the PNG format is basically a gzip-ed BMP image. So we can also play with it's compression.
Currently the default compression is used but it make sense to use maximum compression by default.
It will make generation slightly slower but just a little bit.
The images are often transmitted over internet and network bandwidth is more critical than CPU time.
It would be nice to be able to generate BMP images so that they can be compressed freely by a developer with a compressor that best fits to their needs.

[FEATURE] Transparent (png) output for halftone QR codes.

Is your feature request related to a problem? Please describe.
I'm trying to use a transparent image in png format. Currently the output of .WithHalftone is not transparent. So, a transparent blank image creates a black image with the QR code.

Describe the solution you'd like
A transparent output QR code image is required. It should be just the QR code on a transparent background.

Error when not adding an option

My code

qrc, err := qrcode.New("https://github.com/yeqown/go-qrcode")
if err != nil {
    fmt.Printf("could not generate QRCode: %v", err)
}

// save file
if err := qrc.Save("tes.jpg"); err != nil {
    fmt.Printf("could not save image: %v", err)
}

Error

=== RUN   TestQRCodePDF_CreateQRCode
--- FAIL: TestQRCodePDF_CreateQRCode (0.02s)
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
	panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x12de60e]

goroutine 6 [running]:
testing.tRunner.func1.1(0x1474ca0, 0x18ae4a0)
	/usr/local/go/src/testing/testing.go:940 +0x2f5
testing.tRunner.func1(0xc00011b680)
	/usr/local/go/src/testing/testing.go:943 +0x3f9
panic(0x1474ca0, 0x18ae4a0)
	/usr/local/go/src/runtime/panic.go:969 +0x166
github.com/yeqown/go-qrcode.drawAndSave(0x159b760, 0xc0000105c0, 0xc0001dbc00, 0x21, 0x21, 0x21, 0x21, 0xc000066780, 0x14eb532, 0xc00004fe68)
	/Users/nurmanhabib/go/pkg/mod/github.com/yeqown/[email protected]/image.go:43 +0x7e
github.com/yeqown/go-qrcode.(*QRCode).SaveTo(0xc00018c0c0, 0x159b760, 0xc0000105c0, 0x159b760, 0xc0000105c0)
	/Users/nurmanhabib/go/pkg/mod/github.com/yeqown/[email protected]/qrcode.go:621 +0xa4
github.com/yeqown/go-qrcode.(*QRCode).Save(0xc00018c0c0, 0x14eb532, 0x7, 0x0, 0x0)
	/Users/nurmanhabib/go/pkg/mod/github.com/yeqown/[email protected]/qrcode.go:612 +0x15b
xxx/watermark_test.TestQRCodePDF_CreateQRCode(0xc00011b680)
	/Users/nurmanhabib/x/watermark/qrcode_pdf_test.go:32 +0xec
testing.tRunner(0xc00011b680, 0x15167c8)
	/usr/local/go/src/testing/testing.go:991 +0xdc
created by testing.(*T).Run
	/usr/local/go/src/testing/testing.go:1042 +0x357

Process finished with exit code 1

Temporary solution (add at least one option)


qrc, err := qrcode.New("https://github.com/yeqown/go-qrcode", qrcode.WithBuiltinImageEncoder(qrcode.PNG_FORMAT))

there should be a default option so that there is no fatal error

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.