- 支持多种橘雪莉表情模板,也可以自行扩展
- 文字自动居中且带黑色描边,确保在任何背景下清晰可见
- 简单易用而高效的 API 接口
- 自带图床,支持更多应用场景
- 自动清理临时生成的图片,节省存储空间
- 完整的配置系统,支持自定义字体和资源路径,可根据需求灵活调整
- 完善的日志系统,记录运行日志,方便排查问题
- webui 界面,方便用户可视化操作直接使用
- webui 管理页面,方便运维管理
- 管理员认证系统,保护管理功能安全
- 配置热更新,无需重启服务即可应用配置变更
- 图片过期时间可配置,灵活控制存储空间使用
├── api/ # API接口定义
├── core/ # 核心配置和初始化
├── data/ # 数据存储
│ ├── conf/ # 配置文件
│ ├── log.txt # 日志文件
│ └── memes/ # 生成的表情包存储
├── doc/ # 文档文件
├── drawer/ # 表情包绘制逻辑
├── resource/ # 资源文件
│ ├── fonts/ # 字体文件
│ └── *.png # 表情模板图片
├── utils/ # 工具类
│ ├── conf.py # 配置管理
│ └── log.py # 日志系统
├── webui/ # webui 界面代码
├── main.py # 程序入口
├── requirements.txt # 依赖包列表
└── readme.md # 项目说明文档
- Python 3.10+
- pip
# 使用 HTTPS 协议
git clone https://github.com/Sheyiyuan/ShyeriMeme.git # HTTPS
# 或者使用 SSH 协议,如果你不知道这是什么用上面那个
git clone [email protected]:Sheyiyuan/ShyeriMeme.git # SSH
# 进入项目目录
cd ShyeriMemepip install -r requirements.txtpython main.py服务将在 http://0.0.0.0:7210 启动
打开浏览器,访问 http://127.0.0.1:7210/webui 即可打开 Web UI 界面。
打开浏览器,访问 http://127.0.0.1:7210/webui/admin 即可打开 Web UI 管理页面。
首次访问管理页面时需要设置管理员密码。
除了直接运行 Python 程序外,您还可以使用 Docker 来部署此项目,这将确保环境一致性并简化部署过程。
- 安装Docker:Docker官方安装指南
在项目根目录下执行以下命令构建 Docker 镜像:
docker build -t shyerimeme .使用以下命令运行容器:
docker run -d \
--name shyerimeme \
-p 7210:7210 \
-v $(pwd)/data:/app/data \
shyerimeme参数说明:
-d:后台运行容器--name shyerimeme:设置容器名称为shyerimeme-p 7210:7210:将容器的7210端口映射到主机的7210端口-v $(pwd)/data:/app/data:挂载数据卷,实现数据持久化
您也可以创建一个 docker-compose.yml 文件来管理容器:
version: '3'
services:
shyerimeme:
build: .
container_name: shyerimeme
ports:
- "7210:7210"
volumes:
- ./data:/app/data
restart: unless-stopped然后使用以下命令启动服务:
docker-compose up -d-
配置文件位置:
- 容器内部的配置文件位于
/app/data/conf/conf.json - 通过数据卷挂载,您可以在宿主机上直接修改
./data/conf/conf.json
- 容器内部的配置文件位于
-
字体支持:
- Docker 镜像中已包含字体支持,可以正常显示中文
- 如果需要使用自定义字体,请确保字体文件位于正确的路径
-
数据持久化:
- 通过挂载
./data目录,确保生成的表情包、日志和配置在容器重启后不会丢失
- 通过挂载
-
域名配置:
- 在生产环境中,请确保在配置文件中设置正确的域名,以便生成可访问的图片URL
配置文件位于 data/conf/conf.json,可以修改以下参数:
{
"name": "ShyeriMeme",
"work_dir": "./",
"log": {
"log_level": "info",
"output_path": "data/",
"output_file": "log.txt"
},
"api": {
"route_root": "/",
"port": 7210,
"host": "0.0.0.0",
"token": "",
"domain": "www.example.com"
},
"resource": {
"resource_paths": {
"哭": "resource/shyeri_cry.png",
"慌张": "resource/shyeri_fear.png",
"点赞": "resource/shyeri_good.png",
"震惊": "resource/shyeri_shocked.png",
"害羞": "resource/shyeri_shy.png",
"投降": "resource/shyeri_surrender.png",
"惊讶": "resource/shyeri_surprise.png",
"灵机一动": "resource/shyeri_ting.png",
"好吃": "resource/shyeri_yummy.png",
"愣住": "resource/shyeri_speechless.png",
"恍悟": "resource/shyeri_soga.png",
"得意": "resource/shyeri_proud.png"
},
"chinese_font_path": "resource/fonts/STHeitiMedium.ttc",
"english_font_path": "resource/fonts/Times New Roman.ttf"
},
"storage": {
"image_expiry_time": 300
},
"admin": {
"password_hash": "9321c83cb583b2c8090fc315ed6f878e712128209be3cb01539194ec77ef9dfe",
"salt": "60fc419eb9aeb47afc0b373303039b30"
}
}- name: 项目名称
- work_dir: 工作目录路径
- log:
- log_level: 日志级别(debug, info, warning, error)
- output_path: 日志输出路径
- output_file: 日志文件名
- api:
- route_root: API路由根路径
- port: 服务端口
- host: 服务监听地址
- token: API访问令牌(可选)
- domain: 域名配置,用于生成图片URL
- resource:
- resource_paths: 表情模板图片映射关系
- chinese_font_path: 中文字体路径
- english_font_path: 英文字体路径
- storage:
- image_expiry_time: 图片过期时间(秒),默认300秒(5分钟)
- admin:
- password_hash: 管理员密码哈希值(自动生成,请勿手动修改)
- salt: 密码盐值(自动生成,请勿手动修改)
由于 API 返回的是图片的 URL,所以需要配置域名,否则无法访问图片。
配置文件中 api.domain 项需要设置为你的域名,例如 www.example.com。
如果你没有域名的反向代理,你需要为 api.domain 项添加端口,例如 127.0.0.1:7210。
- URL:
/ - Method:
POST - Content-Type:
application/json - 请求参数:
| 参数名 | 类型 | 必需 | 说明 |
|---|---|---|---|
| background | string | 是 | 表情模板名称,可选值:哭、慌张、点赞、震惊、害羞、投降、惊讶、灵机一动、好吃、愣住、恍悟、得意 |
| text | string | 是 | 要添加到表情包上的文字 |
- 请求示例:
{
"background": "得意",
"text": "我一根手指就能扣晕你"
}- 返回示例:
{
"code": 200,
"message": "success",
"data": {
"img_url": "http://www.example.com:7210/images/shyeri_meme_得意_我一根手指就能扣晕你.jpg"
}
}- 图片示例:
-
错误响应:
- 400: 请求参数错误或背景图不存在
- 500: 服务器内部错误
- URL:
/list - Method: GET
- 描述: 获取所有可用的背景图片关键字列表
- 返回示例:
{
"code": 200,
"message": "success",
"data": {
"background_list": ["哭", "慌张", "点赞", "震惊", "害羞", "投降", "惊讶", "灵机一动", "好吃", "愣住", "恍悟", "得意"],
"total": 12
}
}- 错误响应:
- 500: 服务器内部错误
- URL:
/config - Method: GET
- 描述: 获取当前系统配置
- 返回示例:
- 返回完整的配置JSON对象
- URL:
/config - Method: POST
- Content-Type:
application/json - 描述: 更新系统配置(需要管理员权限)
- 请求体: 完整的配置JSON对象
- 返回示例:
{"status": "success"}: 更新成功{"status": "error", "message": "错误信息"}: 更新失败
- URL:
/logs - Method: GET
- 描述: 获取系统运行日志(需要管理员权限)
- 返回示例:
{
"code": 200,
"message": "success",
"data": {
"logs": "日志内容..."
}
}- URL:
/background/{background_name} - Method: GET
- 描述: 获取指定名称的背景图片
- 路径参数:
background_name: 背景图片名称
- 返回: 背景图片文件
- URL:
/admin/password/set - Method: POST
- Content-Type:
application/json - 描述: 首次设置管理员密码
- 请求体:
{"password": "新密码"} - 返回示例:
- 成功:
{"code": 200, "message": "密码设置成功", "data": {}} - 失败:
{"code": 400, "message": "密码已设置,请使用重置密码功能", "data": {}}
- 成功:
- URL:
/admin/password/verify - Method: POST
- Content-Type:
application/json - 描述: 验证管理员密码
- 请求体:
{"password": "密码"} - 返回示例:
- 成功:
{"code": 200, "message": "验证成功", "data": {"token": "会话令牌"}} - 密码错误:
{"code": 401, "message": "密码错误", "data": {}} - 未设置密码:
{"code": 401, "message": "未设置密码", "data": {"need_setup": true}}
- 成功:
- URL:
/admin/password/reset - Method: POST
- Content-Type:
application/json - 描述: 重置管理员密码
- 请求体:
{"old_password": "旧密码", "new_password": "新密码"} - 返回示例:
- 成功:
{"code": 200, "message": "密码重置成功", "data": {}} - 失败:
{"code": 401, "message": "旧密码错误", "data": {}}
- 成功:
生成的图片可以通过返回的 img_url 直接访问,图片会在生成后根据配置的过期时间自动删除(默认 5 分钟)。
项目默认使用以下字体:
- 中文字体:STHeitiMedium.ttc
- 英文字体:Times New Roman.ttf
可以在配置文件中修改字体路径。
日志文件位于 data/log.txt,记录了系统运行状态和错误信息。
系统提供了 /logs API接口,可以通过管理页面查看最近的日志记录。
为了节省存储空间,生成的图片会在配置文件中设置的过期时间后自动删除(默认 5 分钟)。请及时保存需要的图片。
- 将新的表情图片放入
resource/目录 - 在配置文件中的
resource.resource_paths中添加对应的映射关系 - 重启服务或通过管理页面更新配置
可以修改 drawer/meme_draw.py 文件中的 _draw_centered_text 方法来自定义文字样式,包括颜色、大小、描边等。
如果忘记了管理员密码,可以直接编辑配置文件 data/conf/conf.json,删除 admin 字段,然后重新访问管理页面进行首次密码设置。
可以在 webui 管理页面的系统设置中修改,也可以在配置文件中的 storage.image_expiry_time 项设置图片过期时间(秒)。
本项目基于 MIT License 传播,仅供个人学习交流使用,不拥有相关素材的版权。进行分发时应注意不违反素材版权与官方二次创造协定。