概述
使用 PyQt5 编写的手写字生成器,旨在完成一些无用的手写作业任务 本项目提供了丰富的参数设置,以满足您在生成手写字时的个性化需求。
功能介绍
- 纸张设置:可自定义纸张宽度和高度
- 字体选择:支持多种字体选择
- 字体大小:可自由调整字体大小
- 行距字距:提供行距和字距调整功能
- 留白设置:可分别设置上下左右留白
- 颜色选择:支持自定义字体颜色、背景颜色、透明色(transparent)和白色(white)
- 输入文本框:方便输入需要生成的文字内容
- 扰动设置:包括行间距扰动、字体大小扰动、字间距扰动、横向笔画扰动、纵向笔画扰动和旋转笔划扰动,以模拟手写字体的自然特点
结果与使用方法
9. 1 和 2)是纸张大小的宽度和高度,可以根据实际情况确定,接下来会有例子进行讲解
10. (3) 背景色选择透明色可以更方便的将输出文件覆盖在其他图片上进行打印
11. (4) 如果文本过长会被自动切分为多个页面, 这里可以选择页码进行预览
12. (5) 这里可以选择渲染精度,倍率越高,输出的文件越清晰,但是渲染速度会变慢(PNG)
13. (6) 按下export进行导出,默认导出到当前文件夹output目录下 其他字体
默认字体文件夹在当前目录的ttf_library文件夹下,可以自行添加字体文件,但是字体文件必须是.ttf格式的,字体文件夹不能为空!
使用例子
截图后,外围绿色方框为宽度和高度,可以用工具测量距离
(1, 2, 3, 4)为上下左右留白 两根黑线之间为行距,两个字之间的距离为字距, 字体大小为粉色方框处 字体大小不能超过行距否则会报错
扰动设为0,可以得到一个比较整齐的手写字体,例:
扰动设为较大,可以得到一个比较潦草的手写字体,例:
代码
# -*- coding: utf-8 -完整代码*------
import os
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QGraphicsPixmapItem, QGraphicsScene
from QT_GUI.qt_gui import *
from core import handwrite_generator
from tools import BasicTools
class Windows(QtWidgets.QDialog, Ui_Form):
def __init__(self):
super(Windows, self).__init__()
self.setupUi(self)
self.basic_tools = BasicTools()
self.generator_engine = handwrite_generator()
self.params = self.generator_engine.template_params # 获取默认参数
self.preview_image_dict = {}
# 设置默认启动项
self.set_default()
self.connect_signal()
def img_show_func(self, img_path):
frame = QImage(str(img_path), "PNG")
frame = frame.scaled(667, 945, Qt.KeepAspectRatio, Qt.SmoothTransformation | Qt.HighEventPriority)
pix = QPixmap.fromImage(frame)
item = QGraphicsPixmapItem(pix)
scene = QGraphicsScene()
scene.addItem(item)
self.img_preview.setScene(scene)
self.img_preview.horizontalScrollBar().setValue(1) # 设置滚动条初始位置
self.img_preview.verticalScrollBar().setValue(1) # 设置滚动条初始位置
def page_number_change(self):
if self.page_number.currentText() != "":
self.img_show_func(self.preview_image_dict[int(self.page_number.currentText())])
def connect_signal(self):
self.page_number.currentIndexChanged.connect(self.page_number_change)
self.pushButton_export.clicked.connect(self.export)
def set_default(self):
# 设置宽度高度
self.lineEdit_width.setText(str(self.params["default_paper_x"]))
self.lineEdit_height.setText(str(self.params["default_paper_y"]))
# 设置默认字体和候选字体
self.ttf_selector.addItems(self.basic_tools.get_ttf_file_path()[0])
self.ttf_selector.setCurrentIndex(0)
# 设置字体大小,行距,字距
self.lineEdit_font_size.setText(str(self.params["default_font_size"]))
self.lineEdit_line_spacing.setText(str(self.params["default_line_spacing"]))
self.lineEdit_char_distance.setText(str(self.params["default_word_spacing"]))
# 设置留白
self.lineEdit_margin_top.setText(str(self.params["default_top_margin"]))
self.lineEdit_margin_bottom.setText(str(self.params["default_bottom_margin"]))
self.lineEdit_margin_left.setText(str(self.params["default_left_margin"]))
self.lineEdit_margin_right.setText(str(self.params["default_right_margin"]))
# 设置默认字体颜色, 背景颜色
self.comboBox_char_color.addItems(self.basic_tools.font_color_dict.keys())
self.comboBox_char_color.setCurrentIndex(0)
self.comboBox_background_color.addItems(self.basic_tools.background_color_dict.keys())
self.comboBox_background_color.setCurrentIndex(0)
# 设置扰动参数
self.lineEdit_line_spacing_sigma.setText(str(self.params["default_line_spacing_sigma"]))
self.lineEdit_font_size_sigma.setText(str(self.params["default_font_size_sigma"]))
self.lineEdit_word_spacing_sigma.setText(str(self.params["default_word_spacing_sigma"]))
self.lineEdit_perturb_x_sigma.setText(str(self.params["default_perturb_x_sigma"]))
self.lineEdit_perturb_y_sigma.setText(str(self.params["default_perturb_y_sigma"]))
self.lineEdit_perturb_theta_sigma.setText(str(self.params["default_perturb_theta_sigma"]))
# 设置默认文本
default_text = (
"使用 PyQt5 编写的手写字生成器,旨在完成一些无用的手写作业任务"
"本项目提供了丰富的参数设置,以满足您在生成手写字时的个性化需求"
)
self.textEdit_main.setPlainText(default_text)
# 设置默认倍率
self.comboBox_resolution.addItems(self.basic_tools.default_rate_dict.keys())
self.comboBox_resolution.setCurrentIndex(2)
# 设置默认预览
self.generator_engine.modify_template_params(default_background=(255, 255, 255, 255))
preview_image_dict = self.generator_engine.generate_image(default_text)
self.img_show_func(preview_image_dict[0])
self.page_number.addItems([str(i) for i in preview_image_dict]) # 设置page列表
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
window = Windows()
window.show()
sys.exit(app.exec_())
手写字生成器是一种能够模拟人类书写风格来生成文本的工具。这种技术可以应用于多种场景,比如个性化卡片制作、艺术创作、历史文献修复等。下面将介绍手写字体生成的基本原理以及如何构建一个简单的手写字生成器应用程序。
手写字体生成原理
-
数据收集:
- 首先需要大量的手写样本数据。这些数据可以通过手写板或扫描纸质文档获得。
- 数据通常包括不同人的手写样本,以增加模型的多样性和泛化能力。
-
预处理:
- 对图像进行裁剪、缩放、二值化等操作,确保每个字符图像具有一致的格式。
- 将图像转换为适合输入到神经网络的形式,如灰度图或向量表示。
-
模型训练:
- 常用的方法是使用条件生成对抗网络(Conditional GANs, cGANs),其中生成器学习从噪声中生成手写文字,判别器则负责区分真实的手写与生成的手写。
- 另一种方法是使用循环神经网络(RNN)结合变分自编码器(VAE),这种方法在序列数据上表现良好,可以捕捉笔画之间的连续性。
-
后处理:
- 生成的文字可能需要进一步调整,如平滑边缘、连接断开的部分等,以提高视觉质量。
-
应用集成:
- 将训练好的模型封装成API或直接嵌入到应用程序中。
- 提供用户界面,允许用户输入文本并选择不同的字体样式。
构建手写字生成器App
技术栈
- 前端: React Native 或 Flutter 用于跨平台移动开发。
- 后端: Flask 或 FastAPI 作为轻量级Web服务框架。
- 模型部署: TensorFlow Serving 或 ONNX Runtime 用于高效地运行深度学习模型。
- 数据库: SQLite 或 Firebase 用于存储用户数据和配置信息。
开发步骤
-
环境搭建:
- 安装必要的软件包和库。
- 设置项目结构和版本控制系统(如Git)。
-
数据准备:
- 收集和标注手写样本数据。
- 使用Python脚本进行预处理。
-
模型训练:
- 选择合适的深度学习框架(如TensorFlow, PyTorch)。
- 设计并实现生成模型,如cGAN或RNN+VAE。
- 训练模型直到达到满意的性能指标。
-
API开发:
- 创建RESTful API来接收文本输入,并返回生成的手写图片。
- 使用Docker容器化服务,便于部署和扩展。
-
客户端开发:
- 开发React Native或Flutter应用,提供直观的用户界面。
- 通过HTTP请求调用后端API获取生成的手写结果。
-
测试与优化:
- 进行单元测试、集成测试以及用户体验测试。
- 根据反馈调整模型参数和UI设计。
-
发布与维护:
- 将应用提交至Google Play Store或Apple App Store。
- 监控应用性能,定期更新内容和技术支持。
示例代码片段
这里给出一个非常简化的Flask后端示例,用于演示如何设置一个基本的服务:
from flask import Flask, request, jsonify
import numpy as np
# 假设我们有一个已经训练好的模型
from model import HandwritingGenerator
app = Flask(__name__)
generator = HandwritingGenerator()
@app.route('/generate', methods=['POST'])
def generate():
data = request.json
text = data.get('text')
style = data.get('style') # 用户可以选择不同的手写风格
if not text:
return jsonify({'error': 'Text is required'}), 400
# 生成手写图像
image = generator.generate(text, style)
# 将图像转换为Base64字符串以便于传输
from io import BytesIO
import base64
buffer = BytesIO()
image.save(buffer, format="PNG")
img_str = base64.b64encode(buffer.getvalue()).decode('utf-8')
return jsonify({'image': img_str})
if __name__ == '__main__':
app.run(debug=True)
请注意,上述代码仅为概念性示例,实际应用中还需要考虑安全性、效率等因素。希望这能帮助您理解手写字体生成的基本流程及其应用程序的构建过程。如果有更具体的需求或问题,请随时告知!