手动添加字体或背景教程 点我观看视频
已对原程序进行部分调整

核心内容

1.利用PLI.ImageDraw处理图片

2.检测换行换页

3.子线程的开启

Code

from PIL import Image, ImageDraw, ImageFont
from tkinter import Button, ttk, messagebox
import tkinter as tk
import threading
import os
import sys
import random

# 切换到当前目录
cwd = os.path.abspath(os.path.dirname(sys.argv[0]))
os.chdir(cwd)
# 创建GUI界面
Gui = tk.Tk()
Gui.title("手写转换")
Gui.geometry('630x400')

# 设置UI界面部件
words_input = tk.Text(height=10, width=84)
words_input.insert('0.0', "在此输入待转化文本\n\n\
所有参数均可自行修改\n\n\
RGB为字体颜色,范围[0,255]\n\n\
想手动添加字体或背景直接将字体文件或背景图片放到对应目录中即可")
words_input.pack()

tip_rgb = tk.Label(text="RGB:")
tip_rgb.place(x=20, y=150)

content_rgb1 = tk.Entry(width=3)
content_rgb2 = tk.Entry(width=3)
content_rgb3 = tk.Entry(width=3)
content_rgb1.place(x=100, y=150)
content_rgb2.place(x=130, y=150)
content_rgb3.place(x=160, y=150)
content_rgb1.insert(0, "0")
content_rgb2.insert(0, "0")
content_rgb3.insert(0, "0")

tip_fontsize = tk.Label(text="字体大小:")
content_fontsize = tk.Entry(width=3)
content_fontsize.insert(0, "160")
tip_fontsize.place(x=20, y=180)
content_fontsize.place(x=100, y=180)

tip_row = tk.Label(text="额外行间距:")
content_row = tk.Entry(width=3)
tip_row.place(x=20, y=210)
content_row.place(x=100, y=210)
content_row.insert(0, "0")

tip_col = tk.Label(text="额外字间距:")
content_col = tk.Entry(width=3)
tip_col.place(x=20, y=240)
content_col.place(x=100, y=240)
content_col.insert(0, "0")

iv = tk.IntVar()
iv.set(0)  # 默认为不开启
radio = tk.Checkbutton(Gui, variable=iv, onvalue=1, offvalue=0, text='是否开启微扰')
radio.place(x=20, y=270)

tip_random = tk.Label(text="微扰指数:")
content_random = tk.Entry(width=3)
content_random.insert(0, "0.1")
tip_random.place(x=20, y=300)
content_random.place(x=100, y=300)

tip_font = tk.Label(text="选择字体:")
cbox_font = ttk.Combobox(Gui, state="readonly")
# 读取字体文件
font_list = [font[:-4] for font in os.listdir("{}\\Font".format(cwd))]
cbox_font['value'] = font_list
tip_font.place(x=300, y=150)
cbox_font.place(x=370, y=150)
cbox_font.current(4)

tip_background = tk.Label(text="选择背景:")
cbox_background = ttk.Combobox(Gui, state="readonly")
# 读取背景文件
background_list = [background[:-4] for background in os.listdir("{}\\Background".format(cwd))]
cbox_background['value'] = background_list
tip_background.place(x=300, y=180)
cbox_background.place(x=370, y=180)
cbox_background.current(0)

tip_fileformat = tk.Label(text="保存格式")
cbox_fileformat = ttk.Combobox(Gui, state="radonly")
fileformat_list = ["PNG", "PDF"]
cbox_fileformat['value'] = fileformat_list
tip_fileformat.place(x=300, y=210)
cbox_fileformat.place(x=370, y=210)
cbox_fileformat.current(0)

tip_egde = tk.Label(text="页边距")
content_egde1 = tk.Entry(width=3)
content_egde2 = tk.Entry(width=3)
content_egde3 = tk.Entry(width=3)
content_egde4 = tk.Entry(width=3)

