前几天分享过一个开源项目 screenshot-to-code ,这个项目主要功能是利用人工智能技术将屏幕截图转换为前端网页代码的工具。
pip install zhipuai
pip install fastapi uvicorn
pip install sse-starlette
from sse_starlette.sse import EventSourceResponse
<link rel="stylesheet" href="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/twitter-bootstrap/4.6.1/css/bootstrap.min.css">
<script src="https://lf3-cdn-tos.bytecdntp.com/cdn/expire-1-M/jquery/2.0.3/jquery.min.js"></script>
<script src="https://lf26-cdn-tos.bytecdntp.com/cdn/expire-1-M/marked/4.0.2/marked.min.js"></script>
<style>
<header class="bg-info text-white text-center py-3">
<h1>AI 图片解析</h1>
</header>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 py-4">
<h4>上传图片</h4>
<div id="upload-area" class="upload-area">
<p>拖放图片到此处,或点击上传</p>
</div>
<input type="file" id="file-input" hidden accept="image/*">
<div id="file-list" class="mt-3"></div>
</div>
<div class="col-md-6 bg-light py-4">
<h4>AI 解析选项</h4>
<!-- 点击解析按钮 -->
<button id="parse-btn" class="btn btn-warning btn-block mb-3 btn-lg" disabled>开始解析</button>
<div id="output"></div>
</div>
</div>
</div>
<footer class="bg-light text-center py-3">
<p>© 2024 AI 图片解析平台</p>
</footer>
.upload-area {
border: 2px dashed #cce5ff;
border-radius: 5px;
padding: 60px;
font-size:48px;
text-align: center;
color: #6c757d;
cursor: pointer;
}
.upload-area.drag-over {
background-color: #e9ecef;
border-color: #cce5ff;
}
$(document).ready(function() {
let base64Data = null; // 当前图片的 Base64 数据
// 转换文件为 Base64
function toBase64(file) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = () => resolve(reader.result);
reader.onerror = reject;
reader.readAsDataURL(file);
});
}
// 处理图片文件
async function handleFiles(files) {
for (const file of files) {
if (file.type.startsWith('image/')) {
base64Data = await toBase64(file);
// 显示图片预览
const img = $('<img class="img-fluid">').attr('src', base64Data);
$('#file-list').append(img);
// 启用解析按钮
$('#parse-btn').prop('disabled', false);
} else {
alert('仅支持上传图片文件!');
}
}
}
// 点击“解析”按钮时触发
$('#parse-btn').click(async function () {
if (!base64Data) {
alert('请先上传图片');
return;
}
$('#output').html('');
// 通过 EventSource 发送图片数据
const eventSource = new EventSource(`/start-parsing?image=${encodeURIComponent(base64Data)}`);
let _htmlContent = '';
eventSource.onmessage = function (event) {
const data = JSON.parse(event.data);
const content = data.content;
if (content === "[DONE]") {
eventSource.close();
console.log("Stream completed.");
} else {
_htmlContent += content; // 逐步更新内容
}
$('#output').html(marked.parse(_htmlContent));
};
});
// 拖动和点击事件
$('#upload-area').click(function () {
$('#file-input').click();
});
$('#upload-area').on('dragover', function (e) {
e.preventDefault();
$(this).addClass('drag-over');
});
$('#upload-area').on('dragleave', function () {
$(this).removeClass('drag-over');
});
$('#upload-area').on('drop', function (e) {
e.preventDefault();
$(this).removeClass('drag-over');
handleFiles(e.originalEvent.dataTransfer.files);
});
$('#file-input').change(function () {
handleFiles(this.files);
});
});
async def start_parsing(request: Request):
img_base = request.query_params.get('image')
client = ZhipuAI(api_key=apiKey)
"""
接收图片的 Base64 数据并解析
"""
response = client.chat.completions.create(
model="glm-4v-plus", # 填写需要调用的模型名称
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": img_base
}
},
{
"type": "text",
"text": "使用 bootstrap 生成一个跟他一摸一样网页代码,只需要输出代码即可。"
}
]
}
]
)
# 生成器:逐步输出流式数据
async def event_stream():
for chunk in response:
delta_content = response.choices[0].message.content
if delta_content:
yield f"{json.dumps({'content': delta_content})}"
#yield "data: [DONE]\n\n" # 结束标志
yield f"{json.dumps({'content': '[DONE]'})}"# 结束标志
return EventSourceResponse(event_stream())