200 lines
5.7 KiB
Go
200 lines
5.7 KiB
Go
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)
|
||
}
|