吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 2695|回复: 127
收起左侧

[Python 原创] 汉字笔画生成

    [复制链接]
liuchangng 发表于 2024-4-9 16:16
本帖最后由 liuchangng 于 2024-4-19 15:51 编辑

一,简介
小孩上小学,学习汉字书写,为了掌握正确的书写顺序,编写了这个小工具.

二,代码展示
[Python] 纯文本查看 复制代码
import logging
import os
import re
import time

import flet
from PIL import Image
from flet import (
    Page,
    UserControl,
    Text,
    ListView
)
from flet_core import AlertDialog, TextButton
from playwright.sync_api import sync_playwright  # 下载浏览器 playwright install chromium

# 1. 初始化日志记录器
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# 2. 定义浏览器User-Agent
USER_AGENT = \
    'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'


class ChineseBiHua(UserControl):
    """汉字笔划控件"""


    def __init__(self, page: Page, persistent_browser: bool = True):
        super().__init__(page)
        self.page = page
        self.persistent_browser = persistent_browser  # 是否非无痕模式,默认无痕模式

        # 3. 初始化汉字输入文本框
        self.chinese_word_input = flet.TextField(
            label='待输入汉字(可以空格分割;逗号分隔;不加任何符号.)',
            value='无',
            width=615,
            max_lines=5,
            border_radius=10
        )

        # 4. 初始化汉字图片排序下拉菜单
        self.word_sort_dropdown = flet.Dropdown(
            height=55,
            width=150,
            border_radius=20,
            label="排序",
            text_size=12,
            hint_text="选择需要的顺序",
            value="1",
            options=[
                flet.dropdown.Option(key="1", text="汉字顺序"),
                flet.dropdown.Option(key="2", text="字典顺序"),
            ],
            autofocus=True,
        )

        # 5. 定义显示笔划图片的控件,可以滚动
        self.bihua_scroll_viewer = ListView(expand=1, controls=[flet.Image(
            src='./images/笔画总表.png',
            height=600,
            fit=flet.ImageFit.CONTAIN,
        )], height=600, auto_scroll=True)

    def build(self):
        # 5. 构建页面布局
        layout = [
            # 页面标题
            flet.Row(
                controls=[Text("欢迎使用汉字输出笔划工具!", size=30, color=flet.colors.LIGHT_BLUE_500)],
                alignment=flet.MainAxisAlignment.CENTER,
            ),
            # 汉字输入区域
            flet.Row(controls=[self.chinese_word_input]),
            # 操作按钮区域
            flet.Row(
                controls=[
                    self.word_sort_dropdown,
                    # 生成笔划按钮
                    flet.ElevatedButton(
                        "汉字笔划",
                        height=55,
                        icon=flet.icons.SAVE,
                        on_click=self.generate_bi_hua,
                    ),
                ],
                alignment=flet.MainAxisAlignment.END,
            ),

            # 显示笔划图片区域
            flet.Row(controls=[self.bihua_scroll_viewer])
        ]

        return flet.Column(controls=layout)

    def generate_bi_hua(self, e):
        """生成汉字笔划事件处理函数"""
        # 6. 初始化Playwright环境
        with sync_playwright() as playwright:
            if self.persistent_browser:  # 无痕模式
                browser = playwright.chromium.launch(headless=False, args=['--start-maximized'])
                page = browser.new_context(user_agent=USER_AGENT).new_page()
                page.set_viewport_size(viewport_size={'width': 1920, 'height': 1080})  # 设置浏览器窗口大小
            else:
                browser = playwright.chromium.launch_persistent_context(  # 非无痕模式
                    executable_path=r'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe',  # 浏览器路径
                    channel='msedge',  # 浏览器类型
                    headless=False,
                    user_data_dir=r"C:\Users\Administrator\AppData\Local\Microsoft\Edge\User Data\Default",  # 浏览器数据路径
                    accept_downloads=True,
                    args=['--start-maximized'],  # 设置浏览器窗口大小
                    no_viewport=True,
                )
                page = browser.new_page()
            # 获取待处理汉字
            words = re.sub(r'[^\u4e00-\u9fff]', '', self.chinese_word_input.value)
            logging.info(f'汉字: {words}')

            # 去除重复汉字并按指定顺序排序
            word_list = list(set(words))
            if self.word_sort_dropdown.value == "2":
                word_list.sort()

            # 逐个生成并保存单个汉字笔划图片
            for word in word_list:
                self.generate_single_bi_hua(page, word)
                time.sleep(1)

            # 合成所有汉字笔划图片
            concat_images([f'./images/{item}.png' for item in word_list], direction='vertical')

            # 删除图片
            for item in word_list:
                os.remove(f'./images/{item}.png')

            # 更新界面上的笔划图片为合成后的图片
            self.bihua_scroll_viewer.controls.clear()  # 清空已存在的图片控件
            self.bihua_scroll_viewer.controls.append(flet.Image(
                src='./images/合成.png',
                fit=flet.ImageFit.CONTAIN
            ))
            self.bihua_scroll_viewer.update()

            # 弹出提示对话框并打开图片目录
            self.show_completion_dialog_and_open_directory()

            # 关闭浏览器
            browser.close()

    def generate_single_bi_hua(self, page, word):
        """生成单个汉字笔划图片"""
        url = f"https://hanyu.baidu.com/s?wd={word}&ptype=zici"
        try:
            # 访问指定URL
            page.goto(url)

            # 等待笔划元素加载并截图
            element_selector = '.word-stroke-wrap'
            page.wait_for_selector(element_selector, timeout=5000)
            element = page.locator(element_selector)
            bounding_box = element.bounding_box()
            logging.info(f'{word}: {bounding_box}')
            if bounding_box:
                x, y, width, height = (bounding_box['x'], bounding_box['y'], bounding_box['width'],
                                       bounding_box['height'])
                page.screenshot(path=f'./images/{word}.png', full_page=True,
                                clip={'x': x, 'y': y, 'width': width, 'height': height})
                time.sleep(0.5)
            else:
                logging.warning(f"{word}没有找到笔划!")
        except Exception as e:
            logging.error(f"{word}生成笔划时发生错误,原因:{e}")

    def show_completion_dialog_and_open_directory(self):
        """显示完成提示对话框并打开图片目录"""

        def close_dlg(e):
            dialog.open = False
            os.startfile(os.path.abspath('./images'))
            self.page.update()

        # 创建提示对话框
        dialog = AlertDialog(
            title=Text('提示:'),
            actions=[
                TextButton("确定", on_click=close_dlg)
            ],
            actions_alignment=flet.MainAxisAlignment.END,
        )
        self.page.dialog = dialog
        dialog.content = Text('合成图片完成!')
        dialog.open = True
        self.page.update()


