代码写春联【百度AI智能春联Golang版】

工程结构

├─cmd // 程序入口
├─img // 图片
├─lib // 依赖库
│  └─font
│      └─config
├─res // 输出
└─util // 工具

cmd

package main

import (
	"flag"
	uuid "github.com/satori/go.uuid"
	"mock/lib/font/config"
	. "mock/util"
)

func main() {
	// 命令行指令
	flag.Parse()

	// ================== 参数处理

	// 处理字符
	var charset []string
	if len(*Char) == 0 {
		charset = []string{"你", "好", "世", "界"}
	} else {
		for _, v := range *Char {
			charset = append(charset, string(v))
		}
	}

	// 输出路径
	outPath := ""
	if len(*Out) == 0 {
		outPath = "../res/" + uuid.NewV4().String() + ".png"
	} else {
		outPath = "../res/" + *Out + ".png"
	}

	// 处理方向
	horV := "H"
	
	switch *HorV {
	default:
		horV = "H"
	case "V":
		horV = "V"
	}

	// 处理字体
	font := config.Font_2
	
	switch *Font {
	default:
		font = config.Font_2
	case "f2":
		font = config.Font_2
	}

	// 生成对联
	Generator(charset, outPath, horV, font)

}

lib/config

package config

type TextFont struct {
	FontName string  // 字体名称
	FontSize float64 // 字体大小
	X, Y     int     // 字体渲染位置
}

var Font_1 = TextFont{"方正楷体简体.ttf", 390, 60, 520}

var Font_2 = TextFont{"演示夏行楷.ttf", 390, 0, 550}

util

package util

import (
	"flag"
	"github.com/golang/freetype"
	"image"
	"image/color"
	"image/png"
	"io/ioutil"
	"log"
	. "mock/lib/font/config"
	"os"
)

// charset 中文文字
// horV - H-横排,V-竖排
// out 输出文件名
// font 字体
var (
	Char = flag.String("charset", "你好世界", "text (ZH)")
	HorV = flag.String("horV", "H", "H | V")
	Out  = flag.String("out", "", "output file name")
	Font = flag.String("font", "f1", "f1 | f2")
)

