构建AI智能体:二十、妙笔生花:Gradio集成DashScope Qwen-Image模型实现文生图

简介: 本文介绍了一个基于Gradio和阿里云通义千问Qwen-Image模型的文生图应用。该应用通过简洁的Web界面实现文本生成图像功能,支持多种风格(3D卡通、动漫、油画等)和尺寸选择,并包含负面提示词功能。文章详细解析了代码结构,包括API调用封装、参数映射、错误处理等核心功能模块,同时提供了丰富的示例提示词和生成效果展示。该工具适合探索AI图像生成能力,通过调整提示词和参数可优化生成效果。

一、循序渐进

       今天按计划是想讲一些RAG的高阶属性的,但连着几天的烧脑模式,着实脑袋也有点疲惫,经常长篇大论的理论学说,看着可能也觉得枯燥了,今天计划结合前面的几篇文章,做个综合性的演示,温故而知新,同时也让大脑短暂的放松放松,事缓则圆,多几分从容!

       考虑良久,决定搭建一个基于 Gradio 与 DashScope Qwen-Image 模型的文生图演示应用!此应用通过Gradio 直接生成简洁直观的 Web 界面,使用阿里云通义千问的Qwen-Image模型提供文生图能力。只需输入文字描述,选择风格与尺寸,即可快速生成高质量图像,顺便看看不同组合的prompt生成的图片有什么独特之处。

首先,看看整体界面:

image.gif

image.gif

二、文生图实践

1 整体概览

这是一个集成了阿里云 DashScope Qwen-Image 模型Gradio 框架构建的交互式文生图演示应用,考虑到便捷性,特意采用 Gradio 库构建用户界面。应用支持多种图像风格(3D卡通、动漫、油画、水彩等)和尺寸规格,提供负面提示词功能和示例模板,同时也能够输入,通过简单文本输入快速生成精美图像,并支持结果下载与分享。

代码主要功能包括:

  1. API 调用封装:通过 HTTP 请求直接调用 DashScope Qwen-Image API,支持异步任务处理和轮询机制
  2. 参数映射:将用户友好的中文参数名称映射到 API 实际支持的格式
  3. 用户界面:使用 Gradio 构建直观的 Web 界面,支持提示词输入、参数选择和图像展示
  4. 错误处理:完善的异常处理和错误信息反馈机制
  5. 辅助功能:提供示例提示词、图像下载和状态显示等功能

image.gif

       模型使用的是文生图V1版(wanx-v1),是最早期的版本,但它的丰富性足以够我们多场景、多风格、多尺寸的演示,可以根据实际需求切换更新的模型版本,下图是V1版的官网介绍:

image.gif

相比其他版本文生图模型的介绍,按需选择合适的即可:

image.gif

  • 负向提示词(Negative Prompt)

       负面提示词是AI图像生成中的一个重要概念,它在代码中的作用是指导模型避免生成某些特定内容、风格或元素。

       负面提示词是指我们不希望出现在生成图像中的内容描述。与正面提示词(描述希望看到的内容)相反,负面提示词告诉模型应该避免生成什么。

负面提示词的作用:

1. 排除不需要的元素,避免生成特定物体、人物或场景,如果生成自然风景,可以添加"人物、建筑物"作为负面提示词,确保画面纯净

2. 改善图像质量,减少常见的图像缺陷,如使用"模糊、扭曲、畸形、低质量"等负面提示词可以提高图像清晰度

3. 控制风格和氛围,避免不想要的风格倾向,如果希望生成写实风格,可以添加"卡通、漫画、水彩"作为负面提示词

4. 符合内容政策,避免生成不当或敏感内容,如添加"暴力、血腥、裸露"等负面提示词确保生成内容符合规范

2. 代码结构

