Files
qr_labels/main.go

149 lines
3.3 KiB
Go
Raw Normal View History

2026-04-28 08:26:35 +09:30
package main
import (
"fmt"
2026-04-28 10:52:48 +09:30
"log/slog"
2026-04-28 08:26:35 +09:30
"codeberg.org/go-pdf/fpdf"
"github.com/yeqown/go-qrcode/v2"
"github.com/yeqown/go-qrcode/writer/standard"
)
var cols = 4
2026-04-28 10:52:48 +09:30
var rows = 4
var qrSize = 50.0
var fontSize = 16.0 // pts
var fontSizeMM = fontSize / 72 * 25.4
var text = "meow!"
var textTopPadding = 5.0
var qrTopPadding = 5.0
// var probably some padding instead of offsets for qr/font placement
2026-04-28 08:26:35 +09:30
func main() {
2026-04-28 10:52:48 +09:30
qrc, err := qrcode.New("https://nanocat.net/dom/sdfih/dsifj/sidhof/sdifho/sdfiuoh/safiuho")
2026-04-28 08:26:35 +09:30
if err != nil {
fmt.Printf("could not generate QRCode: %v", err)
return
}
b := newBWC()
qrBytes := standard.NewWithWriter(&b,
2026-04-28 09:45:18 +09:30
// standard.WithQRWidth(uint8(qrSize)),
standard.WithBorderWidth(0),
2026-04-28 08:26:35 +09:30
standard.WithBuiltinImageEncoder(standard.PNG_FORMAT),
2026-04-28 10:52:48 +09:30
// standard.WithCircleShape(),
// standard.WithFgGradient(&standard.LinearGradient{
// Stops: []standard.ColorStop{{
// T: 0.0,
// Color: color.RGBA{
// R: 255,
// G: 0,
// B: 0,
// A: 0,
// },
// }, {
// T: 1.0,
// Color: color.RGBA{
// R: 0,
// G: 255,
// B: 0,
// A: 0,
// },
// }},
// Angle: 45,
// }),
2026-04-28 08:26:35 +09:30
)
// save file
if err = qrc.Save(qrBytes); err != nil {
fmt.Printf("could not save image: %v", err)
}
2026-04-28 09:45:18 +09:30
// dim := qrc.Dimension()
2026-04-28 08:26:35 +09:30
pdf := fpdf.New("P", "mm", "A4", "")
2026-04-28 09:45:18 +09:30
pdf.SetMargins(0, 0, 0)
2026-04-28 08:26:35 +09:30
pageWidth, pageHeight := pdf.GetPageSize()
// register the qr
pdf.RegisterImageOptionsReader("qr", fpdf.ImageOptions{
ImageType: "png",
ReadDpi: false,
AllowNegativePosition: false,
}, b)
2026-04-28 10:52:48 +09:30
// info := pdf.GetImageInfo("qr")
2026-04-28 09:45:18 +09:30
// panic(info.Height())
2026-04-28 08:26:35 +09:30
pdf.AddPage()
2026-04-28 09:45:18 +09:30
pdf.SetFont("Arial", "B", float64(fontSize))
2026-04-28 08:26:35 +09:30
textWidth := pdf.GetStringWidth(text)
colWidth := pageWidth / float64(cols)
rowHeight := pageHeight / float64(rows)
2026-04-28 10:52:48 +09:30
// qrRowRatio := qrSize / rowHeight
// qrColRatio := qrSize / colWidth
// fmt.Printf("qr/row height ratio: %.2f\n", qrRowRatio)
// fmt.Printf("qr/col width ratio: %.2f\n", qrColRatio)
if textTopPadding+fontSizeMM+qrTopPadding+qrSize > rowHeight {
slog.Warn("qr is too big for row")
}
if qrSize > colWidth {
slog.Warn("qr is too big for column")
}
if textWidth > colWidth {
slog.Warn("text probably too wide")
}
2026-04-28 09:45:18 +09:30
for rowIdx := range rows {
for colIdx := range cols {
topLeftX := colWidth * float64(colIdx)
topLeftY := rowHeight * float64(rowIdx)
// if rowHeight*0.8 < float64(qrSize) {
// panic("row too small for qr")
// }
// if colWidth*0.6 < float64(qrSize) {
// panic("col too small for qr")
// }
// label at the top
pdf.Text(
topLeftX+colWidth/2-textWidth/2,
2026-04-28 10:52:48 +09:30
topLeftY+textTopPadding+fontSizeMM,
2026-04-28 09:45:18 +09:30
text, // +fmt.Sprintf("%d/%d", rowIdx, colIdx)
)
2026-04-28 10:52:48 +09:30
// qr at the bottom
2026-04-28 09:45:18 +09:30
pdf.ImageOptions("qr",
2026-04-28 10:52:48 +09:30
topLeftX+colWidth/2-qrSize/2, //+float64(dim)/2, // centre
topLeftY+textTopPadding+fontSizeMM+qrTopPadding, // centre, below text line
qrSize, qrSize,
2026-04-28 09:45:18 +09:30
false,
fpdf.ImageOptions{AllowNegativePosition: true}, 0, "")
// pdf.Image("qr",
// topLeftX+5, // centre
// topLeftY+float64(fontSize)*1.3, // centre
// float64(qrSize),
// float64(qrSize),
// false, "tp", 0, "")
2026-04-28 08:26:35 +09:30
}
}
err = pdf.OutputFileAndClose("hello.pdf")
if err != nil {
panic(err)
}
fmt.Println(pageWidth, pageHeight)
}