软件工程第一次作业
| 这个作业属于哪个课程 | https://edu.cnblogs.com/campus/fzu/202601SofwareEngineering |
|---|---|
| 这个作业要求在哪里 | https://edu.cnblogs.com/campus/fzu/202601SofwareEngineering/homework/15712 |
| 这个作业的目标 | 完成 GitHub 及博客园环境搭建,掌握 HF API 调用及前后端交互,梳理技能树并制定未来规划 |
| 学号 | 102401529 |
软件工程课程第一次个人作业
1. 准备工作
在本次作业中,我完成了以下基础环境搭建:
- GitHub账号:https://github.com/Aranya12138
已注册并完善个人信息。 - 博客园账号:Aranya12138
已申请开通博客,完善了昵称、头像,并自定义了博客样式。 - 关注:已关注任课老师(吴越钟)和助教(张明圣、王奇蕊)的博客。
- 加入班级:已成功加入“202601 软件工程”班级博客(实名制已确认)。
2. Huggingface-API 的调用(真实世界图像生成)
2.1 操作步骤
-
在 Hugging Face 官网注册账号并获取 Access Token。
![image]()
-
选定模型
XLabs-AI/flux-RealismLora。 -
编写后端代码调用 API(使用 provider 记录日志),并结合 HTML/CSS/JS 编写前端界面实现交互生成。
2.2 项目代码实现
本项目采用前后端分离架构。后端使用 Python 的 Flask 框架,结合 Hugging Face 的 InferenceClient 封装大模型 API 接口;前端使用原生 HTML、CSS 和 JavaScript 实现交互界面。
2.2.1 项目目录结构
项目根目录为 text-to-image-project,具体的文件层级及功能说明如下:
text-to-image-project/
├── app.py # Flask 后端
├── templates/
│ └── index.html # 前端页面
├── static/
│ ├── style.css # 页面样式
│ └── script.js # 前端交互逻辑
├── generated/ # 生成图片存储目录(自动创建)
├── .env # 环境变量(存放 HF_TOKEN)
└── requirements.txt # Python 依赖
2.2.2 后端核心代码展示(Python / Flask)
后端主要负责接收前端传来的 prompt,调用 XLabs-AI/flux-RealismLora 模型生成图像,并在生成成功后保存图片、记录调用日志。
app.py 完整代码:
import os
import time
import json
from io import BytesIO
from datetime import datetime
from flask import Flask, request, jsonify, send_file, render_template
from flask_cors import CORS
from huggingface_hub import InferenceClient
from PIL import Image
from dotenv import load_dotenv
load_dotenv()
app = Flask(__name__)
CORS(app)
# 从环境变量获取 API Token
HF_TOKEN = os.environ.get('HF_TOKEN')
if not HF_TOKEN:
raise ValueError("请在 .env 文件中设置 HF_TOKEN")
# 初始化 Inference Client,指定 provider 为 fal-ai
client = InferenceClient(api_key=HF_TOKEN)
MODEL_ID = "XLabs-AI/flux-RealismLora"
# 确保生成目录存在
os.makedirs('generated', exist_ok=True)
@app.route('/')
def index():
return render_template('index.html')
@app.route('/api/generate', methods=['POST'])
def generate_image():
data = request.get_json()
prompt = data.get('prompt', '').strip()
if not prompt:
return jsonify({'error': '提示词不能为空'}), 400
# 提示词长度限制(防止恶意请求)
if len(prompt) > 500:
return jsonify({'error': '提示词过长,请控制在500字符以内'}), 400
try:
start_time = time.time()
# 调用 Hugging Face Inference API
# 直接返回 PIL.Image 对象
image = client.text_to_image(
prompt,
model=MODEL_ID,
provider="fal-ai" # 指定推理提供商
)
elapsed = time.time() - start_time
# 生成文件名:时间戳 + 提示词前20字符(清理特殊字符)
safe_prompt = ''.join(c for c in prompt[:20] if c.isalnum() or c in ' _-')
timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
filename = f"{timestamp}_{safe_prompt}.png"
filepath = os.path.join('generated', filename)
# 保存图片
image.save(filepath, 'PNG')
# 记录调用日志
log_entry = {
'prompt': prompt,
'model': MODEL_ID,
'provider': 'fal-ai',
'generated_at': datetime.now().isoformat(),
'time_cost': round(elapsed, 2)
}
with open('generated/generation_log.jsonl', 'a', encoding='utf-8') as f:
f.write(json.dumps(log_entry, ensure_ascii=False) + '\n')
# 返回图片 URL 供前端展示
return jsonify({
'success': True,
'image_url': f'/generated/{filename}',
'time_cost': round(elapsed, 2),
'prompt': prompt
})
except Exception as e:
return jsonify({'error': f'生成失败: {str(e)}'}), 500
# 提供生成的图片文件
@app.route('/generated/<filename>')
def serve_image(filename):
return send_file(os.path.join('generated', filename), mimetype='image/png')
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', port=5000)
关键点说明:
使用 huggingface_hub.InferenceClient 的 text_to_image 方法,指定 provider="fal-ai"。
生成成功后返回 PIL.Image 对象,直接保存为 PNG。
每次调用记录日志(提示词、耗时等),便于追踪。
2.2.3 前端页面展示(HTML / CSS / JavaScript)
前端负责提供美观的界面,收集用户输入的提示词,并在生成成功后动态展示图片、耗时及提供下载功能。
templates/index.html 完整代码:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>AI 真实图像生成器 - flux-RealismLora</title>
<link rel="stylesheet" href="/static/style.css">
</head>
<body>
<div class="container">
<header>
<h1>📷 真实世界图像生成器</h1>
<p>基于 XLabs-AI/flux-RealismLora · 极致写实风格</p>
</header>
<main>
<div class="input-section">
<div class="prompt-box">
<label for="prompt-input">📝 描述你想要的画面</label>
<textarea id="prompt-input" rows="4" placeholder="例如:一位老渔夫站在木船甲板上,夕阳从左侧打来,形成戏剧性的边缘光,柯达Portra 400胶片质感..."></textarea>
<div class="prompt-actions">
<button id="random-prompt-btn" class="btn btn-secondary">🎲 随机灵感</button>
<button id="generate-btn" class="btn btn-primary">🚀 生成图像</button>
</div>
</div>
<div class="status-section">
<div id="status-message">等待生成...</div>
<div id="time-cost" style="display:none;">⏱️ 耗时: <span id="cost-value">0</span> 秒</div>
</div>
</div>
<div class="output-section">
<div id="image-container">
<div id="loading-placeholder" style="display:none;">
<div class="spinner"></div>
<p>正在生成中,请稍候...</p>
</div>
<img id="result-image" style="display:none;" alt="生成的图像">
<div id="prompt-display" style="display:none;"></div>
</div>
<div id="download-section" style="display:none;">
<button id="download-btn" class="btn btn-success">⬇️ 下载图片</button>
</div>
</div>
</main>
</div>
<script src="/static/script.js"></script>
</body>
</html>
(前端完整的 style.css 和 script.js 代码已包含在项目文件结构中,此处着重展示了核心的页面结构代码。)
2.3 前端页面与生成图像展示
第一版提示词:
An orange cat sitting on the windowsill, with afternoon sunlight streaming through the blinds and casting shadows on the wooden floor, realistic photography style.
思路:用最直观的自然语言描述主体(橘猫)、环境(窗台、百叶窗)、光影(午后阳光、阴影)以及风格(写实摄影)。
效果:生成成功,但画面景深较浅,稍微偏向普通的AI绘图质感。


