Files
zmkgC/api/v1/common/coryCommon/watermark.go
2025-07-07 20:11:59 +08:00

200 lines
5.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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)
}