Back to skills
SkillHub ClubShip Full StackFull Stack

qwen-image

Generate images using Alibaba Cloud Bailian Qwen-Image and Z-Image models (通义千图文生图 + 人像照片模型)

Packaged view

This page reorganizes the original catalog entry around fit, installability, and workflow context first. The original raw source lives below.

Stars
3,127
Hot score
99
Updated
March 20, 2026
Overall rating
C0.0
Composite score
0.0
Best-practice grade
B84.0

Install command

npx @skill-hub/cli install openclaw-skills-qwen-image-skill

Repository

openclaw/skills

Skill path: skills/irron/qwen-image-skill

Generate images using Alibaba Cloud Bailian Qwen-Image and Z-Image models (通义千图文生图 + 人像照片模型)

Open repository

Best for

Primary workflow: Ship Full Stack.

Technical facets: Full Stack.

Target audience: everyone.

License: Unknown.

Original source

Catalog source: SkillHub Club.

Repository owner: openclaw.

This is still a mirrored public skill entry. Review the repository before installing into production workflows.

What it helps with

  • Install qwen-image into Claude Code, Codex CLI, Gemini CLI, or OpenCode workflows
  • Review https://github.com/openclaw/skills before adding qwen-image to shared team environments
  • Use qwen-image for development workflows

Works across

Claude CodeCodex CLIGemini CLIOpenCode

Favorites: 0.

Sub-skills: 0.

Aggregator: No.

Original source / Raw SKILL.md

---
name: qwen-image
description: Generate images using Alibaba Cloud Bailian Qwen-Image and Z-Image models (通义千图文生图 + 人像照片模型)
homepage: https://help.aliyun.com/zh/model-studio/qwen-image-api
metadata:
  openclaw:
    emoji: 🎨
  requires:
    env:
      - DASHSCOPE_API_KEY
---

# Qwen-Image / Z-Image Skill

基于阿里云百炼的文图生成技能,**智能识别场景**自动选择最佳模型:
- 🧍 **人像/照片** → **z-image-turbo**(专精高质量人像,支持胶片质感)
- 🖼️ **通用文图** → **qwen-image-max**(擅长复杂文字渲染、艺术风格)

## Features

- **🤖 智能模型选择**:自动检测人像场景,无需手动选择模型
- **🎨 双模型支持**:Qwen-Image(通用) + Z-Image(人像)
- **✍️ 中文文字渲染**:在图像中完美呈现复杂中文字符
- **📐 多尺寸支持**:16:9、4:3、1:1、3:4、9:16 等多种比例
- **🔧 可手动指定**:支持强制使用特定模型

## Setup

