package main import ( "fmt" "github.com/gin-gonic/gin" "github.com/nfnt/resize" "github.com/skip2/go-qrcode" "image" "image/draw" "image/jpeg" _ "image/png" "log" "math" "net/http" "os" ) func main() { r := gin.Default() r.GET("/getInCode", GetInCode) r.Static("/s", "./") // 图片是png,所以要import _ "image/png" err := r.Run(":8088") if err != nil { fmt.Println(err) return } } func GetInCode(ctx *gin.Context) { uid := ctx.DefaultQuery("id", "0") filename := "./incode_" + uid + ".jpg" err := GenerateQrcode("http://reg.llmm0613.com/#/?incode="+uid, filename) if err != nil { ctx.JSON(http.StatusInternalServerError, gin.H{ "msg": "生成二维码失败", }) return } if res, ok := CreatePicture("./fullScreenshot.png", filename); ok { // ctx.JSON(http.StatusOK, res) ctx.Data(http.StatusOK, "text/html;charset=utf-8", []byte("<img src='./s/"+res["fileName"].(string)+"'>")) return } ctx.JSON(http.StatusInternalServerError, gin.H{ "msg": "获取失败", }) } func GenerateQrcode(url, filename string) error { return qrcode.WriteFile(url, qrcode.Medium, 256, filename) } // readImgData 从url中获取图片资源 func readImgData(url string) image.Image { // resp, err := http.Get(url) // if err != nil { // log.Println("图片获取失败", err) // return nil // } // defer resp.Body.Close() file, err := os.Open(url) if err != nil { return nil } img, _, err := image.Decode(file) if err != nil { log.Println("图片decode失败", err) return nil } return img } // calculateRatioFit 计算图片缩放后的尺寸 func calculateRatioFit(srcWidth, srcHeight int, defaultWidth, defaultHeight float64) (int, int) { ratio := math.Min(defaultWidth/float64(srcWidth), defaultHeight/float64(srcHeight)) return int(math.Ceil(float64(srcWidth) * ratio)), int(math.Ceil(float64(srcHeight) * ratio)) } // CreatePicture 图片合并,创建图片 func CreatePicture(img1Url, img2Url string) (map[string]interface{}, bool) { returnData := make(map[string]interface{}) if img1Url == "" || img2Url == "" { return nil, false } // 根据图片地址获取图片. img1 := readImgData(img1Url) img2 := readImgData(img2Url) if img1 == nil || img2 == nil { return nil, false } // 图片1缩放 b1 := img1.Bounds() img1Width := b1.Max.X img1Height := b1.Max.Y // 图片2缩放 b2 := img2.Bounds() img2Width := b2.Max.X img2Height := b2.Max.Y w2, h2 := calculateRatioFit(img2Width, img2Height, 150, 150) img2m := resize.Resize(uint(w2), uint(h2), img2, resize.Lanczos3) // 创建源图 fileName := "dst.jpg" file, err := os.Create(fileName) if err != nil { return nil, false } defer func() { err := file.Close() if err != nil { log.Println("CreateGoodsPicture:图片资源关闭错误", err) } }() // 底层画布 jpg := image.NewRGBA(image.Rect(0, 0, img1Width, img1Height)) // 将底图画上去 draw.Draw(jpg, jpg.Bounds().Add(image.Pt(0, 0)), img1, img1.Bounds().Min, draw.Src) // 将二维码画上去 二维码的X轴 Y轴 draw.Draw(jpg, jpg.Bounds().Add(image.Pt(0, 50)), img2m, img2m.Bounds().Min, draw.Src) // jpeg.Encode默认图片质量75% err1 := jpeg.Encode(file, jpg, &jpeg.Options{Quality: 100}) if err1 != nil { log.Println("CreateGoodsPicture:图片png.Encode错误", err1) return nil, false } defer func() { // err := os.Remove(fileName) // if err != nil { // log.Println("CreateGoodsPicture:图片资源删除错误", err) // } }() returnData["fileName"] = fileName return returnData, true }
发表评论