132 lines
3.1 KiB
Go
132 lines
3.1 KiB
Go
package qr
|
||
|
||
import (
|
||
"archive/zip"
|
||
"bytes"
|
||
"encoding/base64"
|
||
"fmt"
|
||
"image"
|
||
"image/draw"
|
||
"image/jpeg"
|
||
"image/png"
|
||
"io"
|
||
"net/http"
|
||
"os"
|
||
"path/filepath"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/nfnt/resize"
|
||
"github.com/skip2/go-qrcode"
|
||
)
|
||
|
||
func CreateQr(content string, logoUrl string) (qr string, err error) {
|
||
emptyBuff, err := CreateQrBase(content, logoUrl)
|
||
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
return string(emptyBuff.Bytes()), nil
|
||
}
|
||
|
||
func CreateQrBase64(content string, logoUrl string) (qr string, err error) {
|
||
|
||
emptyBuff, err := CreateQrBase(content, logoUrl)
|
||
if err != nil {
|
||
return "", err
|
||
}
|
||
|
||
//return string(emptyBuff.Bytes()), nil
|
||
return "data:image/png;base64," + base64.StdEncoding.EncodeToString(emptyBuff.Bytes()), nil
|
||
}
|
||
|
||
func CreateQrBase(content string, logoUrl string) (emptyBuff *bytes.Buffer, err error) {
|
||
emptyBuff = bytes.NewBuffer(nil) //开辟一个新的空buff
|
||
|
||
qrC, err := qrcode.New(content, qrcode.Low)
|
||
img := qrC.Image(460)
|
||
|
||
if err != nil {
|
||
return
|
||
}
|
||
|
||
total := image.NewRGBA(img.Bounds()) //设置背景
|
||
draw.Draw(total, total.Bounds(), img, img.Bounds().Min, draw.Over)
|
||
|
||
if logoUrl != "" { //是否有logo
|
||
v, err := http.Get(logoUrl)
|
||
if err != nil {
|
||
fmt.Printf("Http get [%v] failed! %v", logoUrl, err)
|
||
return emptyBuff, err
|
||
}
|
||
defer v.Body.Close()
|
||
|
||
icoImg2, _ := png.Decode(v.Body)
|
||
|
||
icoImg := resize.Resize(54, 52, icoImg2, resize.Lanczos3)
|
||
|
||
icoImgPnt := image.Point{(total.Bounds().Size().X - icoImg.Bounds().Size().X) / -2, (total.Bounds().Size().Y - icoImg.Bounds().Size().Y) / -2}
|
||
draw.DrawMask(total, total.Bounds(), icoImg, icoImgPnt, nil, image.Point{}, draw.Src)
|
||
}
|
||
|
||
err = jpeg.Encode(emptyBuff, total, nil)
|
||
if err != nil {
|
||
return emptyBuff, err
|
||
}
|
||
return emptyBuff, nil
|
||
}
|
||
|
||
func ImagesOnZip(c *gin.Context, tempDir string) {
|
||
// 创建ZIP文件并添加下载的图片
|
||
zipFilename := "./collection.zip"
|
||
zipFile, err := os.Create(zipFilename)
|
||
if err != nil {
|
||
c.String(http.StatusInternalServerError, fmt.Sprintf("Failed to create ZIP file: %v", err))
|
||
return
|
||
}
|
||
defer zipFile.Close()
|
||
|
||
zipWriter := zip.NewWriter(zipFile)
|
||
defer zipWriter.Close()
|
||
|
||
err = filepath.Walk(tempDir, func(path string, info os.FileInfo, err error) error {
|
||
if err != nil {
|
||
return err
|
||
}
|
||
if info.IsDir() {
|
||
return nil
|
||
}
|
||
relPath, err := filepath.Rel(tempDir, path)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
file, err := os.Open(path)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
defer file.Close()
|
||
zipEntry, err := zipWriter.Create(relPath)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
_, err = io.Copy(zipEntry, file)
|
||
if err != nil {
|
||
return err
|
||
}
|
||
return nil
|
||
})
|
||
if err != nil {
|
||
c.String(http.StatusInternalServerError, fmt.Sprintf("Failed to create ZIP file: %v", err))
|
||
return
|
||
}
|
||
if err := zipWriter.Close(); err != nil {
|
||
fmt.Println("Close error: ", err)
|
||
}
|
||
// 设置响应头,将ZIP文件作为文件流传输给前端
|
||
c.Header("Content-Type", "application/octet-stream")
|
||
c.Header("Content-Disposition", "attachment; filename="+filepath.Base(zipFilename))
|
||
c.Header("Content-Transfer-Encoding", "binary")
|
||
c.Header("Cache-Control", "no-cache")
|
||
c.File(zipFilename)
|
||
}
|