1. 从 [阿里云百炼控制台](https://bailian.console.aliyun.com/) 获取 API Key
2. 配置方式选择其一:
   - **环境变量**:`export DASHSCOPE_API_KEY="sk-xxx"`
   - **TOOLS.md**:在 TOOLS.md 中添加 `DASHSCOPE_API_KEY: sk-xxx`

> **地域注意**:北京和新加坡地域 API Key 不互通

## Available Models

| 模型 | 描述 | 最佳场景 |
|------|------|----------|
| **qwen-image-max** | 最佳质量,减少AI痕迹,文字渲染优秀 | 漫画、插画、图文设计、风景、静物 |
| **qwen-image-plus** | 质量与速度平衡 | 通用场景 |
| **qwen-image** | 基础模型 | 快速生成 |
| **z-image-turbo** | 人像专精,胶片质感,真实感强 | 人像照片、人像写真、film grain效果 |

## Supported Sizes

| 尺寸 | 比例 | 说明 |
|------|------|------|
| 1664*928 | 16:9 | 横向宽屏(通用默认)|
| 1472*1104 | 4:3 | 标准比例 |
| 1328*1328 | 1:1 | 方形 |
| 1104*1472 | 3:4 | 竖向 |
| 928*1664 | 9:16 | 手机竖屏 |
| 1120*1440 | 4:5 | **人像推荐** |

## Usage

### 🎯 快速入门(推荐)

直接写提示词,**自动识别场景**并选择最佳模型:

```bash
# 人像类 → 自动使用 z-image-turbo
python scripts/generate.py "短发少女,清新自然风格,微笑"

# 通用类 → 自动使用 qwen-image-max
python scripts/generate.py "七龙珠孙悟空对战比克大魔王,漫画风格"

# 含film grain关键词 → 自动使用 z-image
python scripts/generate.py "胶片感,Kodak Portra 400风格的人像"
```

### 🔧 高级选项

```bash
python scripts/generate.py "prompt" \
    --model z \              # 强制指定模型 (z/qwen/auto)
    --size 1328*1328 \       # 图片尺寸
    --prompt-extend \        # 开启提示词扩展
    --no-watermark \         # 禁用水印
    --output my-image.png    # 输出路径
```

## Auto-Detection Keywords

以下关键词会触发自动选择 **z-image-turbo**:

**人物类**:人、女、男、少女、帅哥、美女、肖像、人物、face、facial

**照片/胶片类**:photo、photograph、film grain、analog、Kodak、胶片、portra、cinematic、photorealistic、真实、写真人像

## 使用示例

### 人像照片(z-image)
```bash
python scripts/generate.py "东亚年轻女性,户外雪地场景,film grain效果,胶片质感"
```

### 漫画风格(qwen-image)
```bash
python scripts/generate.py "七龙珠孙悟空对战比克大魔王,漫画风格,能量波爆炸,天空背景"
```

### 带中文文字的漫画
```bash
python scripts/generate.py "一副对联,上联:智启千问,下联:机道为善,横批:人机共生"
```

## Tips

- **人像首选 z-image**:对面部细节、皮肤质感、胶片感优化更好
- **文字渲染选 qwen**:复杂中文、图文混排场景更精准
- **自动模式省心**:无需纠结选哪个模型
- **提示词长度**:正向 ≤800字符,负向 ≤500字符
- **扩展提示词**:`--prompt-extend` 可以让AI自动优化你的描述

---

*Qwen-Image Skill - 国产文生图利器 🇨🇳*


---

## Referenced Files

> The following files are referenced in this skill and included for context.

### scripts/generate.py

```python
#!/usr/bin/env python3
"""
Qwen-Image / Z-Image 生图脚本
自动判断场景选择模型,人像用 z-image,其他用 qwen-image
"""

import argparse
import os
import sys
import json
import re
from pathlib import Path
import http.client
from urllib.parse import urlparse
from datetime import datetime


def get_api_key() -> str:
    """从环境变量或 TOOLS.md 获取 API Key"""
    # 1. 环境变量
    key = os.environ.get("DASHSCOPE_API_KEY")
    if key:
        return key
    
    # 2. 从 TOOLS.md 读取
    possible_paths = [
        Path(__file__).parent.parent.parent.parent / "TOOLS.md",
        Path.cwd() / "TOOLS.md",
        Path("/home/admin/clawd/TOOLS.md"),
    ]
    
    for path in possible_paths:
        try:
            if path.exists():
                content = path.read_text(encoding="utf-8")
                match = re.search(r'DASHSCOPE_API_KEY:\s*(\S+)', content)
                if match:
                    key = match.group(1)
                    if key and not key.startswith('请在这里'):
                        return key
        except Exception:
            continue
    
    return None


# 人像/照片关键词
PORTRAIT_KEYWORDS = [
    "人", "女", "男", "少女", "帅哥", "美女", "肖像", "portrait", "woman", "man", "girl", "boy",
    "人物", "face", " facial", "selfie", "photo", "photograph", "film grain", "analog",
    "Kodak", "胶片", "portra", "cinematic", "photorealistic", "真实", "写真人像"
]

def is_portrait_prompt(prompt: str) -> bool:
    """判断提示词是否涉及人像/照片场景"""
    prompt_lower = prompt.lower()
    return any(kw in prompt or kw.lower() in prompt_lower for kw in PORTRAIT_KEYWORDS)


# 模型配置
MODELS = {
    "qwen": {
        "name": "qwen-image-max",
        "sizes": {
            "1664*928": (1664, 928),   # 16:9
            "1472*1104": (1472, 1104), # 4:3
            "1328*1328": (1328, 1328), # 1:1
            "1104*1472": (1104, 1472), # 3:4
            "928*1664": (928, 1664),   # 9:16
        },
        "default_size": "1328*1328"
    },
    "z": {
        "name": "z-image-turbo",
        "sizes": {
            "1120*1440": (1120, 1440), # 人像推荐
            "1664*928": (1664, 928),
            "1328*1328": (1328, 1328),
        },
        "default_size": "1120*1440"
    }
}


def parse_size(size_str: str) -> tuple:
    """解析尺寸字符串,返回 (width, height)"""
    parts = size_str.split("*")
    if len(parts) == 2:
        return int(parts[0]), int(parts[1])
    return 1328, 1328


def generate_image(
    prompt: str,
    model_type: str = "auto",
    size: str = None,
    prompt_extend: int = 0,
    watermark: bool = False,
    output: str = None
) -> str:
    """
    生成图片
    
    Args:
        prompt: 提示词
        model_type: auto/qwen/z | auto 自动判断
        size: 尺寸
        prompt_extend: 是否扩展提示词 (0/1)
        watermark: 是否添加水印
        output: 输出路径
    """
    api_key = get_api_key()
    if not api_key:
        print("❌ 错误: 未设置 DASHSCOPE_API_KEY 环境变量")
        print("请设置: export DASHSCOPE_API_KEY='your-api-key'")
        sys.exit(1)
    
    # 判断模型
    if model_type == "auto":
        if is_portrait_prompt(prompt):
            model_config = MODELS["z"]
            model_type = "z"
            print("🔍 检测到人像/照片场景,自动使用 z-image 模型")
        else:
            model_config = MODELS["qwen"]
            model_type = "qwen"
    else:
        model_config = MODELS.get(model_type, MODELS["qwen"])
    
    # 确定尺寸
    if size and size in model_config["sizes"]:
        size_str = size
    else:
        size_str = model_config["default_size"]
    width, height = model_config["sizes"][size_str]
    
    # 构建请求体 (messages 格式)
    payload = {
        "model": model_config["name"],
        "input": {
            "messages": [
                {
                    "role": "user",
                    "content": [
                        {
                            "text": prompt
                        }
                    ]
                }
            ]
        },
        "parameters": {
            "size": size_str,
            "prompt_extend": bool(prompt_extend),
            "watermark": watermark
        }
    }
    
    # 人像类添加额外参数
    if model_type == "z" and "film grain" not in prompt.lower():
        # 自动添加胶片效果,除非用户已指定
        pass  # 可选:可以自动增强提示词
    
    print(f"🎨 正在生成图片...")
    print(f"   模型: {model_config['name']}")
    print(f"   尺寸: {size_str} ({width}x{height})")
    print(f"   提示词: {prompt[:60]}{'...' if len(prompt) > 60 else ''}")
    
    # 发送请求
    headers = {
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json"
    }
    
    try:
        conn = http.client.HTTPSConnection("dashscope.aliyuncs.com", timeout=120)
        conn.request(
            "POST",
            "/api/v1/services/aigc/multimodal-generation/generation",
            body=json.dumps(payload),
            headers=headers
        )
        
        response = conn.getresponse()
        data = response.read().decode("utf-8")
        
        if response.status != 200:
            print(f"❌ HTTP 错误 {response.status}: {data}")
            sys.exit(1)
        
        result = json.loads(data)
        
        # 解析响应: output.choices[0].message.content[0].image
        if "output" in result and "choices" in result["output"]:
            choice = result["output"]["choices"][0]
            content = choice["message"]["content"]
            
            # 找到 image
            image_url = None
            for item in content:
                if "image" in item:
                    image_url = item["image"]
                    break
            
            if not image_url:
                print(f"❌ 未找到图片 URL: {result}")
                sys.exit(1)
            
            # 确定输出文件名
            if not output:
                timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
                output = f"{model_type}_image_{timestamp}.png"
            
            # 下载图片
            print(f"⬇️  下载图片...")
            parsed = urlparse(image_url)
            img_conn = http.client.HTTPSConnection(parsed.netloc, timeout=60)
            img_conn.request("GET", parsed.path + (f"?{parsed.query}" if parsed.query else ""))
            img_resp = img_conn.getresponse()
            
            with open(output, "wb") as f:
                f.write(img_resp.read())
            img_conn.close()
            
            print(f"✅ 图片已保存: {os.path.abspath(output)}")
            conn.close()
            return output
        
        print(f"❌ API 返回异常: {result}")
        sys.exit(1)
        
    except Exception as e:
        print(f"❌ 错误: {e}")
        import traceback
        traceback.print_exc()
        sys.exit(1)


def main():
    parser = argparse.ArgumentParser(
        description="使用 Qwen-Image / Z-Image 模型生成图片",
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog="""
示例:
  # 自动判断模型
  python generate.py "一只可爱的橘猫"
  
  # 指定人像模式 (z-image)
  python generate.py "短发少女" --model z --size 1120*1440
  
  # 通用模式 (qwen-image)
  python generate.py "赛博朋克城市" --model qwen --size 1664*928
        """
    )
    
    parser.add_argument("prompt", help="图片生成提示词(支持中文)")
    parser.add_argument("--model", default="auto", choices=["auto", "qwen", "z"],
                        help="模型选择 (auto/qwen/z, 默认 auto)")
    parser.add_argument("--size", help="图片尺寸 (如: 1664*928, 1120*1440)")
    parser.add_argument("--extend", action="store_true",
                        help="开启提示词扩展")
    parser.add_argument("--watermark", action="store_true",
                        help="添加水印")
    parser.add_argument("--output", "-o", help="输出文件路径")
    
    args = parser.parse_args()
    
    generate_image(
        prompt=args.prompt,
        model_type=args.model,
        size=args.size,
        prompt_extend=args.extend,
        watermark=args.watermark,
        output=args.output
    )


if __name__ == "__main__":
    main()

```



---

## Skill Companion Files

> Additional files collected from the skill directory layout.

### _meta.json

```json
{
  "owner": "irron",
  "slug": "qwen-image-skill",
  "displayName": "qwenz-image-gen",
  "latest": {
    "version": "1.0.0",
    "publishedAt": 1770693195834,
    "commit": "https://github.com/openclaw/skills/commit/1da3ac907a61b6696b776c0353c164fce21ef974"
  },
  "history": []
}

```

qwen-image | SkillHub