"""
Qwen-Image 文生图演示应用
基于阿里云 DashScope API 和 Gradio 框架构建的文本到图像生成演示界面
功能特点:
- 支持多种图像风格选择 (3D卡通、动漫、油画、水彩等)
- 提供多种图像尺寸选项 (正方形、横屏、竖屏)
- 支持负面提示词输入,排除不希望出现在图像中的内容
- 提供示例提示词,一键尝试不同风格
- 实时状态反馈和图像下载功能
使用方法:
1. 替换 DASHSCOPE_API_KEY 为您的实际API密钥
2. 运行脚本启动Gradio Web界面
3. 在浏览器中访问 http://localhost:7860 使用应用
注意: 使用前需在阿里云DashScope平台申请API密钥
"""
import gradio as gr
import dashscope
from dashscope import ImageSynthesis
import requests
import tempfile
import os
import time
from PIL import Image
import io
import base64
import json
# 设置您的 DashScope API Key
# 注意: 此处需要替换为实际的API密钥,可从阿里云DashScope控制台获取
DASHSCOPE_API_KEY = os.environ.get("DASHSCOPE_API_KEY", "")  # 请替换为您的实际API Key
# 初始化 DashScope
dashscope.api_key = DASHSCOPE_API_KEY
# DashScope Qwen-Image 支持的风格参数
# 映射用户友好的中文名称到API实际支持的参数格式
SUPPORTED_STYLES = {
    "自动": "auto",
    "3D卡通": "<3d cartoon>",
    "动漫": "<anime>",
    "油画": "<oil painting>",
    "水彩": "<watercolor>",
    "素描": "<sketch>",
    "中国画": "<chinese painting>",
    "扁平插画": "<flat illustration>",
    "摄影": "<photography>",
    "肖像": "<portrait>"
}
# DashScope Qwen-Image 支持的尺寸参数
# 使用星号(*)作为分隔符,这是API要求的格式
SUPPORTED_SIZES = {
    "正方形 (1024x1024)": "1024*1024",
    "横屏 (1280x720)": "1280*720",
    "竖屏 (720x1280)": "720*1280"
}
def generate_image_direct(prompt, size, style=None, negative_prompt=None):
    """
    直接使用HTTP请求调用DashScope API,避免dashscope库的问题
    参数:
        prompt: 图像描述文本
        size: 图像尺寸 (API格式,如"1024*1024")
        style: 图像风格 (可选)
        negative_prompt: 负面提示词 (可选)
    返回:
        成功: 图像文件路径
        失败: 错误信息字符串
    """
    # DashScope API端点
    url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text2image/image-synthesis"
    # 设置请求头
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {DASHSCOPE_API_KEY}",
        "X-DashScope-Async": "enable"  # 启用异步调用
    }
    # 构建请求体
    payload = {
        "model": "wanx-v1",  # 使用wanx-v1模型
        "input": {
            "prompt": prompt
        },
        "parameters": {
            "size": size,
            "n": 1  # 生成1张图像
        }
    }
    # 添加风格参数(如果提供且不是"自动")
    if style and style != "自动":
        # 将中文风格名称转换为API支持的格式
        style_code = SUPPORTED_STYLES.get(style, "auto")
        payload["parameters"]["style"] = style_code
    # 添加负面提示(如果提供)
    if negative_prompt and negative_prompt.strip():
        payload["parameters"]["negative_prompt"] = negative_prompt
    try:
        # 打印请求详情便于调试
        print(f"发送请求到DashScope API: {json.dumps(payload, ensure_ascii=False)}")
        # 发送POST请求到DashScope API
        response = requests.post(url, headers=headers, json=payload)
        response_data = response.json()
        # 打印API响应便于调试
        print(f"API响应: {json.dumps(response_data, ensure_ascii=False, indent=2)}")
        # 检查响应状态码
        if response.status_code == 200:
            # 检查是否为异步任务
            if "output" in response_data and "task_status" in response_data["output"]:
                task_id = response_data["output"]["task_id"]
                print(f"异步任务已创建,任务ID: {task_id}")
                # 轮询任务状态
                return poll_task_result(task_id)
            elif "output" in response_data and "results" in response_data["output"]:
                # 同步响应,直接获取结果
                if len(response_data["output"]["results"]) > 0:
                    image_url = response_data["output"]["results"][0]["url"]
                    return download_and_save_image(image_url)
                else:
                    return "API响应中未包含有效结果"
            else:
                return "API响应格式不正确"
        else:
            # 处理API错误响应
            error_msg = f"API调用失败,状态码: {response.status_code}"
            if "message" in response_data:
                error_msg += f", 错误信息: {response_data['message']}"
            return error_msg
    except Exception as e:
        # 处理异常情况
        error_msg = f"发生异常: {str(e)}"
        print(error_msg)
        import traceback
        traceback.print_exc()  # 打印完整堆栈跟踪便于调试
        return error_msg
def poll_task_result(task_id, max_attempts=30, delay=2):
    """
    轮询异步任务结果
    参数:
        task_id: 异步任务ID
        max_attempts: 最大轮询次数
        delay: 每次轮询间隔(秒)
    返回:
        成功: 图像文件路径
        失败: 错误信息字符串
    """
    # 构建任务状态查询URL
    url = f"https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}"
    headers = {
        "Authorization": f"Bearer {DASHSCOPE_API_KEY}"
    }
    attempt = 0
    # 轮询任务状态
    while attempt < max_attempts:
        try:
            print(f"轮询任务状态,尝试 {attempt + 1}/{max_attempts}")
            # 发送GET请求获取任务状态
            response = requests.get(url, headers=headers)
            response_data = response.json()
            # 打印任务状态响应便于调试
            print(f"任务状态响应: {json.dumps(response_data, ensure_ascii=False, indent=2)}")
            if response.status_code == 200:
                task_status = response_data["output"]["task_status"]
                if task_status == "SUCCEEDED":
                    # 任务成功,提取图像URL
                    if ("output" in response_data and 
                        "results" in response_data["output"] and 
                        len(response_data["output"]["results"]) > 0):
                        image_url = response_data["output"]["results"][0]["url"]
                        return download_and_save_image(image_url)
                    else:
                        return "任务成功但未包含有效结果"
                elif task_status in ["FAILED", "CANCELED"]:
                    # 任务失败,提取错误信息
                    error_msg = f"任务失败,状态: {task_status}"
                    if "message" in response_data["output"]:
                        error_msg += f", 错误信息: {response_data['output']['message']}"
                    return error_msg
                else:
                    # 任务仍在处理中,等待后再次尝试
                    time.sleep(delay)
                    attempt += 1
            else:
                return f"获取任务状态失败,状态码: {response.status_code}"
        except Exception as e:
            # 处理轮询过程中的异常
            error_msg = f"轮询任务时发生异常: {str(e)}"
            print(error_msg)
            time.sleep(delay)
            attempt += 1
    return "任务处理超时"