func Generator(charset []string, outPath string, horV string, textFont TextFont) {

	// 打开背景图
	bgFile, err := os.OpenFile("./img/bg.png", os.O_RDONLY, 6)
	if err != nil {
		log.Fatal(err)
	}

	defer bgFile.Close()

	// 解码
	i, err := png.Decode(bgFile)
	if err != nil {
		log.Fatal(err)
	}

	// 图片的宽度
	srcWidth := 640
	// 图片的高度
	srcHeight := 640

	if horV == "H" {
		srcWidth = 640 * len(charset)
	}

	if horV == "V" {
		srcHeight = 640 * len(charset)
	}

	imgFile, _ := os.Create(outPath)
	defer imgFile.Close()
	img := image.NewRGBA(image.Rect(0, 0, srcWidth, srcHeight))

	if horV == "H" {
		log.Println("横向生成,渲染背景...")
		// 根据字符长度创建背景
		for index := 0; index < len(charset); index++ {
			// 复制背景图
			for y := 0; y < srcHeight; y++ {
				for x := index * 640; x < srcWidth; x++ {
					if x < 640 {
						img.Set(x, y, i.At(x, y))
					} else {
						img.Set(x, y, i.At(x-index*640, y))
					}
				}
			}
		}
	}

	if horV == "V" {
		log.Println("竖向生成,渲染背景...")
		// 根据字符长度创建背景
		for index := 0; index < len(charset); index++ {
			// 复制背景图
			for y := index * 640; y < srcHeight; y++ {
				for x := 0; x < srcWidth; x++ {
					if y < 640 {
						img.Set(x, y, i.At(x, y))
					} else {
						img.Set(x, y, i.At(x, y-index*640))
					}
				}
			}
		}
	}

	// 读取字体数据
	fontFileName := "./lib/font/" + textFont.FontName
	fontBytes, err := ioutil.ReadFile(fontFileName)
	log.Printf("加载字体:%s...", textFont.FontName)
	if err != nil {
		log.Fatal(err)
	}

	// 载入字体数据
	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		log.Println("载入字体失败!", err)
	}
	f := freetype.NewContext()
	// 设置分辨率
	f.SetDPI(100)
	// 设置字体
	f.SetFont(font)
	// 设置尺寸
	f.SetFontSize(textFont.FontSize)
	f.SetClip(img.Bounds())
	// 设置输出的图片
	f.SetDst(img)
	// 设置字体颜色(黑色)
	f.SetSrc(image.NewUniform(color.Black))

	if horV == "H" {
		log.Println("开始绘制对联...")
		// 绘制字符
		for index := 0; index < len(charset); index++ {
			// 设置字体的位置
			pt := freetype.Pt(textFont.X+index*640, textFont.Y)

			_, err = f.DrawString(charset[index], pt)
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	if horV == "V" {
		// 绘制字符
		for index := 0; index < len(charset); index++ {
			// 设置字体的位置
			pt := freetype.Pt(textFont.X, textFont.Y+index*640)

			_, err = f.DrawString(charset[index], pt)
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	// 以png 格式写入文件作为输出
	err = png.Encode(imgFile, img)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Done.")
}

方正楷体测试

方正楷体、演示夏行楷都是可以免费商用的字体,测试这两种字体为例。

横向对联

D:\GoFiles\mock-exls\cmd>go build

D:\GoFiles\mock-exls\cmd>cmd.exe -help
Usage of cmd.exe:
  -charset string
        text (ZH) (default "你好世界")
  -font string
        f1 | f2 (default "f1")
  -horV string
        H | V (default "H")
  -out string
        output file name

D:\GoFiles\mock-exls\cmd>cmd.exe -charset "既许一人以偏爱"
2022/01/22 16:30:26 横向生成,渲染背景...
2022/01/22 16:30:27 加载字体:方正楷体简体...
2022/01/22 16:30:27 开始绘制对联...
2022/01/22 16:30:27 Done.

D:\GoFiles\mock-exls\cmd>cmd.exe -charset "愿尽余生之慷慨"
2022/01/22 16:31:17 横向生成,渲染背景...
2022/01/22 16:31:18 加载字体:方正楷体简体...
2022/01/22 16:31:18 开始绘制对联...
2022/01/22 16:31:18 Done.

效果

竖向对联

D:\GoFiles\mock-exls\cmd>cmd.exe -charset "算法数据思路清晰" -horV "V"
2022/01/22 16:52:13 竖向生成,渲染背景...
2022/01/22 16:52:14 加载字体:方正楷体简体...
2022/01/22 16:52:14 Done.

D:\GoFiles\mock-exls\cmd>cmd.exe -charset "编译链接一气呵成" -horV "V"
2022/01/22 16:52:45 竖向生成,渲染背景...
2022/01/22 16:52:45 加载字体:方正楷体简体...
2022/01/22 16:52:45 Done.

D:\GoFiles\mock-exls\cmd>cmd.exe -charset "码到功成"
2022/01/22 16:53:30 横向生成,渲染背景...
2022/01/22 16:53:30 加载字体:方正楷体简体...
2022/01/22 16:53:30 开始绘制对联...
2022/01/22 16:53:30 Done.

效果

春联测试

演示夏行楷测试

 

引用百度AI生成智能春联

工程目录变动

├─cmd
├─img
├─lib
│  └─font
│      └─config
├─res
├─sys // 新增系统变量
└─util

新增百度AI工具类

package util

import (
	"encoding/json"
	"fmt"
	"io/ioutil"
	"log"
	"mock/sys"
	"net/http"
	"strings"
)

// 返回结果
type CoupletsRes struct {
	Couplets Couplets `json:"couplets"`
}

type Couplets struct {
	First  string `json:"first"`
	Second string `json:"second"`
	Center string `json:"center"`
}

type AccessTokenRes struct {
	RefreshToken  string `json:"refresh_token"`
	ExpiresIn     int    `json:"expires_in"`
	Scope         string `json:"scope"`
	SessionKey    string `json:"session_key"`
	AccessToken   string `json:"access_token"`
	SessionSecret string `json:"session_secret"`
}

func GetAiSpringCouplets(text string, index int) CoupletsRes {

	client := http.Client{}

	// 请求参数
	param := fmt.Sprintf(sys.API_PARAM, text, index)

	request, _ := http.NewRequest(http.MethodPost, fmt.Sprintf(sys.URL, sys.ACCESS_TOKEN), strings.NewReader(param))
	// 加入 header
	request.Header.Add("content-type", "application/json")

	r, e := client.Do(request)
	if e != nil {
		log.Fatal(e)
	}

	all, e := ioutil.ReadAll(r.Body)
	if e != nil {
		log.Fatal(e)
	}

	// 将请求结果反序列化
	var coupletsRes CoupletsRes
	json.Unmarshal(all, &coupletsRes)

	log.Println(string(all))
	return coupletsRes
}

func GetAccessToken() AccessTokenRes {

	client := http.Client{}

	// 请求参数
	param := fmt.Sprintf("")

	request, _ := http.NewRequest(http.MethodPost, fmt.Sprintf(sys.ACCESS_TOKEN_URL, sys.CLIENT_ID, sys.CLIENT_SECRET), strings.NewReader(param))

	r, e := client.Do(request)
	if e != nil {
		log.Fatal(e)
	}

	all, e := ioutil.ReadAll(r.Body)
	if e != nil {
		log.Fatal(e)
	}

	// 将请求结果反序列化
	var accessTokenRes AccessTokenRes
	json.Unmarshal(all, &accessTokenRes)

	log.Println(string(all))
	return accessTokenRes
}

春联工具类修改参数

package util

import (
	"flag"
	"github.com/golang/freetype"
	"image"
	"image/color"
	"image/png"
	"io/ioutil"
	"log"
	. "mock/lib/font/config"
	"os"
)

// charset 中文文字
// horV H-横排,V-竖排
// out 输出文件名
// font 字体
// Mode 模式 customer 为用户输入 ,aiRobot 为百度 AI 生成
// Center 对联主题,仅 aiRobot 模式下可以指定
// Index 对联下标,仅 aiRobot 模式下可以指定
var (
	Char = flag.String("charset", "你好世界", "text (ZH)")
	HorV = flag.String("horV", "H", "H | V")
	Out  = flag.String("out", "", "output file name")
	Font = flag.String("font", "f1", "f1 | f2")
	Mode = flag.String("mode","customer","customer | aiRobot")
	Center = flag.String("center","","couplets center")
	Index = flag.Int("index",0,"couplets index")
)

func Generator(charset []string, outPath string, horV string, textFont TextFont) {

	// 打开背景图
	bgFile, err := os.OpenFile("../img/bg.png", os.O_RDONLY, 6)
	if err != nil {
		log.Fatal(err)
	}

	defer bgFile.Close()

	// 解码
	i, err := png.Decode(bgFile)
	if err != nil {
		log.Fatal(err)
	}

	// 图片的宽度
	srcWidth := 640
	// 图片的高度
	srcHeight := 640

	if horV == "H" {
		srcWidth = 640 * len(charset)
	}

	if horV == "V" {
		srcHeight = 640 * len(charset)
	}

	imgFile, _ := os.Create(outPath)
	defer imgFile.Close()
	img := image.NewRGBA(image.Rect(0, 0, srcWidth, srcHeight))

	if horV == "H" {
		log.Println("横向生成,渲染背景...")
		// 根据字符长度创建背景
		for index := 0; index < len(charset); index++ {
			// 复制背景图
			for y := 0; y < srcHeight; y++ {
				for x := index * 640; x < srcWidth; x++ {
					if x < 640 {
						img.Set(x, y, i.At(x, y))
					} else {
						img.Set(x, y, i.At(x-index*640, y))
					}
				}
			}
		}
	}

	if horV == "V" {
		log.Println("竖向生成,渲染背景...")
		// 根据字符长度创建背景
		for index := 0; index < len(charset); index++ {
			// 复制背景图
			for y := index * 640; y < srcHeight; y++ {
				for x := 0; x < srcWidth; x++ {
					if y < 640 {
						img.Set(x, y, i.At(x, y))
					} else {
						img.Set(x, y, i.At(x, y-index*640))
					}
				}
			}
		}
	}

	// 读取字体数据
	fontFileName := "../lib/font/" + textFont.FontName
	fontBytes, err := ioutil.ReadFile(fontFileName)
	log.Printf("加载字体:%s...", textFont.FontName)
	if err != nil {
		log.Fatal(err)
	}

	// 载入字体数据
	font, err := freetype.ParseFont(fontBytes)
	if err != nil {
		log.Println("载入字体失败!", err)
	}
	f := freetype.NewContext()
	// 设置分辨率
	f.SetDPI(100)
	// 设置字体
	f.SetFont(font)
	// 设置尺寸
	f.SetFontSize(textFont.FontSize)
	f.SetClip(img.Bounds())
	// 设置输出的图片
	f.SetDst(img)
	// 设置字体颜色(黑色)
	f.SetSrc(image.NewUniform(color.Black))

	if horV == "H" {
		log.Println("开始绘制对联...")
		// 绘制字符
		for index := 0; index < len(charset); index++ {
			// 设置字体的位置
			pt := freetype.Pt(textFont.X+index*640, textFont.Y)

			_, err = f.DrawString(charset[index], pt)
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	if horV == "V" {
		// 绘制字符
		for index := 0; index < len(charset); index++ {
			// 设置字体的位置
			pt := freetype.Pt(textFont.X, textFont.Y+index*640)

			_, err = f.DrawString(charset[index], pt)
			if err != nil {
				log.Fatal(err)
			}
		}
	}

	// 以png 格式写入文件作为输出
	err = png.Encode(imgFile, img)
	if err != nil {
		log.Fatal(err)
	}
	log.Println("Done.")
}

系统变量

package sys

var ACCESS_TOKEN = ""

var CLIENT_ID = ""

var CLIENT_SECRET = ""

// api 请求参数
var API_PARAM = `
{
  "text": "%s",
  "index": %d
}`

// 百度 AI 接口
var URL = "https://aip.baidubce.com/rpc/2.0/creation/v1/couplets?access_token=%s"

var ACCESS_TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=%s&client_secret=%s"

程序入口修改

package main

import (
	"flag"
	uuid "github.com/satori/go.uuid"
	"mock/lib/font/config"
	. "mock/util"
)

func main() {

	// 命令行指令
	flag.Parse()

	// ================== 参数处理

	// 处理字符
	var charset []string
	if len(*Char) == 0 {
		charset = []string{"你", "好", "世", "界"}
	} else {
		for _, v := range *Char {
			charset = append(charset, string(v))
		}
	}

	// 输出路径
	outPath := ""
	if len(*Out) == 0 {
		outPath = "../res/" + uuid.NewV4().String() + ".png"
	} else {
		outPath = "../res/" + *Out + ".png"
	}

	// 处理方向
	horV := "H"

	switch *HorV {
	default:
		horV = "H"
	case "V":
		horV = "V"
	}

	// 处理字体
	font := config.Font_1

	switch *Font {
	default:
		font = config.Font_1
	case "f2":
		font = config.Font_2
	}

	switch *Mode {
	default:
		// 手动输入生成对联
		Generator(charset, outPath, horV, font)
	case "aiRobot":
		// 百度 AI 生成对联
		couplets := GetAiSpringCouplets(*Center, *Index).Couplets

		center := couplets.Center
		first := couplets.First
		second := couplets.Second

		for i := 0; i < 3; i++ {
			charset = nil
			if i == 0 {
				for _, v := range center {
					charset = append(charset, string(v))
				}
			} else if i == 1 {
				for _, v := range first {
					charset = append(charset, string(v))
				}
			} else {
				for _, v := range second {
					charset = append(charset, string(v))
				}
			}
			outPath = "../res/" + uuid.NewV4().String() + ".png"
			Generator(charset, outPath, horV, font)
		}
	}
}

智能版测试

D:\GoFiles\mock-exls\cmd>go build

D:\GoFiles\mock-exls\cmd>cmd.exe -help
Usage of cmd.exe:
  -center string
        couplets center
  -charset string
        text (ZH) (default "你好世界")
  -font string
        f1 | f2 (default "f1")
  -horV string
        H | V (default "H")
  -index int
        couplets index
  -mode string
        customer | aiRobot (default "customer")
  -out string
        output file name

D:\GoFiles\mock-exls\cmd>cmd.exe -mode "aiRobot" -center "千云祥集" -index 0
2022/01/23 18:11:29 {"couplets":{"center":"千云祥集","first":"万里祥光辉栋宇","second":"百年集色映梅花"},"log_id":1485193458259264015}
2022/01/23 18:11:29 横向生成,渲染背景...
2022/01/23 18:11:29 加载字体:方正楷体简体.ttf...
2022/01/23 18:11:29 开始绘制对联...
2022/01/23 18:11:29 Done.
2022/01/23 18:11:29 横向生成,渲染背景...
2022/01/23 18:11:29 加载字体:方正楷体简体.ttf...
2022/01/23 18:11:29 开始绘制对联...
2022/01/23 18:11:30 Done.
2022/01/23 18:11:30 横向生成,渲染背景...
2022/01/23 18:11:30 加载字体:方正楷体简体.ttf...
2022/01/23 18:11:30 开始绘制对联...
2022/01/23 18:11:30 Done.

参考:百度AI智能春联文档 

新春祝福

新的一年,祝愿大家身体健康,万事如意,依旧不失对新生活的憧憬和热爱,怀揣理想主义,迸发心中花火,活出滚烫人生。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

余衫马

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值