自制软件,封面制作利器:图配文(纯色背景图+文字,自己的图+文字)

想象一下,无论是简洁纯粹的纯色背景图搭配精心雕琢的文字,展现出极致的简约之美;还是将自己珍藏的图片与灵动的文字相结合,诉说着专属于你的故事。它就像是一把钥匙,开启了一扇通往无限创意世界的大门。让我们一同踏上这场封面制作的奇妙之旅,用图配文的魔法,创造出令人惊艳的视觉盛宴。

1.使用

2.入口文件

"""
Author:Liao Ran
Date:2024.8.19
Website:https://www.lrxy.site
"""
# 导入布局文件
from ui import Win as MainWin
# 导入窗口控制器
from Controller import Controller as MainUIController

if __name__ == "__main__":
    # 将窗口控制器 传递给UI
    app = MainWin(MainUIController())
    app.mainloop()

3.ui文件

"""
Author:Liao Ran
Date:2024.8.19
Website:https://www.lrxy.site
"""
import os
from tkinter import *
from tkinter import colorchooser, filedialog, messagebox
from tkinter.ttk import *
from ttkbootstrap import Style


class WinGUI(Tk):
    def __init__(self):
        super().__init__()
        # 设置 ttk 主题

        self.__win()
        self.style = Style(theme='united')
        self.tk_label_m00tujui = self.__tk_label_m00tujui(self)
        self.tk_input_text_user = self.__tk_input_text_user(self)
        self.tk_label_m00tvhwi = self.__tk_label_m00tvhwi(self)
        self.tk_select_box_m036bymy = self.__tk_select_box_m036bymy(self)
        self.tk_label_m036c8uy = self.__tk_label_m036c8uy(self)
        self.tk_button_color = self.__tk_button_color(self)
        self.tk_label_color_display = self.__tk_label_color_display(self)
        self.tk_label_m036g4y9 = self.__tk_label_m036g4y9(self)
        self.tk_button_choice_pic = self.__tk_button_choice_pic(self)
        self.tk_button_start = self.__tk_button_start(self)
        self.tk_label_chice_pic = self.__tk_label_chice_pic(self)
        self.tk_label_m037udbc = self.__tk_label_m037udbc(self)
        self.tk_scale_font_size = self.__tk_scale_font_size(self)
        self.tk_label_m03baeki = self.__tk_label_m03baeki(self)
        self.tk_button_font_color = self.__tk_button_font_color(self)
        self.tk_label_font_color = self.__tk_label_font_color(self)

        self.user_color = None
        self.user_ttf = None
        self.font_size_set = 120
        self.pic_pth = None
        self.font_color = None

    def __win(self):
        self.title("图配文")
        # 设置窗口大小、居中
        width = 600
        height = 350
        screenwidth = self.winfo_screenwidth()
        screenheight = self.winfo_screenheight()
        geometry = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2)
        self.geometry(geometry)
        self.iconbitmap('./icon/logo2.ico')
        self.resizable(width=False, height=False)

    def scrollbar_autohide(self, vbar, hbar, widget):
        """自动隐藏滚动条"""

        def show():
            if vbar: vbar.lift(widget)
            if hbar: hbar.lift(widget)

        def hide():
            if vbar: vbar.lower(widget)
            if hbar: hbar.lower(widget)

        hide()
        widget.bind("<Enter>", lambda e: show())
        if vbar: vbar.bind("<Enter>", lambda e: show())
        if vbar: vbar.bind("<Leave>", lambda e: hide())
        if hbar: hbar.bind("<Enter>", lambda e: show())
        if hbar: hbar.bind("<Leave>", lambda e: hide())
        widget.bind("<Leave>", lambda e: hide())

    def v_scrollbar(self, vbar, widget, x, y, w, h, pw, ph):
        widget.configure(yscrollcommand=vbar.set)
        vbar.config(command=widget.yview)
        vbar.place(relx=(w + x) / pw, rely=y / ph, relheight=h / ph, anchor='ne')

    def h_scrollbar(self, hbar, widget, x, y, w, h, pw, ph):
        widget.configure(xscrollcommand=hbar.set)
        hbar.config(command=widget.xview)
        hbar.place(relx=x / pw, rely=(y + h) / ph, relwidth=w / pw, anchor='sw')

    def create_bar(self, master, widget, is_vbar, is_hbar, x, y, w, h, pw, ph):
        vbar, hbar = None, None
        if is_vbar:
            vbar = Scrollbar(master)
            self.v_scrollbar(vbar, widget, x, y, w, h, pw, ph)
        if is_hbar:
            hbar = Scrollbar(master, orient="horizontal")
            self.h_scrollbar(hbar, widget, x, y, w, h, pw, ph)
        self.scrollbar_autohide(vbar, hbar, widget)

    def __tk_label_m00tujui(self, parent):
        label = Label(parent, text="文本", anchor="center", )
        label.place(x=43, y=21, width=50, height=30)
        return label

    def __tk_input_text_user(self, parent):
        ipt = Entry(parent, )
        ipt.place(x=94, y=21, width=163, height=30)
        return ipt

    def __tk_label_m00tvhwi(self, parent):
        label = Label(parent, text="纯色背景", anchor="center", )
        label.place(x=40, y=75, width=55, height=30)
        return label

    def __tk_select_box_m036bymy(self, parent):
        folder_path = "./ttf"
        available_fonts = []
        for filename in os.listdir(folder_path):
            if filename.endswith(".ttf"):
                font_path = os.path.join(folder_path, filename)
                if os.path.exists(font_path):

                    available_fonts.append(filename)
                else:
                    self.mes_info(info=f"未找到字体文件:{filename}")

        cb = Combobox(parent, state="readonly", values=available_fonts)
        cb.place(x=391, y=76, width=150, height=30)
        cb.bind("<<ComboboxSelected>>", self.selected_ttf)
        return cb

    def __tk_label_m036c8uy(self, parent):
        label = Label(parent, text="字体", anchor="center", )
        label.place(x=340, y=76, width=50, height=30)
        return label

    def __tk_button_color(self, parent):
        btn = Button(parent, text="点击我选择颜色", takefocus=False, )
        btn.place(x=94, y=75, width=163, height=30)
        return btn

    def __tk_label_color_display(self, parent):
        label = Label(parent, text="已选颜色:无", anchor="center", )
        label.place(x=94, y=120, width=445, height=30)
        return label

    def __tk_label_m036g4y9(self, parent):
        label = Label(parent, text="图片", anchor="center", )
        label.place(x=43, y=177, width=50, height=30)
        return label

    def __tk_button_choice_pic(self, parent):
        btn = Button(parent, text="点击我选择图片(如在纯色背景上写字,可无视本选项)", takefocus=False, )
        btn.place(x=94, y=177, width=446, height=30)
        return btn

    def __tk_button_start(self, parent):
        btn = Button(parent, text="开始", takefocus=False, )
        btn.place(x=489, y=296, width=50, height=30)
        return btn

    def __tk_label_chice_pic(self, parent):
        label = Label(parent, text="已选图片:无", anchor="center", )
        label.place(x=95, y=227, width=446, height=30)
        return label

    def __tk_label_m037udbc(self, parent):
        label = Label(parent, text="字体大小", anchor="center", )
        label.place(x=320, y=20, width=60, height=30)
        return label

    def __tk_scale_font_size(self, parent):
        scale = Scale(parent, from_=1, to=500, orient=HORIZONTAL, length=200)
        label = Label(parent, text="尺寸:0")
        label.place(x=400, y=5)
        # 设置初始值为 120
        scale.set(120)
        label.config(text="尺寸:120")

        def on_scale_change(event):
            # 获取当前滑块值并取整
            value = int(scale.get())
            label.config(text=f"尺寸:{value}")
            self.font_size_set = value

        scale.bind("<ButtonRelease-1>", on_scale_change)
        scale.place(x=400, y=19, width=150, height=30)
        return scale

    def __tk_label_m03baeki(self, parent):
        label = Label(parent, text="字体颜色", anchor="center", )
        label.place(x=30, y=296, width=55, height=30)
        return label

    def __tk_button_font_color(self, parent):
        btn = Button(parent, text="点击我选择字体颜色", takefocus=False, )
        btn.place(x=94, y=296, width=162, height=30)
        return btn

    def __tk_label_font_color(self, parent):
        label = Label(parent, text="字体颜色:无", anchor="center", )
        label.place(x=281, y=296, width=176, height=30)
        return label

    #-------------------------------------------
    def selected_ttf(self, event):
        selected_value = self.tk_select_box_m036bymy.get()
        self.user_ttf = selected_value

    def get_text(self):
        user_text = self.tk_input_text_user.get()
        return user_text

    def get_color(self):
        color = colorchooser.askcolor()
        if color[1]:
            self.user_color = color[1]
            self.tk_label_color_display.config(text=f'已选颜色:{color[1]}')
        else:
            #默认白色
            self.user_color = '#ffffff'

    def get_font_color(self):
        color = colorchooser.askcolor()
        if color[1]:
            self.font_color = color[1]
            self.tk_label_font_color.config(text=f'已选颜色:{color[1]}')
        else:
            #默认白色
            self.font_color = '#ffffff'

    def get_pic_pth(self):
        pic_path = filedialog.askopenfilename(filetypes=[("Image files", "*.jpg;*.png;*.gif")])
        if pic_path:
            self.tk_label_chice_pic.config(text=f'已选图片:{pic_path}')
            return pic_path

        else:
            self.tk_label_chice_pic.config(text=f'已选图片:无')
            return '无'

    def get_font_value(self):
        return self.font_size_set

    def mes_info(self, info):
        messagebox.showinfo('提示', info)