def download_and_save_image(image_url):
    """
    下载图像并保存到临时文件
    参数:
        image_url: 图像下载URL
    返回:
        成功: 图像文件路径
        失败: 错误信息字符串
    """
    try:
        # 下载图像
        img_response = requests.get(image_url)
        if img_response.status_code == 200:
            # 创建临时文件保存图像
            with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as f:
                f.write(img_response.content)
                image_path = f.name
            print("图像下载成功!")
            return image_path
        else:
            return f"下载图像失败,状态码: {img_response.status_code}"
    except Exception as e:
        return f"下载图像时发生异常: {str(e)}"
# 创建 Gradio 界面
with gr.Blocks(title="Qwen-Image 文生图演示", theme=gr.themes.Soft()) as demo:
    gr.Markdown("# 🎨 Qwen-Image 文生图演示")
    gr.Markdown("使用阿里云 DashScope 的 Qwen-Image 模型根据文本描述生成图像")
    # 使用行布局分割输入和输出区域
    with gr.Row():
        # 左侧输入区域
        with gr.Column(scale=1):
            # 提示词输入框
            prompt = gr.Textbox(
                label="提示词",
                placeholder="请输入详细的图像描述,例如:一只戴着礼帽、拿着手杖的卡通猫,背景是城市夜景",
                lines=3
            )
            # 负面提示词输入框
            negative_prompt = gr.Textbox(
                label="负面提示词 (可选)",
                placeholder="请输入不希望出现在图像中的内容",
                lines=1
            )
            # 图像尺寸选择下拉菜单
            size = gr.Dropdown(
                choices=list(SUPPORTED_SIZES.keys()),
                value="正方形 (1024x1024)",
                label="图像尺寸"
            )
            # 图像风格选择下拉菜单
            style = gr.Dropdown(
                choices=list(SUPPORTED_STYLES.keys()),
                value="自动",
                label="图像风格"
            )
            # 生成图像按钮
            generate_btn = gr.Button("生成图像", variant="primary")
            # 使用说明
            gr.Markdown("### 使用说明")
            gr.Markdown("""
            1. 在提示词框中输入您想要生成的图像描述
            2. 可选:在负面提示词框中输入不希望出现在图像中的内容
            3. 选择图像尺寸和风格,点击"生成图像"按钮
            4. 等待几秒钟,生成的图像将显示在右侧
            **注意**: 首次使用需要设置您的 DashScope API Key
            **支持的尺寸**: 1024x1024, 1280x720, 720x1280
            **支持的风格**: 3D卡通, 动漫, 油画, 水彩, 素描, 中国画, 扁平插画, 摄影, 肖像
            """)
        # 右侧输出区域
        with gr.Column(scale=1):
            # 生成的图像显示区域
            output_image = gr.Image(
                label="生成的图像",
                interactive=False
            )
            # 状态信息显示文本框
            status_text = gr.Textbox(
                label="状态信息",
                interactive=False,
                lines=3
            )
            # 操作按钮行
            with gr.Row():
                download_btn = gr.Button("下载图像")
                clear_btn = gr.Button("清除")
    # 示例提示词区域
    examples = gr.Examples(
        examples=[
            ["一只戴着礼帽、拿着手杖的卡通猫,背景是城市夜景", "正方形 (1024x1024)", "3D卡通", "模糊"],
            ["宁静的湖边日落,天空中有粉红色的云彩,水面有倒影", "横屏 (1280x720)", "中国画", "人物"],
            ["未来科技城市,飞行汽车穿梭在高楼大厦之间,霓虹灯光", "正方形 (1024x1024)", "自动", "传统建筑"],
            ["一只可爱的熊猫在竹林里吃竹子,阳光透过竹叶洒下", "竖屏 (720x1280)", "自动", "人工建筑物"]
        ],
        inputs=[prompt, size, style, negative_prompt],
        label="示例提示词 (点击尝试)"
    )
    # 处理生成按钮点击事件
    def on_generate_click(prompt, size, style, negative_prompt):
        # 验证提示词是否为空
        if not prompt.strip():
            return None, "请输入提示词"
        # 验证API密钥是否已设置
        if not DASHSCOPE_API_KEY or DASHSCOPE_API_KEY == "您的API_KEY":
            return None, "请先设置您的 DashScope API Key"
        # 将用户友好的尺寸名称转换为API格式
        api_size = SUPPORTED_SIZES.get(size, "1024*1024")
        # 调用API生成图像
        result = generate_image_direct(prompt, api_size, style, negative_prompt)
        # 检查结果是图像路径还是错误信息
        if isinstance(result, str) and result.endswith('.png') and os.path.exists(result):
            return result, "图像生成成功!"
        else:
            return None, f"生成失败: {result}"
    # 绑定生成按钮点击事件
    generate_btn.click(
        fn=on_generate_click,
        inputs=[prompt, size, style, negative_prompt],
        outputs=[output_image, status_text]
    )
    # 处理下载按钮点击事件
    def on_download_click(image):
        # 检查是否有图像可下载
        if image is None:
            return "没有可下载的图像"
        # 生成基于时间戳的文件名
        timestamp = int(time.time())
        filename = f"qwen_image_{timestamp}.png"
        try:
            # 如果图像是文件路径,复制到当前目录
            if isinstance(image, str) and os.path.exists(image):
                import shutil
                shutil.copy2(image, filename)
                return f"图像已保存为 {filename}"
            else:
                return "无法保存图像:无效的图像路径"
        except Exception as e:
            return f"保存图像时发生错误: {str(e)}"
    # 绑定下载按钮点击事件
    download_btn.click(
        fn=on_download_click,
        inputs=output_image,
        outputs=status_text
    )
    # 处理清除按钮点击事件
    def on_clear_click():
        return None, "已清除图像"
    # 绑定清除按钮点击事件
    clear_btn.click(
        fn=on_clear_click,
        inputs=None,
        outputs=[output_image, status_text]
    )
