// Package utils ----------------------------- // @file : qrCode.go // @author : JJXu // @contact : wavingbear@163.com // @time : 2023/3/8 18:01 // ------------------------------------------- package utils import ( "bytes" "encoding/base64" "fmt" "github.com/fonchain_enterprise/fonchain-main/pkg/config" "image" "image/color" "image/draw" "image/jpeg" "image/png" "io" "io/ioutil" "log" "mime/multipart" "net/http" "os" "strings" "github.com/fonchain_enterprise/utils/objstorage" "github.com/fonchain_enterprise/utils/utils" "github.com/golang/freetype" "github.com/nfnt/resize" "github.com/skip2/go-qrcode" "golang.org/x/image/font" ) 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 //return "data:image/png;base64," + base64.StdEncoding.EncodeToString(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 CreateQrCode(invitedCode, userName string) error { QrCodePath, err := utils.GenQRCode("https://artist.fontree.cn/login?invitedCode=" + invitedCode) if err != nil { return err } tmp, err := os.Open(QrCodePath) defer tmp.Close() if err != nil { return err } // tmp, _ := file.Open() src, err := os.Open("./qrcodebg.png") defer src.Close() if err != nil { log.Println(err) return err } img, err := png.Decode(src) if err != nil { log.Println(err) return err } outimage, _ := addLabel(img, userName+"邀请您注册画家宝用户", 210, 300, color.RGBA{255, 255, 255, 255}, 55, "font1716.ttf") outimage, _ = addLabel(outimage, "(使用此二维码后,"+userName+"将成为你的邀请人)", 210, 400, color.RGBA{255, 255, 255, 255}, 38, "font1716.ttf") outimage, _ = addLabel(outimage, "邀请码:"+invitedCode, 260, 1340, color.RGBA{69, 137, 239, 255}, 70, "font1716.ttf") QrCode2Path := "static/qrcode/" + invitedCode + "-2.png" f, err := os.Create(QrCode2Path) if err != nil { log.Println(err) return err } defer f.Close() newImg := image.NewNRGBA(image.Rect(0, 0, 1125, 2436)) // fe, err := os.Open("./" + artistPhoto.SmallPic + "_small.jpg") qrImg, err := png.Decode(tmp) if err != nil { fmt.Println(err.Error()) return err } qrImg = resize.Resize(uint(700), uint(700), qrImg, resize.Lanczos3) draw.Draw(newImg, newImg.Bounds(), outimage, outimage.Bounds().Min.Sub(image.Pt(0, 0)), draw.Over) draw.Draw(newImg, newImg.Bounds(), qrImg, qrImg.Bounds().Min.Sub(image.Pt(210, 570)), draw.Over) err = png.Encode(f, newImg) if err != nil { return err } tmp.Close() tmps, err := os.OpenFile(QrCodePath, os.O_RDWR|os.O_CREATE, 0777) defer tmps.Close() if err != nil { return err } urlss, err := UploadToBos(tmps, fmt.Sprintf("artistmgmt/static/qrcode/%v.png", invitedCode)) if err != nil { return err } fmt.Println(urlss) tmp2, err := os.Open(QrCode2Path) defer tmp2.Close() if err != nil { return err } str, err := UploadToBos(tmp2, fmt.Sprintf("artistmgmt/static/qrcode/%v-2.png", invitedCode)) if err != nil { return err } fmt.Println(str, "===============") return nil } func addLabel(img image.Image, label string, x, y int, fontColor color.Color, size float64, fontPath string) (image.Image, error) { bound := img.Bounds() // 创建一个新的图片 rgba := image.NewRGBA(image.Rect(0, 0, bound.Dx(), bound.Dy())) // 读取字体 fontBytes, err := ioutil.ReadFile(fontPath) if err != nil { return rgba, err } myFont, err := freetype.ParseFont(fontBytes) if err != nil { return rgba, err } draw.Draw(rgba, rgba.Bounds(), img, bound.Min, draw.Src) c := freetype.NewContext() c.SetDPI(72) c.SetFont(myFont) c.SetFontSize(size) c.SetClip(rgba.Bounds()) c.SetDst(rgba) uni := image.NewUniform(fontColor) c.SetSrc(uni) c.SetHinting(font.HintingNone) // 在指定的位置显示 pt := freetype.Pt(x, y+int(c.PointToFixed(size)>>6)) if _, err := c.DrawString(label, pt); err != nil { return rgba, err } return rgba, nil } const ( URL = "https://cdn.fontree.cn" AK = "e102c02f0a7843d29a8abe561a17913e" SK = "a6042bb43d4747259a7da72133cc5ce6" Bucket = "dci-file" ) // 封装上传图片到bos然后返回状态和图片的url,单张 func UploadToBos(file multipart.File, objName string) (string, error) { BOSClient, err := objstorage.NewOSS(config.ConfigData.Oss.AccessKeyId, config.ConfigData.Oss.AccessKeySecret, config.ConfigData.Oss.Endpoint) if err != nil { fmt.Println(err) } b := new(strings.Builder) io.Copy(b, file) _, err = BOSClient.PutObjectFromBytes(config.ConfigData.Oss.BucketName, objName, []byte(b.String())) if err != nil { return "", err } url := config.ConfigData.Oss.CdnHost + "/" + objName return url, nil }