
Aliyun Qwen Image
- 70 installs
- 396 repo stars
- Updated July 18, 2026
- cinience/alicloud-skills
Generate images with Alibaba Cloud Model Studio Qwen Image models via the DashScope SDK, mapping prompt, size, seed, and reference image.
About
Uses the DashScope SDK with Qwen Image models to run image.generate requests and standardize prompt, size, seed, and reference-image inputs. A developer uses it to add text-to-image generation to a pipeline.
- qwen-image, plus/max, and 2.0 series model variants
- Standardized image.generate inputs/outputs for a video-agent pipeline
Aliyun Qwen Image by the numbers
- 70 all-time installs (skills.sh)
- Ranked #848 of 1,335 Generative Media skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/cinience/alicloud-skills --skill aliyun-qwen-imageAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 70 |
|---|---|
| repo stars | ★ 396 |
| Last updated | July 18, 2026 |
| Repository | cinience/alicloud-skills ↗ |
What it does
Generate images with Alibaba Cloud Model Studio Qwen Image models via the DashScope SDK, mapping prompt, size, seed, and reference image.
Files
Category: provider
Model Studio Qwen Image
Validation
mkdir -p output/aliyun-qwen-image
python -m py_compile skills/ai/image/aliyun-qwen-image/scripts/generate_image.py && echo "py_compile_ok" > output/aliyun-qwen-image/validate.txtPass criteria: command exits 0 and output/aliyun-qwen-image/validate.txt is generated.
Output And Evidence
- Write generated image URLs, prompts, and metadata to
output/aliyun-qwen-image/. - Keep at least one sample JSON response per run.
Build consistent image generation behavior for the video-agent pipeline by standardizing image.generate inputs/outputs and using DashScope SDK (Python) with the exact model name.
Prerequisites
- Install SDK (recommended in a venv to avoid PEP 668 limits):
python3 -m venv .venv
. .venv/bin/activate
python -m pip install dashscope- Set
DASHSCOPE_API_KEYin your environment, or adddashscope_api_keyto~/.alibabacloud/credentials(env takes precedence).
Critical model names
Use one of these exact model strings:
qwen-imageqwen-image-plusqwen-image-maxqwen-image-2.0qwen-image-2.0-proqwen-image-2.0-2026-03-03qwen-image-2.0-pro-2026-03-03qwen-image-max-2025-12-30qwen-image-plus-2026-01-09
Normalized interface (image.generate)
Request
prompt(string, required)negative_prompt(string, optional)size(string, required) e.g.1024*1024,768*1024style(string, optional)seed(int, optional)reference_image(string | bytes, optional)
Response
image_url(string)width(int)height(int)seed(int)
Quickstart (normalized request + preview)
Minimal normalized request body:
{
"prompt": "a cinematic portrait of a cyclist at dusk, soft rim light, shallow depth of field",
"negative_prompt": "blurry, low quality, watermark",
"size": "1024*1024",
"seed": 1234
}Preview workflow (download then open):
curl -L -o output/aliyun-qwen-image/images/preview.png "<IMAGE_URL_FROM_RESPONSE>" && open output/aliyun-qwen-image/images/preview.pngLocal helper script (JSON request -> image file):
python skills/ai/image/aliyun-qwen-image/scripts/generate_image.py \\
--request '{"prompt":"a studio product photo of headphones","size":"1024*1024"}' \\
--output output/aliyun-qwen-image/images/headphones.png \\
--print-responseParameters at a glance
| Field | Required | Notes |
|---|---|---|
prompt | yes | Describe a scene, not just keywords. |
negative_prompt | no | Best-effort, may be ignored by backend. |
size | yes | WxH format, e.g. 1024*1024, 768*1024. |
style | no | Optional stylistic hint. |
seed | no | Use for reproducibility when supported. |
reference_image | no | URL/file/bytes, SDK-specific mapping. |
Quick start (Python + DashScope SDK)
Use the DashScope SDK and map the normalized request into the SDK call. Note: For qwen-image-max, the DashScope SDK currently succeeds via ImageGeneration (messages-based) rather than ImageSynthesis. If the SDK version you are using expects a different field name for reference images, adapt the input mapping accordingly.
import os
from dashscope.aigc.image_generation import ImageGeneration
# Prefer env var for auth: export DASHSCOPE_API_KEY=...
# Or use ~/.alibabacloud/credentials with dashscope_api_key under [default].
def generate_image(req: dict) -> dict:
messages = [
{
"role": "user",
"content": [{"text": req["prompt"]}],
}
]
if req.get("reference_image"):
# Some SDK versions accept {"image": <url|file|bytes>} in messages content.
messages[0]["content"].insert(0, {"image": req["reference_image"]})
response = ImageGeneration.call(
model=req.get("model", "qwen-image-max"),
messages=messages,
size=req.get("size", "1024*1024"),
api_key=os.getenv("DASHSCOPE_API_KEY"),
# Pass through optional parameters if supported by the backend.
negative_prompt=req.get("negative_prompt"),
style=req.get("style"),
seed=req.get("seed"),
)
# Response is a generation-style envelope; extract the first image URL.
content = response.output["choices"][0]["message"]["content"]
image_url = None
for item in content:
if isinstance(item, dict) and item.get("image"):
image_url = item["image"]
break
return {
"image_url": image_url,
"width": response.usage.get("width"),
"height": response.usage.get("height"),
"seed": req.get("seed"),
}Error handling
| Error | Likely cause | Action |
|---|---|---|
| 401/403 | Missing or invalid DASHSCOPE_API_KEY | Check env var or ~/.alibabacloud/credentials, and access policy. |
| 400 | Unsupported size or bad request shape | Use common WxH and validate fields. |
| 429 | Rate limit or quota | Retry with backoff, or reduce concurrency. |
| 5xx | Transient backend errors | Retry with backoff once or twice. |
Output location
- Default output:
output/aliyun-qwen-image/images/ - Override base dir with
OUTPUT_DIR.
Operational guidance
- Store the returned image in object storage and persist only the URL in metadata.
- Cache results by
(prompt, negative_prompt, size, seed, reference_image hash)to avoid duplicate costs. - Add retries for transient 429/5xx responses with exponential backoff.
- Some backends ignore
negative_prompt,style, orseed; treat them as best-effort inputs. - If the response contains no image URL, surface a clear error and retry once with a simplified prompt.
Size notes
- Use
WxHformat (e.g.1024*1024,768*1024). - Prefer common sizes; unsupported sizes can return 400.
Anti-patterns
- Do not invent model names or aliases; use official model IDs only.
- Do not store large base64 blobs in DB rows; use object storage.
- Do not omit user-visible progress for long generations.
Workflow
1) Confirm user intent, region, identifiers, and whether the operation is read-only or mutating. 2) Run one minimal read-only query first to verify connectivity and permissions. 3) Execute the target operation with explicit parameters and bounded scope. 4) Verify results and save output/evidence files.
References
- See
references/api_reference.mdfor a more detailed DashScope SDK mapping and response parsing tips. - See
references/prompt-guide.mdfor prompt patterns and examples. - For edit workflows, use
skills/ai/image/aliyun-qwen-image-edit/.
- Source list:
references/sources.md
interface:
display_name: "Alibaba Cloud AI Image Qwen Image"
short_description: "Qwen image generation workflows"
default_prompt: "Use $aliyun-qwen-image to complete this ai/image task on Alibaba Cloud."
DashScope SDK Reference (Qwen Image)
Keep this reference minimal and update it only when the DashScope SDK behavior changes.
Install
python3 -m venv .venv
. .venv/bin/activate
python -m pip install dashscopeEnvironment
export DASHSCOPE_API_KEY=your_keyIf env vars are not set, you can also place dashscope_api_key under [default] in ~/.alibabacloud/credentials.
Suggested mapping
Use the normalized image.generate request and map fields into the SDK call. Note: For qwen-image-max, the DashScope SDK currently succeeds via ImageGeneration (messages-based) rather than ImageSynthesis. The exact parameter names for reference images can vary across SDK versions.
import os
from dashscope.aigc.image_generation import ImageGeneration
messages = [
{
"role": "user",
"content": [{"text": prompt}],
}
]
if reference_image:
# Some SDK versions accept {"image": <url|file|bytes>} in messages content.
messages[0]["content"].insert(0, {"image": reference_image})
response = ImageGeneration.call(
model="qwen-image-max",
messages=messages,
size=size,
api_key=os.getenv("DASHSCOPE_API_KEY"),
negative_prompt=negative_prompt,
style=style,
seed=seed,
)Response parsing
DashScope SDK response shapes can differ slightly by version. Extract the first result URL and normalize into:
image_urlwidthheightseed
Prefer this pattern:
content = response.output["choices"][0]["message"]["content"]
image_url = next((item.get("image") for item in content if isinstance(item, dict) and item.get("image")), None)
width = response.usage.get("width")
height = response.usage.get("height")
seed = seedNotes
negative_prompt,style, andseedmay be ignored by some deployments; treat them as best-effort.- If no image URL is returned, fail fast with a clear error and retry with a shorter prompt.
Prompt Guide (Qwen Image)
Five practical prompt patterns to improve image generation quality.
Core principle
Describe a scene, not just keywords.
Bad: cat, cute, window, sunlight
Good: a white cat napping on a sunny windowsill, soft afternoon light, shallow depth of field1) Photorealistic
Include camera and lighting details.
Example:
portrait photo, 85mm lens, f/1.8, golden hour rim light, natural skin texture, soft bokeh background2) Illustration / Sticker
Call out a clear style and line treatment.
Example:
flat vector sticker of a smiling coffee mug, pastel palette, thick black outline, clean white background3) Text-in-image
Be explicit about font, placement, and size.
Example:
birthday card with the text "HAPPY BIRTHDAY", bold sans-serif, centered, large type, pastel balloons background4) Product photo
Use studio lighting and a specific angle.
Example:
product photo of wireless earbuds on a white sweep, softbox lighting, 45 degree angle, minimal shadow, high detail5) Minimal design
Emphasize negative space and limited palette.
Example:
minimal abstract wallpaper, light blue gradient background, small geometric shape in bottom-right, lots of whitespaceEditing prompts (when using reference_image)
Add:
add a rainbow in the backgroundRemove:
remove the person in the backgroundChange:
change the hair color to blondeStyle transfer:
convert to watercolor style官方文档来源(用于后续更新) ============================
- (暂无外部文档链接)
#!/usr/bin/env python3
"""Generate an image using DashScope (qwen-image-max) from a normalized request.
Usage:
python scripts/generate_image.py --request '{"prompt":"a cat","size":"1024*1024"}'
python scripts/generate_image.py --file request.json --output output/ai-image-qwen-image/images/cat.png
"""
from __future__ import annotations
import argparse
import configparser
import json
import os
import sys
import urllib.request
from pathlib import Path
from typing import Any
def _find_repo_root(start: Path) -> Path | None:
for parent in [start] + list(start.parents):
if (parent / ".git").exists():
return parent
return None
def _load_dotenv(path: Path) -> None:
if not path.exists():
return
for line in path.read_text().splitlines():
line = line.strip()
if not line or line.startswith("#") or "=" not in line:
continue
key, value = line.split("=", 1)
key = key.strip()
value = value.strip().strip('"').strip("'")
if key and key not in os.environ:
os.environ[key] = value
def _load_env() -> None:
_load_dotenv(Path.cwd() / ".env")
repo_root = _find_repo_root(Path(__file__).resolve())
if repo_root:
_load_dotenv(repo_root / ".env")
def _load_dashscope_api_key_from_credentials() -> None:
if os.environ.get("DASHSCOPE_API_KEY"):
return
credentials_path = Path(os.path.expanduser("~/.alibabacloud/credentials"))
if not credentials_path.exists():
return
config = configparser.ConfigParser()
try:
config.read(credentials_path)
except configparser.Error:
return
profile = os.getenv("ALIBABA_CLOUD_PROFILE") or os.getenv("ALICLOUD_PROFILE") or "default"
if not config.has_section(profile):
return
key = config.get(profile, "dashscope_api_key", fallback="").strip()
if not key:
key = config.get(profile, "DASHSCOPE_API_KEY", fallback="").strip()
if key:
os.environ["DASHSCOPE_API_KEY"] = key
try:
from dashscope.aigc.image_generation import ImageGeneration
except ImportError:
print("Error: dashscope is not installed. Run: pip install dashscope", file=sys.stderr)
sys.exit(1)
MODEL_NAME = "qwen-image-max"
DEFAULT_SIZE = "1024*1024"
def load_request(args: argparse.Namespace) -> dict[str, Any]:
if args.request:
return json.loads(args.request)
if args.file:
with open(args.file, "r", encoding="utf-8") as f:
return json.load(f)
raise ValueError("Either --request or --file must be provided")
def resolve_reference_image(value: str) -> Any:
if value.startswith("http://") or value.startswith("https://"):
return value
path = Path(value)
if path.exists():
return path.read_bytes()
return value
def _get_field(obj: Any, key: str, default: Any = None) -> Any:
if obj is None:
return default
if isinstance(obj, dict):
return obj.get(key, default)
getter = getattr(obj, "get", None)
if callable(getter):
try:
return getter(key, default)
except TypeError:
value = getter(key)
return default if value is None else value
try:
return obj[key]
except Exception:
return getattr(obj, key, default)
def call_generate(req: dict[str, Any]) -> dict[str, Any]:
prompt = req.get("prompt")
if not prompt:
raise ValueError("prompt is required")
messages = [{"role": "user", "content": [{"text": prompt}]}]
reference_image = req.get("reference_image")
if reference_image:
messages[0]["content"].insert(0, {"image": resolve_reference_image(reference_image)})
response = ImageGeneration.call(
model=MODEL_NAME,
messages=messages,
size=req.get("size", DEFAULT_SIZE),
api_key=os.getenv("DASHSCOPE_API_KEY"),
negative_prompt=req.get("negative_prompt"),
style=req.get("style"),
seed=req.get("seed"),
)
output = _get_field(response, "output", response.output if hasattr(response, "output") else None)
choices = _get_field(output, "choices", [])
if not choices:
raise RuntimeError(f"No choices returned by DashScope: {response}")
message = _get_field(choices[0], "message", {})
content = _get_field(message, "content", [])
image_url = None
for item in content:
if isinstance(item, dict) and item.get("image"):
image_url = item["image"]
break
if not image_url:
raise RuntimeError("No image URL returned by DashScope")
usage = _get_field(response, "usage", response.usage if hasattr(response, "usage") else {})
return {
"image_url": image_url,
"width": _get_field(usage, "width"),
"height": _get_field(usage, "height"),
"seed": req.get("seed"),
}
def download_image(image_url: str, output_path: Path) -> None:
output_path.parent.mkdir(parents=True, exist_ok=True)
with urllib.request.urlopen(image_url) as response:
output_path.write_bytes(response.read())
def main() -> None:
parser = argparse.ArgumentParser(description="Generate image with qwen-image-max")
parser.add_argument("--request", help="Inline JSON request string")
parser.add_argument("--file", help="Path to JSON request file")
default_output_dir = Path(os.getenv("OUTPUT_DIR", "output")) / "ai-image-qwen-image" / "images"
parser.add_argument(
"--output",
default=str(default_output_dir / "output.png"),
help="Output image path",
)
parser.add_argument("--print-response", action="store_true", help="Print normalized response JSON")
args = parser.parse_args()
_load_env()
_load_dashscope_api_key_from_credentials()
if not os.environ.get("DASHSCOPE_API_KEY"):
print(
"Error: DASHSCOPE_API_KEY is not set. Configure it via env/.env or ~/.alibabacloud/credentials.",
file=sys.stderr,
)
print("Example .env:\n DASHSCOPE_API_KEY=your_key_here", file=sys.stderr)
print(
"Example credentials:\n [default]\n dashscope_api_key=your_key_here",
file=sys.stderr,
)
sys.exit(1)
req = load_request(args)
result = call_generate(req)
download_image(result["image_url"], Path(args.output))
if args.print_response:
print(json.dumps(result, ensure_ascii=True))
if __name__ == "__main__":
main()