# 应用启动入口
if __name__ == "__main__":
    # 检查API密钥是否已设置
    if not DASHSCOPE_API_KEY or DASHSCOPE_API_KEY == "您的API_KEY":
        print("警告: 请先设置您的 DashScope API Key")
        print("您可以在代码中设置 DASHSCOPE_API_KEY 变量")
    # 启动 Gradio 界面
    demo.launch(
        server_name="0.0.0.0",  # 允许外部访问
        server_port=7860,       # 设置端口
        share=False,            # 不创建公开链接
        debug=True              # 启用调试模式
    )

image.gif

  • 使用说明
  1. 首先,您需要在阿里云DashScope平台注册账号并获取API Key
  2. 将代码中的DASHSCOPE_API_KEY变量替换为实际的API Key
  3. 运行代码,Gradio界面将在本地启动
  4. 在浏览器中打开http://localhost:7860访问界面
  5. 输入提示词,选择参数,点击"生成图像"按钮

3. 流程解析

  • 主要步骤:

1. 用户通过Gradio界面输入提示词和参数

2. 调用生成图像函数(使用HTTP请求)

3. 如果是异步任务,则轮询任务状态直到完成

4. 从返回的结果中获取图像URL并下载图像

5. 将图像显示在Gradio界面上

6. 用户可以选择下载图像或清除结果

  • 流程图:

image.gif

  • 流程概述

1. 初始化阶段:应用启动时完成库导入、API密钥设置、参数映射定义和核心函数定义

2. 界面构建:创建Gradio用户界面,包括输入控件、输出区域和功能按钮

3. 用户交互:

  • 用户输入提示词和参数后点击生成按钮
  • 应用调用DashScope API生成图像
  • 处理API响应(同步或异步)
  • 下载并显示生成的图像
  • 用户可选择下载图像或清除显示内容

4. 执行过程

   4.1 初始化阶段    

  1. 导入必要的库:加载Gradio、DashScope、requests等依赖库
  2. 设置API密钥:配置DashScope API访问凭证
  3. 定义参数映射:创建用户友好名称与API参数之间的映射关系
  4. 定义核心函数
  • 生成图像函数:构建并发送API请求
  • 轮询任务函数:检查异步任务状态
  • 下载图像函数:获取并保存生成的图像

   4.2 用户交互阶段      

  1. 构建用户界面:使用Gradio创建包含输入控件和输出区域的Web界面
  2. 定义事件处理:设置按钮点击事件的处理逻辑
  3. 启动应用:运行Gradio服务器,提供Web访问接口

   4.3 API调用阶段    

  1. 发送生成请求:将用户输入转换为API请求格式并发送
  2. 处理异步任务:如果是异步任务,定期轮询直到任务完成
  3. 下载生成结果:从返回的URL下载生成的图像
  4. 错误处理:捕获并显示各种可能的错误信息

   4.4 结果返回阶段  

  1. 显示生成状态:实时反馈生成进度和状态
  2. 展示生成结果:在界面中显示生成的图像
  3. 提供操作选项:允许用户下载图像或清除当前结果

