mirror of
https://github.com/h44z/wg-portal
synced 2025-02-26 05:49:14 +00:00
89 lines
2.0 KiB
Go
89 lines
2.0 KiB
Go
|
package configfile
|
||
|
|
||
|
// waiting for https://github.com/yeqown/go-qrcode/pull/85 to get merged
|
||
|
// meanwhile we use our own writer implementation
|
||
|
|
||
|
import (
|
||
|
"image"
|
||
|
"image/color"
|
||
|
"image/png"
|
||
|
"io"
|
||
|
|
||
|
"github.com/yeqown/go-qrcode/v2"
|
||
|
)
|
||
|
|
||
|
type Option struct {
|
||
|
Padding int
|
||
|
BlockSize int
|
||
|
}
|
||
|
|
||
|
// compressedWriter implements issue#69, generating compressed images
|
||
|
// in some special situations, such as, network transferring.
|
||
|
// https://github.com/yeqown/go-qrcode/issues/69
|
||
|
type compressedWriter struct {
|
||
|
fd io.WriteCloser
|
||
|
|
||
|
option *Option
|
||
|
}
|
||
|
|
||
|
var (
|
||
|
backgroundColor = color.Gray{Y: 0xff}
|
||
|
foregroundColor = color.Gray{Y: 0x00}
|
||
|
)
|
||
|
|
||
|
func NewCompressedWriter(writer io.WriteCloser, opt *Option) qrcode.Writer {
|
||
|
return compressedWriter{fd: writer, option: opt}
|
||
|
}
|
||
|
|
||
|
func (w compressedWriter) Write(mat qrcode.Matrix) error {
|
||
|
padding := w.option.Padding
|
||
|
blockWidth := w.option.BlockSize
|
||
|
width := mat.Width()*blockWidth + 2*padding
|
||
|
height := width
|
||
|
|
||
|
img := image.NewPaletted(
|
||
|
image.Rect(0, 0, width, height),
|
||
|
color.Palette([]color.Color{backgroundColor, foregroundColor}),
|
||
|
)
|
||
|
bgColor := uint8(img.Palette.Index(backgroundColor))
|
||
|
fgColor := uint8(img.Palette.Index(foregroundColor))
|
||
|
|
||
|
rectangle := func(x1, y1 int, x2, y2 int, img *image.Paletted, color uint8) {
|
||
|
for x := x1; x < x2; x++ {
|
||
|
for y := y1; y < y2; y++ {
|
||
|
pos := img.PixOffset(x, y)
|
||
|
img.Pix[pos] = color
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// background
|
||
|
rectangle(0, 0, width, height, img, bgColor)
|
||
|
|
||
|
mat.Iterate(qrcode.IterDirection_COLUMN, func(x int, y int, v qrcode.QRValue) {
|
||
|
sx := x*blockWidth + padding
|
||
|
sy := y*blockWidth + padding
|
||
|
es := (x+1)*blockWidth + padding
|
||
|
ey := (y+1)*blockWidth + padding
|
||
|
|
||
|
if v.IsSet() {
|
||
|
rectangle(sx, sy, es, ey, img, fgColor)
|
||
|
}
|
||
|
|
||
|
//switch v.IsSet() {
|
||
|
//case false:
|
||
|
// gray = backgroundColor
|
||
|
//default:
|
||
|
// gray = foregroundColor
|
||
|
//}
|
||
|
|
||
|
})
|
||
|
|
||
|
encoder := png.Encoder{CompressionLevel: png.BestCompression}
|
||
|
return encoder.Encode(w.fd, img)
|
||
|
}
|
||
|
|
||
|
func (w compressedWriter) Close() error {
|
||
|
return w.fd.Close()
|
||
|
}
|