def concat_images(images, direction='horizontal', separator_color=(0, 0, 0), separator_size=3):
    """
    合成图片

    :param images: 待合成图片列表
    :param direction: 合成方向(horizontal或vertical)
    :param separator_color: 分割线颜色
    :param separator_size: 分割线大小
    """
    # 打开所有图像并获取尺寸
    images = [Image.open(img) for img in images]
    widths, heights = zip(*(i.size for i in images))
    logging.info(f'widths: {widths}, heights: {heights}')

    # 计算拼接后图像的尺寸
    if direction == 'horizontal':
        total_width = sum(widths) + separator_size * (len(images) - 1)
        max_height = max(heights)
        new_size = (total_width, max_height)
    else:
        max_width = max(widths)
        total_height = sum(heights) + separator_size * (len(images) - 1)
        new_size = (max_width, total_height)

    # 创建新图像并将所有图像拼接到上面
    new_image = Image.new('RGB', new_size, color=separator_color)
    offset = 0
    for img in images:
        if direction == 'horizontal':
            new_image.paste(img, (offset, 0))
            offset += img.size[0] + separator_size
        else:
            new_image.paste(img, (0, offset))
            offset += img.size[1] + separator_size

    new_image.save('./images/合成.png')


def main(page: flet.Page):
    # 10. 定义页面属性和布局
    page.title = "汉字笔画"
    page.window_width = 650
    page.window_height = 850
    page.scroll = True
    page.window_maximizable = False
    page.window_minimized = False
    page.window_center()
    page.update()

    # 11. 创建并添加汉字笔划控件到页面
    chinese_bihua = ChineseBiHua(page)
    page.add(chinese_bihua)


if __name__ == '__main__':
    flet.app(target=main)


三,本地运行
[Asm] 纯文本查看 复制代码
1,安装依赖
```shell
pip install flet==0.21.2 playwright==1.42.0 pillow==10.2.0
```