5. 代码分解

5.1 导入和初始化

import gradio as gr
import dashscope
from dashscope import ImageSynthesis
import requests
import tempfile
import os
import time
from PIL import Image
import io
import base64
import json
# 设置您的 DashScope API Key
DASHSCOPE_API_KEY = os.environ.get("DASHSCOPE_API_KEY", "")   # 请替换为您的实际API Key
# 初始化 DashScope
dashscope.api_key = DASHSCOPE_API_KEY

image.gif

导入必要的库:

  • gradio: 用于构建Web界面
  • dashscope: 阿里云的DashScope SDK
  • requests: 用于HTTP请求
  • tempfile, os: 用于文件操作
  • time: 用于时间相关操作
  • PIL, io, base64: 用于图像处理
  • json: 用于JSON数据处理

API密钥设置:从环境变量中获取名为DASHSCOPE_API_KEY的API key。

5.2 参数定义

# DashScope Qwen-Image 支持的风格参数
SUPPORTED_STYLES = {
    "自动": "auto",
    "3D卡通": "<3d cartoon>",
    "动漫": "<anime>",
    "油画": "<oil painting>",
    "水彩": "<watercolor>",
    "素描": "<sketch>",
    "中国画": "<chinese painting>",
    "扁平插画": "<flat illustration>",
    "摄影": "<photography>",
    "肖像": "<portrait>"
}
# DashScope Qwen-Image 支持的尺寸参数
SUPPORTED_SIZES = {
    "正方形 (1024x1024)": "1024*1024",
    "横屏 (1280x720)": "1280*720",
    "竖屏 (720x1280)": "720*1280"
}


  • 参数映射:创建了两个字典,将用户友好的参数名称映射到DashScope API实际支持的参数格式。
  • 解决兼容性问题:通过这种方式,用户界面可以使用友好的中文名称,而API调用使用正确的格式。

5.3 主要功能函数

5.3.1 generate_image_direct 函数

def generate_image_direct(prompt, size, style=None, negative_prompt=None):
    # 构建请求头和请求体
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {DASHSCOPE_API_KEY}",
        "X-DashScope-Async": "enable"  # 启用异步调用
    }
    payload = {
        "model": "wanx-v1",
        "input": {
            "prompt": prompt
        },
        "parameters": {
            "size": size,
            "n": 1
        }
    }
    # 处理可选参数
    if style and style != "自动":
        style_code = SUPPORTED_STYLES.get(style, "auto")
        payload["parameters"]["style"] = style_code
    if negative_prompt and negative_prompt.strip():
        payload["parameters"]["negative_prompt"] = negative_prompt
    # 发送请求并处理响应
    response = requests.post(url, headers=headers, json=payload)
    response_data = response.json()
    # 处理同步和异步响应
    if response.status_code == 200:
        if "output" in response_data and "task_status" in response_data["output"]:
            task_id = response_data["output"]["task_id"]
            return poll_task_result(task_id)  # 异步任务,需要轮询
        elif "output" in response_data and "results" in response_data["output"]:
            # 同步响应,直接获取结果
            if len(response_data["output"]["results"]) > 0:
                image_url = response_data["output"]["results"][0]["url"]
                return download_and_save_image(image_url)

image.gif

  • 直接HTTP请求:使用requests库直接调用DashScope API。
  • 异步处理:通过设置X-DashScope-Async: enable头,启用异步处理模式。
  • 参数处理:正确处理风格和负面提示词等可选参数。
  • 错误处理:检查HTTP状态码和响应结构,确保正确处理各种情况。

5.3.2 poll_task_result 函数

def poll_task_result(task_id, max_attempts=30, delay=2):
    url = f"https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}"
    headers = {"Authorization": f"Bearer {DASHSCOPE_API_KEY}"}
    attempt = 0
    while attempt < max_attempts:
        response = requests.get(url, headers=headers)
        response_data = response.json()
        if response.status_code == 200:
            task_status = response_data["output"]["task_status"]
            if task_status == "SUCCEEDED":
                if ("output" in response_data and 
                    "results" in response_data["output"] and 
                    len(response_data["output"]["results"]) > 0):
                    image_url = response_data["output"]["results"][0]["url"]
                    return download_and_save_image(image_url)
            elif task_status in ["FAILED", "CANCELED"]:
                error_msg = f"任务失败,状态: {task_status}"
                if "message" in response_data["output"]:
                    error_msg += f", 错误信息: {response_data['output']['message']}"
                return error_msg
            else:
                time.sleep(delay)
                attempt += 1

image.gif

  • 轮询机制:定期检查异步任务的状态,直到任务完成或超时。
  • 超时控制:通过max_attempts和delay参数控制轮询频率和最大尝试次数。
  • 状态处理:正确处理任务的各种状态(成功、失败、取消、处理中)。
  • 错误信息提取:从API响应中提取详细的错误信息,便于调试和用户反馈。

