目录
问题
核心思路
pollinations
提示词
基于deepseek的图像生成系统
项目说明
详细说明
1. 注册流程
2. 登录流程
3. 图片生成流程
4. 图片下载流程
项目结构
代码实现
1. 配置文件
config.py
2. 数据库模型
models.py
3. 解决循环引用
exts.py
4. 登录和注册逻辑
auth.py
5. Deepseek API 封装
deepseek_api.py
6. Flask 主程序
app.py
7. 前端页面
templates/index.html
templates/login.html
templates/register.html
8. 前端脚本
static/scripts.js
9. 前端样式
static/style.css
10. 依赖文件
requirements.txt
运行项目
1. 安装依赖
2. 启动 MySQL 数据库,并确保数据库连接配置正确
3. 迁移数据库
4. 访问生成的API
问题
直接让deepseek模型去生成图像,实现不了
但是它可以生成图像生成的描述词,那么是否可以使用deepseek生成描述词,然后用其他的AI绘画工具去生成呢?曲线救国
deepseek它能支持Markdown格式显示图片呢!要是再搭配一个在线图像生成API,那可就方便了。只需要访问一个特定的网址,就能实时生成AI图片,就像过去用老式相机拍照,按下快门就能看到结果,多有意思呀!
核心思路
-
DeepSeek本身支持生成markdown格式的内容,而markdown可以嵌入图片链接。
-
通过一个在线图像生成API,只需要提供提示词和参数,就能生成图片并返回URL。
-
把生成的URL嵌入到markdown中,DeepSeek就能直接显示图片!
pollinations
其实这是一个开源项目(pollinations),无需注册或API密钥,为大家提供免费的图像生成服务
首先,咱们得给DeepSeek一个明确的指令,让它帮我们生成图片提示词并嵌入到markdown中。以下是亲测有效的提示词模板,大家可以直接复制使用,当然你也可以根据自己的实际需求来调整。
提示词
你现在是一个ai图片生成机器人,我给你一些提示,你用你的想象力去生动描述这幅图片,并转换成英文填充到下面url的占位符中:- {prompt}必须是英文,符合stable diffusion提示词格式;
这个提示词中最主要要的就是这个URL:
https://image.pollinations.ai/prompt/{prompt}?width=1024&height=1024&seed=100&model=flux&nologo=true
当你向这个URL发送请求Pollinations AI的服务器会根据URL中的参数生成一张图片,并将图片返回给你,其中包含了不少AI绘图所需的参数,内行人应该一眼就能看懂~
作者在官方文档中找了一下,目前到这个生图次数是没有限制的。
测试:沙漠日落
基于deepseek的图像生成系统
作者想做一个基于本地deepseek-r1模型的图像生成系统。问为什么?就是玩玩,好玩,爱玩。。。
项目说明
整个项目包括 Flask 后端、MySQL 数据库、前端页面 和 Deepseek API 集成。项目实现了以下功能:
-
用户注册和登录(使用 Flask-Login 和 MySQL)。
-
AI 图片生成(调用 ChatGPT API 生成提示词,并使用 Pollinations API 生成图片)。
-
图片下载(将生成的图片下载到本地)。
-
前端页面(包括登录、注册和图片生成页面)。
项目的业务逻辑:
详细说明
1. 注册流程
-
前端:用户访问注册页面 (
/register
),填写用户名和密码,点击“Register”按钮。 -
后端:接收
POST /register
请求,验证用户名是否已存在,将用户数据保存到数据库。 -
数据库:存储用户数据(用户名和加密后的密码)。
2. 登录流程
-
前端:用户访问登录页面 (
/login
),填写用户名和密码,点击“Login”按钮。 -
后端:接收
POST /login
请求,验证用户名和密码是否正确,登录成功后返回用户信息。 -
数据库:查询用户数据,验证用户名和密码。
3. 图片生成流程
-
前端:用户访问主页 (
/
),输入提示词,点击“Generate Image”按钮。 -
后端:接收
POST /generate
请求,调用Deepseek API 生成图片提示词,生成图片 URL 并返回给前端。 -
第三方 API:调用 Deepseek API 和 Pollinations API 生成图片。
4. 图片下载流程
-
前端:用户点击“Download Image”按钮,发送
POST /download
请求。 -
后端:接收
POST /download
请求,从 Pollinations API 下载图片并返回给前端。 -
前端:将图片保存到本地。
项目结构
代码实现
前期准备工作,部署本地deepseek模型,可以参考本地部署Deeoseek,安装mysql数据库,创建数据库。
1. 配置文件
config.py
python">import osSECRET_KEY = os.environ.get("SECRET_KEY") or "your_secret_key_here" # 设置一个随机的密钥
#mysql所在的主机名
HOSTNAME = '127.0.0.1'
#mysql监听的端口号
PORT = 3306
#连接Mysql的用户名
USERNAME = 'root' #设置成你自己的
#连接mysql的密码
PASSWORD = '123456' #设置成你自己的
#mysql上创建的数据库
DATABASE = 'image_generator' #设置成你自己的
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8mb4'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)
SQLALCHEMY_DATABASE_URI = DB_URI
SQLALCHEMY_TRACK_MODIFICATIONS = False
2. 数据库模型
models.py
python">from exts import dbclass User(db.Model):__tablename__ = 'user'id = db.Column(db.Integer, primary_key=True, autoincrement=True)username = db.Column(db.String(100), nullable=False)password = db.Column(db.String(1000), nullable=False)# Flask-Login 需要的属性和方法@propertydef is_active(self):return True # 默认所有用户都是活跃的@propertydef is_authenticated(self):return True # 默认所有用户都是已认证的@propertydef is_anonymous(self):return False # 默认所有用户都不是匿名的def get_id(self):return str(self.id) # 返回用户 ID 的字符串形式
3. 解决循环引用
exts.py
为什么要这样做大家可以参考
项目准备(flask+pyhon+MachineLearning)- 1
python">from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
4. 登录和注册逻辑
auth.py
python">from flask import Blueprint, request, jsonify, render_template
from werkzeug.security import generate_password_hash, check_password_hash
from flask_login import login_user, logout_user, login_required
from models import User, db
from flask import redirect, url_forauth = Blueprint("auth", __name__)@auth.route("/login", methods=["GET", "POST"])
def login():if request.method == "POST":data = request.jsonusername = data.get("username")password = data.get("password")user = User.query.filter_by(username=username).first()if not user or not check_password_hash(user.password, password):return jsonify({"error": "Invalid username or password"}), 401login_user(user)return jsonify({"message": "Logged in successfully"}), 200else:return render_template("login.html")@auth.route("/register", methods=["GET", "POST"])
def register():if request.method == "POST":data = request.jsonusername = data.get("username")password = data.get("password")if not username or not password:return jsonify({"error": "Username and password are required"}), 400if User.query.filter_by(username=username).first():return jsonify({"error": "Username already exists"}), 400new_user = User(username=username, password=generate_password_hash(password))db.session.add(new_user)db.session.commit()return jsonify({"message": "User registered successfully"}), 201else:return render_template("register.html")@auth.route("/logout")
@login_required
def logout():logout_user() # 注销用户return redirect(url_for("auth.login")) # 重定向到登录页面
5. Deepseek API 封装
deepseek_api.py
python">from openai import OpenAIclass DeepSeekLocalAPI:def __init__(self, api_base, api_key="none"):"""初始化 DeepSeek 本地模型 API:param api_base: DeepSeek 本地模型的 API 地址,例如 "http://localhost:5001/v1":param api_key: API 密钥(如果不需要可以设置为 "none")"""self.client = OpenAI(base_url=api_base, # 设置本地模型的 API 地址api_key=api_key # 设置 API 密钥)def generate_prompt(self, user_input):"""调用 DeepSeek 本地模型生成图片提示词"""# 系统提示:预设角色system_prompt = ("You are an AI image generation bot. I will give you some prompts, and you will use your imagination to vividly describe the image, ""then convert it into English to fill in the placeholder of the following URL: "";只返回url")# 调用 DeepSeek 本地模型try:response = self.client.chat.completions.create(model="deepseek-r1:32b", # 模型名称messages=[{"role": "system", "content": system_prompt}, # 系统提示{"role": "user", "content": user_input} # 用户输入],max_tokens=500, # 限制生成内容的长度temperature=0.7 # 控制生成内容的创造性)print('正在生成提示词。')# 提取生成的提示词generated_prompt1 = response.choices[0].message.contentreturn generated_prompt1except Exception as e:print(f"Error calling DeepSeek Local API: {e}")return ""# 示例用法
if __name__ == "__main__":# DeepSeek 本地模型的 API 地址api_base = "http://127.0.0.1:11434/v1" # 替换为你的 DeepSeek 本地模型地址api_key = "none" # 如果不需要 API 密钥,可以设置为 "none"# 初始化 DeepSeek 本地模型 APIdeepseek = DeepSeekLocalAPI(api_base, api_key)# 用户输入user_input = "一只凤凰在彩虹色星云中翱翔"# 生成提示词generated_prompt = deepseek.generate_prompt(user_input)if generated_prompt:print("Generated Prompt:", generated_prompt)else:print("Failed to generate prompt.")
6. Flask 主程序
app.py
python">from deepseek_api import DeepSeekLocalAPI
from flask import Flask, render_template, request, jsonify, send_file
from flask_login import LoginManager, current_user, login_required
from models import User
from auth import auth
import requests
import io
import config
from exts import db
from flask_migrate import Migrate
from werkzeug.security import generate_password_hashapp = Flask(__name__)
# 导入自定义配置
app.config.from_object(config)
# 数据库初始化
db.init_app(app)
migrate = Migrate(app,db)login_manager = LoginManager(app)
login_manager.login_view = "auth.login" # 设置登录页面路由# 注册蓝图
app.register_blueprint(auth)deepseek_api_base = "http://127.0.0.1:11434/v1" # 替换为你的 DeepSeek 本地模型地址
deepseek_api_key = "none" # 如果不需要 API 密钥,可以设置为 "none"
deepseek = DeepSeekLocalAPI(deepseek_api_base, deepseek_api_key)@login_manager.user_loader
def load_user(user_id):return User.query.get(int(user_id))@app.route("/")
@login_required
def index():return render_template("index.html")@app.route("/generate", methods=["POST"])
@login_required
def generate():"""生成图片提示词并返回图片 URL"""user_input = request.form.get("prompt", "")if not user_input:return jsonify({"error": "Please provide a prompt"}), 400print(user_input)# 调用 DeepSeek 生成提示词image_url = deepseek.generate_prompt(user_input)generated_prompt = '图像渲染'print('url:',image_url)if not generated_prompt:return jsonify({"error": "Failed to generate prompt"}), 500return jsonify({"image_url": image_url, "prompt": generated_prompt})@app.route("/download", methods=["POST"])
@login_required
def download():image_url = request.json.get("image_url")if not image_url:return jsonify({"error": "Image URL is required"}), 400response = requests.get(image_url)if response.status_code != 200:return jsonify({"error": "Failed to download image"}), 500return send_file(io.BytesIO(response.content),mimetype="image/png",as_attachment=True,download_name="generated_image.png")
if __name__ == "__main__":app.run(debug=True)
7. 前端页面
templates/index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>AI Image Generator</title><link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body><div class="container"><h1>图像自动生成器</h1><form id="prompt-form"><textarea id="prompt-input" placeholder="Enter your prompt here..."></textarea><button type="submit">生成图像</button></form><div id="result"><p id="status-message"></p> <!-- 显示生成状态 --><img id="generated-image" src="" alt="Generated Image"><p id="generated-prompt"></p><button id="download-button" style="display: none;">下载图像</button></div><a href="{{ url_for('auth.logout') }}">退出登录</a></div><script src="{{ url_for('static', filename='scripts.js') }}"></script>
</body>
</html>
templates/login.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>登录</title><link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body><div class="container"><h1>登录</h1><form id="login-form"><input type="text" id="username" placeholder="Username" required><input type="password" id="password" placeholder="Password" required><button type="submit">登录</button></form><p>还没有账号? <a href="{{ url_for('auth.register') }}">注册</a></p></div><script src="{{ url_for('static', filename='scripts.js') }}"></script>
</body>
</html>
templates/register.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>注册</title><link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
</head>
<body><div class="container"><h1>注册</h1><form id="register-form"><input type="text" id="username" placeholder="Username" required><input type="password" id="password" placeholder="Password" required><button type="submit">注册</button></form><p>已经有了账号?<a href="{{ url_for('auth.login') }}">登录</a></p></div><script src="{{ url_for('static', filename='scripts.js') }}"></script>
</body>
</html>
8. 前端脚本
static/scripts.js
// 登录表单提交
document.getElementById("login-form")?.addEventListener("submit", async (e) => {e.preventDefault();const data = {username: document.getElementById("username").value,password: document.getElementById("password").value,};const response = await fetch("/login", {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify(data),});const result = await response.json();if (response.ok) {window.location.href = "/"; // 登录成功后跳转到主页} else {alert(result.error); // 显示错误信息}
});// 注册表单提交
document.getElementById("register-form")?.addEventListener("submit", async (e) => {e.preventDefault();const data = {username: document.getElementById("username").value,password: document.getElementById("password").value,};const response = await fetch("/register", {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify(data),});const result = await response.json();if (response.ok) {alert(result.message); // 注册成功window.location.href = "/login"; // 跳转到登录页面} else {alert(result.error); // 显示错误信息}
});document.getElementById("prompt-form")?.addEventListener("submit", async (e) => {e.preventDefault(); // 阻止表单默认提交行为const prompt = document.getElementById("prompt-input").value;const statusMessage = document.getElementById("status-message");// 显示“生成中”statusMessage.innerText = "Generating...";statusMessage.style.color = "blue";try {const response = await fetch("/generate", {method: "POST",headers: {"Content-Type": "application/x-www-form-urlencoded",},body: `prompt=${encodeURIComponent(prompt)}`,});const data = await response.json();if (data.image_url) {// 显示“生成完成”statusMessage.innerText = "Generation complete!";statusMessage.style.color = "green";// 显示生成的图片和提示词document.getElementById("generated-image").src = data.image_url;document.getElementById("generated-prompt").innerText = data.prompt;document.getElementById("download-button").style.display = "block";} else {// 显示错误信息statusMessage.innerText = "Error: " + (data.error || "Failed to generate image");statusMessage.style.color = "red";}} catch (error) {console.error("Error:", error);statusMessage.innerText = "An error occurred. Please try again.";statusMessage.style.color = "red";}
});// 图片下载
document.getElementById("download-button")?.addEventListener("click", async () => {const imageUrl = document.getElementById("generated-image").src;const response = await fetch("/download", {method: "POST",headers: {"Content-Type": "application/json",},body: JSON.stringify({ image_url: imageUrl }),});if (response.ok) {const blob = await response.blob();const url = window.URL.createObjectURL(blob);const a = document.createElement("a");a.href = url;a.download = "generated_image.png";document.body.appendChild(a);a.click();a.remove();} else {alert("Failed to download image");}
});
9. 前端样式
static/style.css
body {font-family: Arial, sans-serif;background-color: #f4f4f9;color: #333;margin: 0;padding: 0;display: flex;justify-content: center;align-items: center;height: 100vh;
}.container {background: white;padding: 2rem;border-radius: 8px;box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);max-width: 600px;width: 100%;text-align: center;
}h1 {margin-bottom: 1.5rem;
}input, textarea {width: 100%;padding: 0.75rem;margin-bottom: 1rem;border: 1px solid #ccc;border-radius: 4px;font-size: 1rem;
}button {width: 100%;padding: 0.75rem;background-color: #007bff;color: white;border: none;border-radius: 4px;font-size: 1rem;cursor: pointer;
}button:hover {background-color: #0056b3;
}#result {margin-top: 1.5rem;
}#generated-image {max-width: 100%;border-radius: 4px;margin-bottom: 1rem;
}#generated-prompt {font-size: 0.9rem;color: #666;
}#status-message {font-size: 1.2rem;font-weight: bold;margin-bottom: 1rem;
}a {color: #007bff;text-decoration: none;
}a:hover {text-decoration: underline;
}
10. 依赖文件
requirements.txt
Flask==2.3.2
Flask-SQLAlchemy==3.0.5
Flask-Login==0.6.2
mysql-connector-python==8.0.33
openai==1.0.0
requests==2.31.0
运行项目
1. 安装依赖
pip install -r requirements.txt
2. 启动 MySQL 数据库,并确保数据库连接配置正确
3. 迁移数据库
这一步是为了创建数据库表,可以参考项目准备(flask+pyhon+MachineLearning)- 1
在终端中依次执行
初始化(只需要执行一次)
flask db init
生成文件
flask db migrate
迁移数据库
flask db upgrade
4. 访问生成的API
访问 http://localhost:5000
,注册并登录后即可使用图片生成和下载功能。