2,安装浏览器
```shell
playwright install chromium
```
3,运行
```shell
python main.py
```


四,可执行文件地址
版本hanzibihuaV20240415.zip
123网盘:
https://www.123pan.com/s/Gvawjv-TwOph.html  提取码:52pj
百度网盘:
链接:https://pan.baidu.com/s/1ibSbeemyyir_cb-k8K0fCw?pwd=1024
提取码:1024
说明:
1)增加拼音,部首,笔画数
2)效果图
合成.png
[color=rgba(0, 0, 0, 0.85)]

版本hanzibihuaV20240410.zip
https://www.123pan.com/s/Gvawjv-PaOph.html  提取码:52pj
说明:
1)输入汉字或句子生成笔画合成图片
2)效果图
1.png

2.png

合成.png





免费评分

参与人数 31吾爱币 +33 热心值 +27 收起 理由
pjj811885 + 1 + 1 我很赞同!
l18c19 + 1 + 1 谢谢@Thanks!
cnmsh + 1 + 1 我很赞同!
龙骨鬼 + 1 + 1 我很赞同!
wangxuhai + 1 + 1 我很赞同!
Godless + 1 + 1 我很赞同!
aaalpaaalp + 1 + 1 谢谢@Thanks!
冬天冷了多穿点 + 2 + 1 谢谢@Thanks!
pushand + 1 + 1 谢谢@Thanks!
左右仙人掌 + 1 鼓励转贴优秀软件安全工具和文档!
苏紫方璇 + 7 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
lijie0100 + 1 谢谢@Thanks!
o568941932 + 1 + 1 用心讨论,共获提升!
zengsipei + 1 + 1 热心回复!
hnm372 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ffdn2002 + 1 + 1 谢谢@Thanks!
Coptis_china + 1 谢谢@Thanks!
豆瓣辣酱TM + 1 + 1 我很赞同!
optimismsj + 1 + 1 我很赞同!
Timothys + 1 鼓励转贴优秀软件安全工具和文档!
discom + 1 谢谢@Thanks!
印象深處 + 1 能不能出个成品
坐久落花多 + 1 + 1 看着不错,之前我给女儿做的小工具是直接把百度的动画展示给她看
chinaxndd + 1 + 1 正好给小朋友学习
max2012 + 1 + 1 我很赞同!
gqdsc + 1 + 1 这是个好工具啊
wuming4 + 1 谢谢@Thanks!
jiangzhikuan + 1 谢谢@Thanks!
chz123 + 1 + 1 我很赞同!
blindcat + 1 + 1 谢谢@Thanks!
jinqiaoa1a + 1 + 1 谢谢@Thanks!

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

csclc 发表于 2024-4-10 08:05
这个非常好,分享的很是有水准
nccdap 发表于 2024-4-10 08:43
D:\Python>pip install flet
ERROR: Could not find a version that satisfies the requirement flet (from versions: none)
ERROR: No matching distribution found for flet

D:\Python>playwright install chromium
'playwright' 不是内部或外部命令,也不是可运行的程序
或批处理文件。

D:\Python>pip3 install flet
ERROR: Could not find a version that satisfies the requirement flet (from versions: none)
ERROR: No matching distribution found for flet

D:\Python>pip install flet -i https://pypi.tuna.tsinghua.edu.cn/simple/
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple/
ERROR: Could not find a version that satisfies the requirement flet (from versions: none)
ERROR: No matching distribution found for flet

D:\Python>pip3 install flet -i https://pypi.tuna.tsinghua.edu.cn/simple/
Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple/
ERROR: Could not find a version that satisfies the requirement flet (from versions: none)
ERROR: No matching distribution found for flet
Corgibro 发表于 2024-4-10 04:54
hhxx23 发表于 2024-4-10 05:44
这个不错,方便!
jinqiaoa1a 发表于 2024-4-10 06:38
真的很不错,感谢楼主分享
66688891zgl 发表于 2024-4-10 07:17
不错。这是一个好帮手。
blindcat 发表于 2024-4-10 07:19
这个厉害了,我现在都不会写字了
a12345r 发表于 2024-4-10 08:00
不懂编程,请问怎么使用它?谢谢!
l441669899 发表于 2024-4-10 08:01
很好,感谢楼主分享!
Wapj_Wolf 发表于 2024-4-10 08:02
py都写了这么多行代码,这是真的牛。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-5-3 21:49

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表