package coryCommon import ( "fmt" "github.com/fogleman/gg" "github.com/nfnt/resize" "image/color" "log" "os" "path/filepath" "strings" ) func GetCWD() string { cwd, _ := os.Getwd() return filepath.ToSlash(cwd) } func MultiPicture(pictureList string, compere string, meetingDate string, site string, teamName string, labourserviceName string) { //1、分割字符串 split := strings.Split(pictureList, ",") //2、循环添加水印 for i := range split { filePath := split[i] newPath := strings.ReplaceAll(filePath, "/wxfile", GetCWD()+"/resource/public") newPath = strings.ReplaceAll(newPath, "\\", "/") WatermarkFunc(newPath, compere, meetingDate, site, teamName, labourserviceName) } } // WatermarkFunc 给图片设置水印和logo func WatermarkFunc(filePath string, compere string, meetingDate string, site string, teamName string, labourserviceName string) { // 检查文件是否存在 _, err := os.Stat(filePath) if err != nil { if os.IsNotExist(err) { fmt.Println("文件不存在") } else { fmt.Println("发生错误:", err) } return } //// 获取文件名和后缀 //fileName := filepath.Base(filePath) //fileExt := filepath.Ext(filePath) //1、加载图片 srcImage, err := gg.LoadImage(filePath) if err != nil { log.Fatalf("打开图片失败: %v", err) } //2、加载logo水印 dc := gg.NewContextForImage(srcImage) dc.SetRGB(1, 1, 1) logoImage, err := gg.LoadImage(GetCWD() + "/resource/cory/zmlogo.jpg") if err != nil { log.Fatalf("打开 logo 图片失败: %v", err) } logoWidth := 80.0 logoHeight := float64(logoImage.Bounds().Dy()) * (logoWidth / float64(logoImage.Bounds().Dx())) logoImage = resize.Resize(uint(logoWidth), uint(logoHeight), logoImage, resize.Lanczos3) x := float64(logoWidth) + 10.0 y := float64(dc.Height()/2) + 96.0 dc.DrawImageAnchored(logoImage, int(x), int(y), 1.0, 1.0) //3、设置字体 fontPath := GetCWD() + "/resource/cory/msyh.ttc" if err != nil { log.Fatalf("加载字体失败: %v", err) } dc.SetRGB(0, 0, 0) //4、创建矩形框 背景透明 boxText := teamName dc.SetRGBA255(0, 99, 175, 100) rectangleX := x rectangleY := y - logoHeight + 1 rectangleWidth := len(boxText) * 8 rectangleHeight := logoHeight - 1 dc.DrawRectangle(rectangleX, rectangleY, float64(rectangleWidth), rectangleHeight) dc.Fill() textFunc(dc, boxText, fontPath, 18.0, rectangleX, rectangleY, float64(rectangleWidth), rectangleHeight, 1) //5、添加文字水印 text := "开会宣讲人:" + compere + "\n \n" + "开 会 时 间:" + meetingDate + "\n \n" + //"天 气:多云转晴\n \n" + "地 点:" + site + "\n \n" textX := x - logoWidth textY := y + 10 err = dc.LoadFontFace(fontPath, 12) dc.DrawStringWrapped(text, textX, textY, 0.0, 0.0, float64(dc.Width())-textX, 1.2, gg.AlignLeft) //6、创建矩形框 渐变透明 boxText = labourserviceName width := len(boxText) * 8 height := 30 fromAlpha := 0.6 toAlpha := 0 for x := 0; x <= width; x++ { alpha := fromAlpha - (fromAlpha-float64(toAlpha))*(float64(x)/float64(width)) rgba := color.RGBA{G: 99, B: 175, A: uint8(alpha * 255)} dc.SetRGBA255(int(rgba.R), int(rgba.G), int(rgba.B), int(rgba.A)) dc.DrawLine(float64(x)+10, y+96, float64(x)+10, y+96+float64(height)) dc.StrokePreserve() dc.Fill() } textFunc(dc, boxText, fontPath, 16.0, 10.0, y+96, float64(width), float64(height), 2) //7、保存图片 err = dc.SavePNG(filePath) if err != nil { log.Fatalf("保存带水印的图片失败: %v", err) } } func textFunc(dc *gg.Context, boxText string, fontPath string, boxTextSize, rectangleX, rectangleY, rectangleWidth, rectangleHeight float64, num int) { err := dc.LoadFontFace(fontPath, boxTextSize) if err != nil { log.Fatalf("加载字体失败: %v", err) } dc.SetRGB(1, 1, 1) boxTextWidth, boxTextHeight := dc.MeasureString(boxText) boxTextX := 0.00 if num == 1 { boxTextX = rectangleX + (rectangleWidth-boxTextWidth)/2 } else if num == 2 { boxTextX = 10 } else { log.Fatalf("对齐方式错误") } boxTextY := rectangleY + (rectangleHeight-boxTextHeight)/2 + boxTextHeight dc.DrawStringAnchored(boxText, boxTextX, boxTextY, 0.0, 0.0) } // 绘制矩形框 func Test_draw_rect_text(im_path string, x, y, w, h float64) { // Load image //font_path := GetCWD() + "/resource/cory/msyh.ttc" im, err := gg.LoadImage(im_path) if err != nil { log.Fatal(err) } // 2 method dc := gg.NewContextForImage(im) // Set color and line width dc.SetHexColor("#FF0000") dc.SetLineWidth(4) // DrawRoundedRectangle 使用 DrawRoundedRectangle 方法在图像上绘制一个带有圆角的矩形。这里 x, y 是矩形左上角的坐标,w, h 是矩形的宽度和高度,最后的 0 表示圆角的半径为0。 dc.DrawRoundedRectangle(x, y, w, h, 0) // Store set dc.Stroke() dc.DrawRectangle(x, y, w, h) dc.Clip() // Save png image dc.SavePNG(im_path) } type TestDrawRectTextEntity struct { ImPath string `json:"im_path"` Coordinates []*CoordinatesListEntity `json:"coordinates"` } type CoordinatesListEntity struct { X float64 `json:"x"` Y float64 `json:"y"` W float64 `json:"w"` H float64 `json:"h"` } // TestDrawRectTextFunc 同一文件多次绘制矩形框 func TestDrawRectTextFunc(entity *TestDrawRectTextEntity) { if entity == nil { return } if len(entity.Coordinates) == 0 { return } // 加载图像 im, err := gg.LoadImage(entity.ImPath) // 加载图像一次 if err != nil { log.Fatal(err) } // 创建上下文 dc := gg.NewContextForImage(im) // 设置颜色和线宽 dc.SetHexColor("#FF0000") dc.SetLineWidth(4) //绘制和保存矩形 for _, zuobiao := range entity.Coordinates { // 绘制矩形 dc.DrawRoundedRectangle(zuobiao.X, zuobiao.Y, zuobiao.W, zuobiao.H, 0) } dc.Stroke() // 保存图像 dc.SavePNG(entity.ImPath) }