5.3.3 download_and_save_image 函数

def download_and_save_image(image_url):
    try:
        img_response = requests.get(image_url)
        if img_response.status_code == 200:
            with tempfile.NamedTemporaryFile(delete=False, suffix='.png') as f:
                f.write(img_response.content)
                image_path = f.name
            return image_path
        else:
            return f"下载图像失败,状态码: {img_response.status_code}"
    except Exception as e:
        return f"下载图像时发生异常: {str(e)}"

image.gif

  • 图像下载:从生成的URL下载图像内容。
  • 临时文件:使用tempfile创建临时文件保存图像,避免永久存储。
  • 错误处理:捕获下载过程中可能出现的异常。

5.3.4 on_generate_click 事件处理函数

def on_generate_click(prompt, size, style, negative_prompt):
    if not prompt.strip():
        return None, "请输入提示词"
    if not DASHSCOPE_API_KEY or DASHSCOPE_API_KEY == "您的API_KEY":
        return None, "请先设置您的 DashScope API Key"
    # 将用户友好的尺寸名称转换为API格式
    api_size = SUPPORTED_SIZES.get(size, "1024*1024")
    # 调用API
    result = generate_image_direct(prompt, api_size, style, negative_prompt)
    # 检查结果是图像路径还是错误信息
    if isinstance(result, str) and result.endswith('.png') and os.path.exists(result):
        return result, "图像生成成功!"
    else:
        return None, f"生成失败: {result}"
generate_btn.click(
    fn=on_generate_click,
    inputs=[prompt, size, style, negative_prompt],
    outputs=[output_image, status_text]
)

image.gif

  • 参数验证:检查提示词是否为空和API密钥是否已设置。
  • 参数转换:将用户友好的参数名称转换为API支持的格式。
  • 结果处理:根据返回结果判断是图像路径还是错误信息,并更新相应的输出控件。

5.4 Gradio 界面构建

with gr.Blocks(title="Qwen-Image 文生图演示", theme=gr.themes.Soft()) as demo:
    gr.Markdown("# 🎨 Qwen-Image 文生图演示")
    with gr.Row():
        with gr.Column(scale=1):
            # 输入控件
            prompt = gr.Textbox(label="提示词", lines=3)
            negative_prompt = gr.Textbox(label="负面提示词 (可选)", lines=2)
            size = gr.Dropdown(choices=list(SUPPORTED_SIZES.keys()), value="正方形 (1024x1024)", label="图像尺寸")
            style = gr.Dropdown(choices=list(SUPPORTED_STYLES.keys()), value="自动", label="图像风格")
            generate_btn = gr.Button("生成图像", variant="primary")
        with gr.Column(scale=1):
            # 输出控件
            output_image = gr.Image(label="生成的图像", interactive=False)
            status_text = gr.Textbox(label="状态信息", interactive=False, lines=3)
            with gr.Row():
                download_btn = gr.Button("下载图像")
                clear_btn = gr.Button("清除")
    # 示例提示词
    examples = gr.Examples(
        examples=[
            ["一只戴着礼帽、拿着手杖的卡通猫,背景是城市夜景", "正方形 (1024x1024)", "3D卡通", "模糊"],
            # 更多示例...
        ],
        inputs=[prompt, size, style, negative_prompt],
        label="示例提示词 (点击尝试)"
    )

image.gif

  • 界面布局:使用gr.Row()和gr.Column()创建响应式布局。
  • 输入控件:

           gr.Textbox: 用于提示词和负面提示词输入

           gr.Dropdown: 用于选择尺寸和风格

           gr.Button: 生成图像按钮

  • 输出控件:

           gr.Image: 显示生成的图像

           gr.Textbox: 显示状态信息

  • 示例功能:使用gr.Examples提供预设的示例,用户可以一键尝试。

5.5 其他功能

def on_download_click(image):
    if image is None:
        return "没有可下载的图像"
    timestamp = int(time.time())
    filename = f"qwen_image_{timestamp}.png"
    try:
        if isinstance(image, str) and os.path.exists(image):
            import shutil
            shutil.copy2(image, filename)
            return f"图像已保存为 {filename}"
        else:
            return "无法保存图像:无效的图像路径"
    except Exception as e:
        return f"保存图像时发生错误: {str(e)}"
download_btn.click(
    fn=on_download_click,
    inputs=output_image,
    outputs=status_text
)
def on_clear_click():
    return None, "已清除图像"
clear_btn.click(
    fn=on_clear_click,
    inputs=None,
    outputs=[output_image, status_text]
)

image.gif

  • 下载功能:将生成的图像保存到本地文件。
  • 清除功能:清除显示的图像和状态信息。
  • 错误处理:捕获可能出现的异常并提供友好的错误信息。

5.6 应用启动