第二版提示词(修改后):
A ginger cat sits on the windowsill. Afternoon sunlight filters through the blinds, casting striped shadows across the wooden floor. The cat's pupils are slightly constricted, and its fur shows fine, sharp details. Shot on a Canon 5D Mark IV with a 35mm lens at f/2.8, natural light, high detail, 8k.
修改思路:引入了极致的摄影参数(佳能相机、50mm镜头、f/2.8大光圈),并强调了细节刻画(毛发细节、瞳孔收缩)和画质要求(8k, high detail)。
效果:画面质感瞬间提升,背景产生了真实的景深虚化,色彩和光影对比度更接近真实的单反摄影作品。


2.4 API 调用成功记录展示

日志清晰记录了模型名称、提供商(fal-ai)、生成时间戳以及耗时。
2.5 API 调用体验和心得
- 体验:API 调用非常便捷,且前端与后台的耗时记录(Time cost)完美同步,体验极佳。通过添加特定的镜头参数等“咒语”,能极大改变图片的写实程度。
- 心得:在使用大模型 API 时,提示词(Prompt)的准确性和细节描述直接决定了生成的边界。同时也体会到了后端日志记录(如
generation_log.json)对于系统调试的重要性。
3. GitHub 个人主页搭建

我选择了方案二(借助GitHub Pages搭建个人主页,制作内容较为充实的展示页面)。
GitHub 个人主页地址:https://Aranya12138.github.io/files/example.pdf
内容包括:个人兴趣爱好、个人成果展示,并进行了自我评估(掌握的技能、感兴趣方向、想学习的知识),以及对未来三年(考研/就业)的发展规划。
4. 博客园随笔:个人技能树与目标梳理
随笔地址:https://www.cnblogs.com/Aranya12138/p/22911282
4.1 技能树和技术偏好评估
1. 已具备的专业知识与能力
- 能力 A(底层语言与C/C++基础):掌握C语言的指针、内存管理、文件IO,具备开发学生管理系统、贪吃蛇等课设项目的能力;熟悉C++的类与对象,了解智能指针等基本概念。
- 能力 B(AI模型调用与脚本开发):了解当前主流大模型(如HuggingFace/Flux等)的API调用方式,尝试过简单的本地或云端部署;熟悉Python基础及PyCharm开发环境。
- 能力 C(嵌入式与系统环境配置):拥有使用CCS(Code Composer Studio)进行嵌入式/DSP开发的实际硬件编程与仿真调试经验;熟悉VirtualBox虚拟机搭建Linux环境;熟练使用VS Code等现代化开发工具。
2. 感兴趣的技术方向
- 方向 A(后端服务开发):倾向于使用C++或Python编写高性能服务,深入探索网络编程与多线程技术。
- 方向 B(AI应用开发):基于大模型API进行应用层开发,将AI能力集成到实际工具中。
- 方向 C(嵌入式/系统级开发):偏向底层与硬件的结合,对C/C++应用在底层系统有强烈兴趣。
3. 欠缺的能力(自我评估)
- 欠缺 A(缺乏工程化项目经验):目前未写过超2000行的完整项目,缺乏模块化设计、代码组织与大型项目架构能力。
- 欠缺 B(主流框架与数据库空白):未接触过Django/Flask等后端框架,完全没有SQL数据库使用经验,不懂MySQL/PostgreSQL。
4.2 代码量统计与目标
- 当前代码量:未详细统计,但总体较少,绝大部分来源于课程作业和少量课外自学。
- 本学期目标:课程结束后希望总代码量达到 1.5万 - 2万行。来源计划为:课程团队项目(约3000-5000行)、Python/C++课后实践工具(约2000行)、数据库与前后端练习代码。
4.3 课程期待与收获
- 最期待学习的知识:软件工程完整流程(需求分析至部署);Git分支策略与代码审查等团队协作方法;数据库ER图设计与SQL语句;单元测试与集成测试(Google Test / pytest)。
- 希望获得的收获:能主导或深度参与一个完整的小型软件项目,完成全流程;学会编写规范的需求、设计与API文档;建立工程化思维,弥补在数据库、网络编程、框架使用上的短板,为实习就业奠定基础。
4.4 AI 工具生成的学习指南及分析
说明:以下由 DeepSeek 针对“C/C++和Python基础初学者”生成指南。
DeepSeek 学习指南摘要:
- 工具准备(1-2周):系统学习Git(分支、冲突解决)、安装VS Code/CLion、Postman。
- 基础夯实(3-5周):学习MySQL/SQLite数据库基础;掌握Python Flask/FastAPI搭建服务;复习C++11/14/17新特性。
- 项目实践(6-12周):用C++写“命令行任务管理器”并存入SQLite,用Flask提供HTTP接口;每两周迭代一次;编写单元测试(Google Test/pytest)及完整文档。
- 总结展示(13-16周):撰写总结报告,开源代码完善GitHub仓库。
合理性分析:
该指南结构清晰,推荐的SQLite、Flask、Google Test等技术对C/C++初学者非常友好,两周一迭代的节奏与课程周期匹配。缺点是偏通用化,缺少前端GUI、C++网络编程(如Boost.Asio)以及Docker部署环节;且项目体量偏小,难以承载团队协作与架构设计训练,未利用我已具备的AI API经验。
对自身的帮助评估:
有帮助的部分:Git协作建议精准弥补了我毫无版本控制经验的短板;推荐的项目契合我“C++写核心逻辑,Python写接口”的能力边界;指明了测试工具的学习路径。
总体评价:这是一份合格的通用入门指南,能帮我快速摸清入门路径,但需根据我已有AI基础和C++能力进行大幅度定制,加入更多工程化与团队协作内容。
5. 作业要求说明与后台截图
本作业全程使用 Markdown 编写,以下为博客园后台 Markdown 编辑器的截图。



浙公网安备 33010602011771号