class Win(WinGUI):
    def __init__(self, controller):
        self.ctl = controller
        super().__init__()
        self.__event_bind()
        self.__style_config()
        self.ctl.init(self)

    def __event_bind(self):
        self.tk_button_color.bind('<Button>', self.ctl.choice_color)
        self.tk_button_choice_pic.bind('<Button>', self.ctl.choice_pic)
        self.tk_button_start.bind('<Button>', self.ctl.start)
        self.tk_button_font_color.bind('<Button>', self.ctl.font_color)
        pass

    def __style_config(self):
        pass

4.逻辑文件

"""
Author:Liao Ran
Date:2024.8.19
Website:https://www.lrxy.site
"""

from ui import Win
import threading
from PIL import Image, ImageDraw, ImageFont

class Controller:
    # 导入UI类后,替换以下的 object 类型,将获得 IDE 属性提示功能
    ui: Win

    def __init__(self):
        self.pic_pth = None
        self.stop=False
        pass

    def init(self, ui):
        """
        得到UI实例,对组件进行初始化配置
        """
        self.ui = ui
        # TODO 组件初始化 赋值操作

    def choice_color(self, evt):
        color = self.ui.get_color()
        return color

    def choice_pic(self, evt):
        result = self.ui.get_pic_pth()
        self.pic_pth = result

    def font_color(self, evt):
        font_color = self.ui.get_font_color()
        return font_color

    def start(self, evt):
        pic_path = self.pic_pth
        user_text = self.ui.get_text()
        user_color = self.ui.user_color
        user_ttf = self.ui.user_ttf
        font_size = self.ui.get_font_value()
        font_pth = f'./ttf/{user_ttf}'

        f_color = self.ui.font_color

        if pic_path == None:
            if user_text == None or user_color == None or user_ttf == None or f_color == None:
                self.ui.mes_info(info='请先完善要填写的文本信息!')
            else:
                self.make_pic(text=user_text, color=user_color, font_size=font_size, font_pth=font_pth,
                              font_color=f_color)
                self.ui.mes_info(info='纯色图片——生成成功啦!')

        else:
            if user_text == None or font_size == None or user_ttf == None or f_color == None:
                self.ui.mes_info(info='请先完善要填写的文本信息!')
            else:
                def writ_in_your_pic():
                    self.write_text_on_image(image_path=pic_path, text_content=user_text, font_path=font_pth,
                                             f_color=f_color, font_size=font_size)
                    self.ui.mes_info(info='自选图片——生成成功啦!')

                thread1 = threading.Thread(target=writ_in_your_pic)
                thread1.start()





    def make_pic(self, text, color, font_size, font_pth, font_color):
        # 创建一个 1920x1080 的指定颜色图片
        image = Image.new('RGB', (1920, 1080), color)
        draw = ImageDraw.Draw(image)

        # 选择字体和字体大小
        font = ImageFont.truetype(f"{font_pth}", font_size)

        # 获取文本的大小
        text_bbox = draw.textbbox((0, 0), f'{text}', font=font)
        text_width = text_bbox[2] - text_bbox[0]
        text_height = text_bbox[3] - text_bbox[1]

        # 计算文本的位置(居中)
        x = (1920 - text_width) // 2
        y = (1080 - text_height) // 2

        # 使用传入的十六进制颜色
        draw.text((x, y), f'{text}', font=font, fill=font_color)
        image.save(f'文字图片_纯色.png')

    def write_text_on_image(self, image_path, text_content, font_path, font_size, f_color):
        # 打开图片
        img = Image.open(image_path)
        width, height = img.size

        # 设置字体
        font = ImageFont.truetype(font_path, font_size)

        # 创建一个临时的 ImageDraw 对象用于计算文本尺寸
        temp_draw = ImageDraw.Draw(img)
        text_bbox = temp_draw.textbbox((0, 0), text_content, font=font)
        text_width = text_bbox[2] - text_bbox[0]
        text_height = text_bbox[3] - text_bbox[1]

        # 计算文本在图片中心的位置
        text_position = ((width - text_width) // 2, (height - text_height) // 2)

        # 创建绘图对象
        draw = ImageDraw.Draw(img)

        # 在图片上绘制文本
        draw.text(text_position, text_content, font=font, fill=f_color)
        # 保存修改后的图片
        img.save('文字图片_自选.png')

5.下载链接

下载链接:自制软件,封面制作利器:图配文(纯色背景图+文字,自己的图+文字)
提取码:0mr9

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注