commit 9ef734816eefafe905ccd7f3c0c55ce1fd0b31e6
Author: dtapps
Date: Fri Dec 22 13:13:11 2023 +0800
init
diff --git a/.drone.yml b/.drone.yml
new file mode 100644
index 0000000..c56c479
--- /dev/null
+++ b/.drone.yml
@@ -0,0 +1,17 @@
+kind: pipeline
+type: docker
+name: clone
+
+steps:
+ - name: Test
+ image: golang:1.18
+ commands:
+ - go env -w GO111MODULE=on
+ - go env -w GOPROXY=https://goproxy.cn,direct
+ - go test -v ./...
+ - name: Benchmark
+ image: golang:1.18
+ commands:
+ - go env -w GO111MODULE=on
+ - go env -w GOPROXY=https://goproxy.cn,direct
+ - go test -bench=. -benchmem
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..760d251
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+.env
+.git
+.svn
+.idea
+.vscode
+*.log
+gomod.sh
+*_test.go
+/vendor/
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..ff84bbf
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2018 李光春
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..7becdbd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,17 @@
+
+
+📦 Golang goqc
+
+[comment]: <> (go)
+[![godoc](https://pkg.go.dev/badge/go.dtapp.net/goqc?status.svg)](https://pkg.go.dev/go.dtapp.net/goqc)
+[![goproxy.cn](https://goproxy.cn/stats/go.dtapp.net/goqc/badges/download-count.svg)](https://goproxy.cn/stats/go.dtapp.net/goqc)
+[![goreportcard.com](https://goreportcard.com/badge/go.dtapp.net/goqc)](https://goreportcard.com/report/go.dtapp.net/goqc)
+[![deps.dev](https://img.shields.io/badge/deps-go-red.svg)](https://deps.dev/go/go.dtapp.net%2Fgoqc)
+
+#### 安装
+
+```shell
+go get -v -u go.dtapp.net/goqc@v1.0.0
+```
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..3b60f3d
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,12 @@
+module go.dtapp.net/goqc
+
+go 1.21
+
+require (
+ github.com/fogleman/gg v1.3.0
+ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0
+ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
+ github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e
+)
+
+require golang.org/x/image v0.14.0 // indirect
diff --git a/go.sum b/go.sum
new file mode 100644
index 0000000..999d1d7
--- /dev/null
+++ b/go.sum
@@ -0,0 +1,10 @@
+github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
+github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
+github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
+github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
+github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0=
+github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e/go.mod h1:XV66xRDqSt+GTGFMVlhk3ULuV0y9ZmzeVGR4mloJI3M=
+golang.org/x/image v0.14.0 h1:tNgSxAFe3jC4uYqvZdTr84SZoM1KfwdC9SKIFrLjFn4=
+golang.org/x/image v0.14.0/go.mod h1:HUYqC05R2ZcZ3ejNQsIHQDQiwWM4JBqmm6MKANTp4LE=
diff --git a/goqc_text.go b/goqc_text.go
new file mode 100644
index 0000000..a9e5c77
--- /dev/null
+++ b/goqc_text.go
@@ -0,0 +1,129 @@
+package goqc
+
+import (
+ "bytes"
+ "context"
+ "embed"
+ _ "embed"
+ "github.com/fogleman/gg"
+ "github.com/golang/freetype/truetype"
+ "github.com/nfnt/resize"
+ "github.com/skip2/go-qrcode"
+ "image/png"
+ "io"
+ "path/filepath"
+)
+
+//go:embed simhei.ttf
+var fontContent embed.FS
+var fontPath = "simhei.ttf"
+var fontSize = 16.0
+
+func loadFontPath(dc *gg.Context) error {
+ // 设置字体和文本属性
+ err := dc.LoadFontFace(fontPath, fontSize)
+ if err != nil {
+ return err
+ }
+ return nil
+}
+
+func loadFontEmbed(dc *gg.Context) error {
+ // 读取嵌入的字体文件
+ fontBytes, err := fontContent.ReadFile(fontPath)
+ if err != nil {
+ return err
+ }
+ // 设置字体
+ f, err := truetype.Parse(fontBytes)
+ if err != nil {
+ return err
+ }
+ // 文本属性
+ face := truetype.NewFace(f, &truetype.Options{
+ Size: fontSize,
+ })
+ dc.SetFontFace(face)
+ return nil
+}
+
+// QrCodeOperation 二维码操作
+type QrCodeOperation struct {
+ ctx context.Context
+ dc *gg.Context
+}
+
+// QrCodeText 生成二维码带文本
+func QrCodeText(ctx context.Context, textContent string, qcContent string, qcLevel qrcode.RecoveryLevel) (*QrCodeOperation, error) {
+
+ // 生成二维码
+ qr, err := qrcode.New(qcContent, qcLevel)
+ if err != nil {
+ return nil, err
+ }
+
+ // 设置二维码图片的大小
+ qrSize := 256
+
+ // 生成二维码图片
+ qrImage := qr.Image(qrSize)
+
+ // 调整二维码图片大小
+ qrImage = resize.Resize(uint(qrSize), uint(qrSize), qrImage, resize.Lanczos3)
+
+ // 使用 github.com/fogleman/gg 绘制文本
+ dc := gg.NewContext(qrSize, qrSize)
+ dc.DrawImage(qrImage, 0, 0)
+
+ // 设置字体和文本属性
+ err = loadFontEmbed(dc)
+ if err != nil {
+ return nil, err
+ }
+
+ // 设置文本颜色
+ dc.SetRGB(0, 0, 0)
+
+ // 计算文本尺寸
+ textWidth, textHeight := dc.MeasureString(textContent)
+
+ // 计算文本位置
+ x := (float64(qrSize) - textWidth) / 2
+ y := (float64(qrSize+qrSize) + textHeight - textHeight) / 2
+
+ // 绘制文本
+ dc.DrawStringAnchored(textContent, x, y-6, 0, 0)
+
+ return &QrCodeOperation{ctx: ctx, dc: dc}, err
+}
+
+// SavePNG 保存图片
+func (o *QrCodeOperation) SavePNG(filePath, fileName string) error {
+ if fileName == "" {
+ return o.dc.SavePNG(filePath)
+ } else {
+ path := filepath.Join(filePath, "/", fileName)
+ return o.dc.SavePNG(path)
+ }
+}
+
+// Encode 返回图片字节
+func (o *QrCodeOperation) Encode() ([]byte, error) {
+ img := o.dc.Image()
+
+ encoder := png.Encoder{CompressionLevel: png.BestCompression}
+
+ var b bytes.Buffer
+ err := encoder.Encode(&b, img)
+
+ if err != nil {
+ return nil, err
+ }
+
+ return b.Bytes(), nil
+}
+
+// EncodePNG 返回图片编码
+func (o *QrCodeOperation) EncodePNG(w io.Writer) error {
+ return o.dc.EncodePNG(w)
+}
diff --git a/simhei.ttf b/simhei.ttf
new file mode 100644
index 0000000..5bd4687
Binary files /dev/null and b/simhei.ttf differ
diff --git a/version.go b/version.go
new file mode 100644
index 0000000..732860f
--- /dev/null
+++ b/version.go
@@ -0,0 +1,5 @@
+package goqc
+
+const (
+ Version = "1.0.0"
+)