go 实现海报
package main
import (
"fmt"
"github.com/disintegration/imaging"
"github.com/golang/freetype"
"github.com/golang/freetype/truetype"
"image"
"image/color"
"image/draw"
"image/png"
"io/ioutil"
"log"
"net/http"
"os"
)
func main() {
// 根据路径打开模板文件
dir, _ := os.Getwd()
fmt.Println(dir)
dir, err := os.Getwd()
templateFile, err := os.Open(dir + "/test/top_bg2@3x.png")
if err != nil {
panic(err)
}
defer func(templateFile *os.File) {
_ = templateFile.Close()
}(templateFile)
// 解码
templateFileImage, err := png.Decode(templateFile)
if err != nil {
panic(err)
}
// 新建一张和模板文件一样大小的画布
newTemplateImage := image.NewRGBA(image.Rect(0, 0, 1125, 2000))
for x := 0; x < newTemplateImage.Bounds().Dx(); x++ { // 将背景图涂白
for y := 0; y < newTemplateImage.Bounds().Dy(); y++ {
newTemplateImage.Set(x, y, color.White)
}
}
// 加载字体文件
font, err := loadFont(dir + "/test/simsun.ttc")
if err != nil {
log.Panicln(err.Error())
return
}
content := freetype.NewContext()
content.SetFont(font) // 设置字体
content.SetClip(newTemplateImage.Bounds()) //设置可以操作的区域
content.SetDst(newTemplateImage) //设置操作的目标文件
content.SetDPI(72) // 设置字体分辨率
// top
if true {
// 将模板图片画到新建的画布上
draw.Draw(newTemplateImage, templateFileImage.Bounds(), templateFileImage, templateFileImage.Bounds().Min, draw.Over)
content.SetFontSize(40) // 设置字体大小
content.SetSrc(image.White)
_, _ = content.DrawString("D222222222222222", freetype.Pt(255, 208))
_, _ = content.DrawString("2022年06月16日 11:54:03", freetype.Pt(255, 280))
iconNoteFile, _ := os.Open(dir + "/test/icon1.png")
iconNoteImg, _, _ := image.Decode(iconNoteFile)
draw.Draw(newTemplateImage, iconNoteImg.Bounds().Add(image.Pt(900, 100)), iconNoteImg, image.Point{}, draw.Over)
_, _ = content.DrawString("品 质 保 证 值 得 信 赖", freetype.Pt(200, 415))
}
content.SetSrc(image.Black)
lineFile, _ := os.Open(dir + "/test/line.png")
defer func(lineFile *os.File) {
err = lineFile.Close()
}(lineFile)
lineImg, _, _ := image.Decode(lineFile)
// 收货人
if true {
//60-100
consigneeFile, _ := os.Open(dir + "/test/consignee.png")
defer func(consigneeFile *os.File) {
err = consigneeFile.Close()
}(consigneeFile)
consigneeImage, _, _ := image.Decode(consigneeFile)
draw.Draw(newTemplateImage, consigneeImage.Bounds().Add(image.Pt(60, 485)), consigneeImage, image.Point{}, draw.Over)
_, _ = content.DrawString("张三 18888888888", freetype.Pt(230, 520))
//_, _ = content.DrawString("收货人: 张三 18888888888", freetype.Pt(60, 520))
addressFile, _ := os.Open(dir + "/test/address.png")
defer func(addressFile *os.File) {
err = addressFile.Close()
}(addressFile)
addressImage, _, _ := image.Decode(addressFile)
draw.Draw(newTemplateImage, addressImage.Bounds().Add(image.Pt(60, 565)), addressImage, image.Point{}, draw.Over)
_, _ = content.DrawString(" 广东省深圳市宝安区****", freetype.Pt(180, 600))
draw.Draw(newTemplateImage, lineImg.Bounds().Add(image.Pt(25, 660)), lineImg, image.Point{}, draw.Over)
}
goodsDivHeight := 100 //商品块的总高度
dx := newTemplateImage.Bounds().Dx()
//商品
if true {
minHeight := 252
//商品图片
goodsImage, _ := getRemotelyImage("https://dd.jzbull.com/dsx/2010011258/pc/20211129165907c6i9cmvbeupft5d9hrbg.jpg", minHeight, minHeight)
draw.Draw(newTemplateImage, goodsImage.Bounds().Add(image.Pt(60, 700)), goodsImage, image.Point{}, draw.Over)
//商品标题
//字符串截取
_, _ = content.DrawString("多件任选test-重量1111多件任选test-重量1111多件任选test-重量1111多件任选test-重量1111", freetype.Pt(350, 740))
//商品规格
content.SetFontSize(30)
content.SetSrc(image.NewUniform(color.RGBA{R: 142, G: 145, B: 152, A: 255}))
_, _ = content.DrawString("第一件:颜色:黑色aaaaaaaa,尺码:sbbbbbbbbbbbbbbbbbbbbbbbbbbbbb x1", freetype.Pt(350, 750+50))
_, _ = content.DrawString("第二件:颜色:白色,尺码:s x1", freetype.Pt(350, 750+50*2))
_, _ = content.DrawString("第三件:颜色:红色,尺码:s x1", freetype.Pt(350, 750+50*3))
_, _ = content.DrawString("第四件:颜色:蓝色,尺码:s x1", freetype.Pt(350, 750+50*4))
_, _ = content.DrawString("第五件:颜色:黄色,尺码:s x1", freetype.Pt(350, 750+50*5))
//如果规格过多 则 minHeight 增加
minHeight += 100
//价格
content.SetFontSize(40)
content.SetSrc(image.Black)
_, _ = content.DrawString("¥ 59.00", freetype.Pt(350, 750+50*6))
//印章
if true {
authFile, _ := os.Open(dir + "/test/img_2.png")
defer func(authFile *os.File) {
err = authFile.Close()
}(authFile)
authImg, _, _ := image.Decode(authFile)
draw.Draw(newTemplateImage, authImg.Bounds().Add(image.Pt(dx-278, 660)), authImg, image.Point{}, draw.Over)
}
goodsDivHeight += minHeight
draw.Draw(newTemplateImage, lineImg.Bounds().Add(image.Pt(25, 750+50*6+50)), lineImg, image.Point{}, draw.Over)
}
//订单信息
if true {
pointToFixed := content.PointToFixed(40).Round()
startY := 660 + goodsDivHeight + 60
goodsNumStr := "x 114"
startGoodsNumX := getStartX(dx, goodsNumStr, pointToFixed)
//fmt.Println(startGoodsNumX)
goodsTotalFile, _ := os.Open(dir + "/test/goods_total.png")
defer func(goodsTotalFile *os.File) {
err = goodsTotalFile.Close()
}(goodsTotalFile)
goodsTotalImage, _, _ := image.Decode(goodsTotalFile)
draw.Draw(newTemplateImage, goodsTotalImage.Bounds().Add(image.Pt(60, startY-40)), goodsTotalImage, image.Point{}, draw.Over)
//_, _ = content.DrawString("商品数量", freetype.Pt(60, startY))
_, _ = content.DrawString(goodsNumStr, freetype.Pt(startGoodsNumX, startY))
startGoodsAmountStr := "¥ 59.00"
startGoodsAmountX := getStartX(dx, startGoodsAmountStr, pointToFixed) + 20 //微调20个像素
//fmt.Println(startGoodsAmountX)
goodsAmountFile, _ := os.Open(dir + "/test/goods_amount.png")
defer func(goodsAmountFile *os.File) {
err = goodsAmountFile.Close()
}(goodsAmountFile)
goodsAmountImage, _, _ := image.Decode(goodsAmountFile)
draw.Draw(newTemplateImage, goodsAmountImage.Bounds().Add(image.Pt(60, startY+40)), goodsAmountImage, image.Point{}, draw.Over)
//_, _ = content.DrawString("商品总额", freetype.Pt(60, startY+80))
_, _ = content.DrawString(startGoodsAmountStr, freetype.Pt(startGoodsAmountX, startY+80))
startShippingFeeStr := "¥ 0.00"
startShippingFeeX := getStartX(dx, startShippingFeeStr, pointToFixed) + 20
//fmt.Println(startShippingFeeX)
shippingFeeFile, _ := os.Open(dir + "/test/shipping_fee.png")
defer func(shippingFeeFile *os.File) {
err = shippingFeeFile.Close()
}(shippingFeeFile)
shippingFeeImage, _, _ := image.Decode(shippingFeeFile)
draw.Draw(newTemplateImage, shippingFeeImage.Bounds().Add(image.Pt(60, startY+120)), shippingFeeImage, image.Point{}, draw.Over)
//_, _ = content.DrawString("运费", freetype.Pt(60, startY+160))
_, _ = content.DrawString(startShippingFeeStr, freetype.Pt(startShippingFeeX, startY+160))
draw.Draw(newTemplateImage, lineImg.Bounds().Add(image.Pt(25, startY+240)), lineImg, image.Point{}, draw.Over)
startTotalStr := "¥ 59.00"
startTotalX := getStartX(dx, startTotalStr, pointToFixed) + 20
//fmt.Println(startTotalX)
totalFile, _ := os.Open(dir + "/test/total.png")
defer func(totalFile *os.File) {
err = totalFile.Close()
}(totalFile)
totalImage, _, _ := image.Decode(totalFile)
draw.Draw(newTemplateImage, totalImage.Bounds().Add(image.Pt(60, startY+280)), totalImage, image.Point{}, draw.Over)
//_, _ = content.DrawString("合计", freetype.Pt(60, startY+320))
content.SetSrc(image.NewUniform(color.RGBA{R: 237, G: 39, B: 90, A: 255}))
_, _ = content.DrawString(startTotalStr, freetype.Pt(startTotalX, startY+320))
}
saveFile(newTemplateImage)
}
// 根据路径加载字体文件
// path 字体的路径
func loadFont(path string) (font *truetype.Font, err error) {
var fontBytes []byte
fontBytes, err = ioutil.ReadFile(path) // 读取字体文件
if err != nil {
err = fmt.Errorf("加载字体文件出错:%s", err.Error())
return
}
font, err = freetype.ParseFont(fontBytes) // 解析字体文件
if err != nil {
err = fmt.Errorf("解析字体文件出错,%s", err.Error())
return
}
return
}
func saveFile(pic *image.RGBA) {
dstFile, err := os.Create("dst.png")
if err != nil {
fmt.Println(err)
}
defer dstFile.Close()
png.Encode(dstFile, pic)
}
//总宽度 - 自身宽度 - 右侧宽度
func getStartX(dx int, str string, pointToFixed int) int {
return dx - (len(str)+2)*(pointToFixed/2) - 40
}
func getRemotelyImage(filePath string, width int, height int) (*image.NRGBA, error) {
resp, err := http.Get(filePath)
if err != nil {
return nil, err
}
defer resp.Body.Close()
imgDecode, _, err := image.Decode(resp.Body)
//转成缩略图
imgDecode = imaging.Resize(imgDecode, width, height, imaging.Lanczos)
if err != nil {
return nil, err
}
rgba := image.NewNRGBA(image.Rect(0, 0, width, height))
draw.Draw(rgba, rgba.Bounds(), imgDecode, image.Point{}, draw.Src)
return rgba, nil
}
作者:admin 创建时间:2022-06-20 11:09
最后编辑:admin 更新时间:2023-04-10 15:46
最后编辑:admin 更新时间:2023-04-10 15:46