tip_egde.place(x=380, y=280)
content_egde1.place(x=390, y=250)
content_egde2.place(x=390, y=310)
content_egde3.place(x=350, y=280)
content_egde4.place(x=430, y=280)
content_egde1.insert(0, "100")
content_egde2.insert(0, "100")
content_egde3.insert(0, "100")
content_egde4.insert(0, "0")


class WORK():
    def __init__(self):
        # 获取参数内容
        self.rgb1 = int(content_rgb1.get())  # rgb值
        self.rgb2 = int(content_rgb2.get())
        self.rgb3 = int(content_rgb3.get())
        self.font_size = int(content_fontsize.get())  # 字体大小
        self.row = int(content_row.get())  # 额外行间距
        self.col = int(content_col.get())  # 额外字间距
        self.font_style = cbox_font.get() + ".ttf"  # 字体格式
        self.background = cbox_background.get() + ".jpg"  # 背景图片
        self.fileformat = cbox_fileformat.get()  # 文件格式
        self.edge1 = int(content_egde1.get())  # 页边距
        self.edge2 = int(content_egde2.get())
        self.edge3 = int(content_egde3.get())
        self.edge4 = int(content_egde4.get())
        self.israndom = iv.get()  # 微扰
        self.random = float(content_random.get())  # 微扰指数
        self.words = words_input.get("1.0", "end")  # 文本内容

    def work(self, pos=0):
        WORK.__init__(self)
        img = Image.open("Background\\{}".format(self.background))
        new_img = ImageDraw.Draw(img)
        size = img.size

        x = -self.font_size + self.edge3
        y = self.edge1
        n = 0
        page = 1
        for word in self.words[pos:]:
            n += 1
            # 检测换行
            if (size[0] - n * (self.font_size + self.col) < self.font_size + self.edge4) or (word == "\n"):
                n = 1
                y += self.font_size + self.row
                x = -self.font_size + self.edge3
            # 检测换页
            if size[1] - (y + self.edge2) < self.font_size:
                # 换页前先保存
                if self.fileformat == "PNG":
                    img.save("{}.jpg".format(page), "JPEG")
                elif self.fileformat == "PDF":
                    img.save("{}.pdf".format(page), "PDF")
                page += 1
                # 对文本内容切片
                self.words = self.words[self.words.index(word) - 1:]
                # 换页之后变量需重新初始化
                img = Image.open("Background\\{}".format(self.background))
                new_img = ImageDraw.Draw(img)
                size = img.size
                x = -self.font_size + self.edge3
                y = self.edge1
                n = 0

            x += self.font_size + self.col
            # 检测是否开启微扰
            if self.israndom == 1:
                # 根据微扰指数生成随机偏移量
                x_r = random.randint(-int(self.random * self.font_size), int(self.random * self.font_size))
                y_r = random.randint(-int(self.random * self.font_size), int(self.random * self.font_size))
                font_r = random.randint(0, 30)

                font = ImageFont.truetype("Font\\{}".format(self.font_style), self.font_size + font_r, encoding="unic")
                new_img.text((x + x_r, y + y_r), word, (self.rgb1, self.rgb2, self.rgb3), font)
            else:
                font = ImageFont.truetype("Font\\{}".format(self.font_style), self.font_size, encoding="unic")
                new_img.text((x, y), word, (self.rgb1, self.rgb2, self.rgb3), font)

        # 保存
        if self.fileformat == "PNG":
            img.save("{}.jpg".format(page), "JPEG")
        elif self.fileformat == "PDF":
            img.save("{}.pdf".format(page), "PDF")
        tk.messagebox.showinfo("Done", "转化完毕")


def new_thread():
    # 开新线程防止主程序卡顿
    threading.Thread(target=WORK().work).start()


button = tk.Button(Gui, text="导出", font=5, width=10, height=2, command=new_thread)
button.place(x=20, y=340)
Gui.mainloop()

预览效果

程序界面

输出结果

输出结果

下载链接

点我下载 密码1234