if __name__ == "__main__":
    # 检查API密钥是否已设置
    if not DASHSCOPE_API_KEY or DASHSCOPE_API_KEY == "您的API_KEY":
        print("警告: 请先设置您的 DashScope API Key")
        print("您可以在代码中设置 DASHSCOPE_API_KEY 变量")
    # 启动 Gradio 界面
    demo.launch(
        server_name="0.0.0.0",  # 允许外部访问
        server_port=7860,       # 设置端口
        share=False,            # 不创建公开链接
        debug=True              # 启用调试模式
    )

image.gif

  • API密钥检查:启动前检查API密钥是否已正确设置。
  • 服务器配置:配置服务器监听地址、端口和调试模式。

三、示例画作赏析

1.示例提示词:宁静的湖边日落,天空中有粉红色的云彩,水面有倒影

image.gif

大图预览:

image.gif

2.示例提示词:未来科技城市,飞行汽车穿梭在高楼大厦之间,霓虹灯光

image.gif

大图预览:

image.gif

3.示例提示词:一只可爱的熊猫在竹林里吃竹子,阳光透过竹叶洒下

image.gif

大图预览:

image.gif

四、妙笔生花,美图赏析

1. 提示词:一位绝美的仙侠古风女子,面容精致无瑕,肌肤胜雪,淡妆容,眼眸如秋水含情。身着飘逸的雪纱汉服,衣袂飘飘,上有淡淡的青莲暗纹,发丝边缘闪烁着柔光,站在云雾缭绕的仙境山巅。大师级摄影,胶片质感,超高细节,8K分辨率。

image.gif

大图预览:

image.gif

2. 提示词:中国桂林漓江,春雨后,雾气缭绕如薄纱,江面如镜,倒映着喀斯特地貌的翠绿山峰。一叶扁舟点缀江心,远处山峦层层叠叠,意境如水墨画般诗意朦胧。柔和散射光,宁静氛围。

image.gif

大图预览:

image.gif

3. 提示词:江南古典园林的夏夜,一轮明月倒映在荷花盛开的池塘中,九曲回廊和亭台在水面形成对称倒影。荷花与荷叶上有晶莹的露珠,远处有薄雾和萤火虫微光,氛围宁静梦幻。蓝金色调,工笔细腻。

image.gif

大图预览:

image.gif

4. 提示词:险峻的悬崖绝壁上,一座古老的寺庙腾空而起,四周是深谷和缭绕的云雾。红墙灰瓦,古松斜出,夕阳的金光恰好打在寺庙的屋檐上,神圣而危险。中国山水画意境,细节惊人。

image.gif

大图预览:

image.gif

5. 提示词:一位绝美的古风少女,面容精致无瑕,鹅蛋脸,柳叶细眉,眼眸清澈如秋水含情,眼神略带疏离感。肌肤白皙透亮如雪,吹弹可破。背景虚化,焦点完全集中在完美的脸庞上。柔光照明,肤色均匀,超级细节。

image.gif

大图预览:

image.gif

五、总结

       经过今天的部署,我们能构建了一个功能完整、用户友好的Web应用程序,通过Gradio界面连接Qwen-Image模型实现了从文本描述生成高质量图像的功能。使用前务必将 DASHSCOPE_API_KEY 替换为阿里云平台获取的真实密钥。

       使用时过程中要注意,从提供的示例提示词开始,逐步修改以探索模型能力;善用负面提示词来排除不想要的元素,能极大提升出图质量;仔细观察生成结果和后台打印的日志,根据错误信息调整参数。

相关文章
|
3月前
|
人工智能 缓存 自然语言处理
构建AI智能体:二十二、双剑合璧:Qwen系列双模型在文生文、文生图中的搭配应用
使用Gradio构建的一个演示界面,该界面将展示如何使用Qwen-Turbo生成提示词,然后使用Qwen-Image生成图像。 我们将按照之前的设计,将流程分为两个主要步骤:先生成提示词,然后生成图像。在提示词生成成功之前,直接生成图像将会给出提示先生成提示词。
376 0
|
3月前
|
存储 人工智能 自然语言处理
构建AI智能体:十七、大模型的幻觉难题:RAG 解决AI才华横溢却胡言乱语的弊病
RAG(检索增强生成)是一种结合信息检索与大型语言模型的技术,旨在解决LLM的幻觉问题。其核心流程包括:离线处理阶段(知识库构建)和在线处理阶段(用户查询应答)。通过将外部知识源转换为向量存入数据库,当用户提问时,系统会检索相关内容并增强提示,再由LLM生成准确答案。RAG技术显著提升了AI在专业领域的可靠性,适用于智能客服、企业知识管理、内容创作等场景。尽管面临检索精度、多模态处理等挑战,RAG仍是AI实用化的重要突破方向。
680 2
|
3月前
|
编解码 物联网 API
码上生花:用API链接Qwen-Image系列及衍生LoRA生态模型
Qwen-Image系列开源三月成爆款,凭借中文场景优势与ModelScope平台深度集成,支持文生图、图像编辑及LoRA生态API调用,助力开发者高效创作。
1102 1
|
3月前
|
机器学习/深度学习 人工智能 前端开发
构建AI智能体:十、开箱即见 Gradio:大模型的“魔法画布”,让每一个想法清晰可见
Gradio是一个快速构建机器学习演示界面的Python库,能够将需要数天开发工作的模型展示缩短为几分钟的脚本编写。它通过简单的Python代码即可生成完整的Web应用界面,支持文本、图像、音频等多种交互组件,适用于模型展示、教学演示和原型测试等场景。文章详细介绍了Gradio的核心功能、基础语法和组件使用方法,并通过情感分析和聊天机器人两个实际案例展示了如何快速部署AI模型交互界面。Gradio大幅降低了将模型转化为可交互应用的门槛,使开发者能更专注于模型本身而非界面开发。
792 7
|
2月前
|
机器学习/深度学习 人工智能 数据可视化
构建AI智能体:四十四、线性回归遇见大模型:从数学原理到智能实战
本文系统介绍了线性回归的原理、实现和应用。线性回归通过建立自变量(X)与因变量(Y)之间的线性关系(Y=wX+b)进行预测,核心方法包括最小二乘法(精确解析解)和梯度下降法(迭代数值解)。文章结合Python代码示例,演示了从简单线性回归到多元线性回归的实现过程,并分析了大模型时代线性回归的新应用场景。同时指出了线性回归的局限性(如对异常值敏感)和扩展方向(多项式回归、正则化等)。通过Qwen等大模型的辅助,可以快速生成高质量代码并深入分析回归结果,使这一基础方法在复杂数据中发挥更大价值。
262 6
|
3月前
|
存储 人工智能 自然语言处理
构建AI智能体:二十三、RAG超越语义搜索:如何用Rerank模型实现检索精度的大幅提升
本文介绍了重排序(Rerank)技术在检索增强生成(RAG)系统中的应用。Rerank作为初始检索和最终生成之间的关键环节,通过交叉编码器对初步检索结果进行精细化排序,筛选出最相关的少量文档提供给大语言模型。相比Embedding模型,Rerank能更精准理解查询-文档的语义关系,显著提高答案质量,降低Token消耗。文章详细比较了BGE-Rerank和CohereRerank等主流模型,并通过代码示例展示了Rerank在解决歧义查询(如区分苹果公司和水果)上的优势。
957 5
|
3月前
|
机器学习/深度学习 人工智能 API
构建AI智能体:二十四、RAG的高效召回方法论:提升RAG系统召回率的三大策略实践
本文探讨了检索增强生成(RAG)系统中的高效召回技术。RAG系统通过检索相关文档增强大语言模型的回答质量,但性能受制于垃圾进,垃圾出原则。为提高召回效果,文章重点分析了三种方法:Small-to-Big通过大小文本块映射兼顾检索精度与上下文丰富度;索引扩展(如HyDE)利用大模型生成假设文档来优化检索;双向改写弥合用户查询与文档表述的差异。这些方法从不同角度解决了RAG系统中的语义鸿沟、词汇不匹配等核心问题,可单独或组合使用。高效召回技术能显著提升RAG系统的回答质量和效率。
529 5
|
3月前
|
存储 人工智能 JSON
构建AI智能体:十九、优化 RAG 检索精度:深入解析 RAG 中的五种高级切片策略
本文详细介绍了RAG(检索增强生成)系统中的文本切片策略。RAG切片是将长文档分割为语义完整的小块,以便AI模型高效检索和使用知识。文章分析了五种切片方法:改进固定长度切片(平衡效率与语义)、语义切片(基于嵌入相似度)、LLM语义切片(利用大模型智能分割)、层次切片(多粒度结构)和滑动窗口切片(高重叠上下文)。作者建议根据文档类型和需求选择策略,如通用文档用固定切片,长文档用层次切片,高精度场景用语义切片。切片质量直接影响RAG系统的检索效果和生成答案的准确性。
797 11
|
6月前
|
存储 人工智能 自然语言处理
告别文字乱码!全新文生图模型Qwen-Image来咯
通义千问团队开源了Qwen-Image,一个20B参数的MMDiT模型,具备卓越的文本渲染和图像编辑能力。支持复杂中英文文本生成与自动布局,适用于多场景图像生成与编辑任务,已在魔搭社区与Hugging Face开源。
1161 2
|
4月前
|
人工智能 API 开发工具
构建AI智能体:一、初识AI大模型与API调用
本文介绍大模型基础知识及API调用方法,涵盖阿里云百炼平台密钥申请、DashScope SDK使用、Python调用示例(如文本情感分析、图像文字识别),助力开发者快速上手大模型应用开发。
1738 16
构建AI智能体:一、初识AI大模型与API调用

热门文章

最新文章