The portrait style repainting model transforms portrait photos into various preset or custom artistic styles.
This document applies only to the China (Beijing) region. Use an API key from this region.
Model overview
Model name | Billing price | Throttling (shared by Alibaba Cloud account and RAM users) | Free quota(View) | |
QPS limit for task submission API | Number of concurrent tasks | |||
wanx-style-repaint-v1 | CNY 0.12 per image | 2 | 1 | 500 images |
Getting started
Prerequisites
Obtain an API key and configure it as an environment variable.
Sample code
This model provides only an HTTP API. Refer to the curl sample code.
curl
For a beginner's guide to HTTP calls, see Postman.
Because image generation is time-consuming, the API uses an asynchronous mode. The call process consists of two steps:
Step 1: Create a task to get the task ID
This API returns a unique task ID (task_id).
Sample request
Use a preset style
Set `style_index`. Do not set it to -1.
curl --location 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/image-generation/generation' \
--header 'X-DashScope-Async: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "wanx-style-repaint-v1",
"input": {
"image_url": "https://vigen-video.oss-cn-shanghai.aliyuncs.com/demo_image/image_demo_input.png",
"style_index": 3
}
}'
Use a custom style
Set `style_ref_url` (style reference image) and set `style_index` to -1.
curl --location 'https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/image-generation/generation' \
--header 'X-DashScope-Async: enable' \
--header "Authorization: Bearer $DASHSCOPE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"model": "wanx-style-repaint-v1",
"input": {
"image_url": "https://vigen-video.oss-cn-shanghai.aliyuncs.com/demo_image/input_example.png",
"style_ref_url": "https://vigen-video.oss-cn-shanghai.aliyuncs.com/demo_image/style_example.png",
"style_index": -1
}
}'
Sample response
The task_id is valid for queries for 24 hours.
{
"output": {
"task_status": "PENDING",
"task_id": "0385dc79-5ff8-4d82-bcb6-xxxxxx"
},
"request_id": "4909100c-7b5a-9f92-bfe5-xxxxxx"
}Step 2: Query the task result
Use the task_id to poll the task status until it is complete and you obtain the generated image URL.
Sample request
Replace {task_id} with the task_id value returned by the previous API call. The task_id is valid for queries for 24 hours.
curl -X GET https://{WorkspaceId}.cn-beijing.maas.aliyuncs.com/api/v1/tasks/{task_id} \
--header "Authorization: Bearer $DASHSCOPE_API_KEY"Sample response
The image URL is valid for 24 hours. Download the image promptly.
{
"request_id": "f7fee4f1-1f68-9f17-85df-xxxxx",
"output": {
"task_id": "316c7af0-e91f-476f-99bd-xxxxxx",
"task_status": "SUCCEEDED",
"submit_time": "2025-08-12 10:55:43.768",
"scheduled_time": "2025-08-12 10:55:43.799",
"end_time": "2025-08-12 10:55:48",
"error_message": "Success",
"start_time": "2025-08-12 10:55:43",
"style_index": 0,
"error_code": 0,
"results": [
{
"url": "http://oss.aliyuncs.com/xxx/abc.jpg"
}
]
},
"usage": {
"image_count": 1
}
}Python
To integrate this into an existing project, you must implement the HTTP call logic in your preferred language, such as Python, Java, or Node.js.
This topic provides only a Python example. It is not an official software development kit (SDK) but a reference implementation for HTTP calls.
Environment configuration
Python 3.8 or later is recommended.
Install the required dependency package.
pip install -U requestsSample request
import os
import requests
import time
from http import HTTPStatus
# Get the Alibaba Cloud Model Studio API key from an environment variable, or assign it directly in the code.
api_key = os.getenv("DASHSCOPE_API_KEY")
if not api_key:
raise ValueError("Set the DASHSCOPE_API_KEY environment variable.")
def submit_task():
"""Submit a style repainting task."""
url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/image-generation/generation"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
"X-DashScope-Async": "enable" # Asynchronous invocation
}
# --- Use a preset style ---
# style_index: 0=Retro Comic, 1=3D Fairy Tale, 2=Anime, 3=Fresh, 4=Future Tech...
body = {
"model": "wanx-style-repaint-v1",
"input": {
"image_url": "https://vigen-video.oss-cn-shanghai.aliyuncs.com/demo_image/image_demo_input.png",
"style_index": 3 # Example: Select the "Fresh" style
}
}
# --- Use a custom style ---
# body = {
# "model": "wanx-style-repaint-v1",
# "input": {
# "image_url": "https://vigen-video.oss-cn-shanghai.aliyuncs.com/demo_image/input_example.png",
# "style_ref_url": "https://vigen-video.oss-cn-shanghai.aliyuncs.com/demo_image/style_example.png",
# "style_index": -1
# }
# }
response = requests.post(url, headers=headers, json=body)
if response.status_code == HTTPStatus.OK:
task_id = response.json().get('output', {}).get('task_id')
print(f"Task submitted successfully. Task ID: {task_id}")
return task_id
else:
print(f"Task submission failed. Status code: {response.status_code}, Response: {response.text}")
return None
def query_task_result(task_id):
"""Poll for the result based on the task ID."""
if not task_id:
return
url = f"https://dashscope.aliyuncs.com/api/v1/tasks/{task_id}"
headers = {"Authorization": f"Bearer {api_key}"}
print("Querying task status...")
while True:
response = requests.get(url, headers=headers)
if response.status_code != HTTPStatus.OK:
print(f"Query failed. Status code: {response.status_code}, Response: {response.text}")
break
response_data = response.json()
task_status = response_data.get('output', {}).get('task_status')
if task_status == 'SUCCEEDED':
print("Task completed successfully!")
print(f"Successful task response data: {response_data}")
results = response_data.get('output', {}).get('results', [])
for i, result in enumerate(results):
print(f"Generated image_{i + 1} URL: {result.get('url')}")
break
elif task_status == 'FAILED':
print(f"Task failed. Error message: {response_data}")
break
else:
print(f"Task is processing. Current status: {task_status}...")
time.sleep(5) # Wait 5 seconds before the next query
if __name__ == '__main__':
task_id = submit_task()
if task_id:
query_task_result(task_id)Sample response
Task submitted successfully. Task ID: b6496481-4fdc-476b-b20f-xxxxxx
Querying task status...
Task is processing. Current status: RUNNING...
Task completed successfully!
Successful task response data: {'request_id': 'ec3a682b-4d67-96f2-937d-xxxxxx', 'output': {'task_id': 'b6496481-4fdc-476b-b20f-xxxxxx', 'task_status': 'SUCCEEDED', 'submit_time': '2025-08-12 17:52:56.439', 'scheduled_time': '2025-08-12 17:52:56.466', 'end_time': '2025-08-12 17:53:01', 'error_message': 'Success', 'start_time': '2025-08-12 17:52:56', 'style_index': 3, 'error_code': 0, 'results': [{'url': 'https://dashscope-result-wlcb.oss-cn-wulanchabu.aliyuncs.com/1d/e0/20250812/b1be3297/20250812175256936406_style3_w52l3kpz6i.jpg?Expires=xxxx'}]}, 'usage': {'image_count': 1}}
Generated image_1 URL: https://dashscope-result-wlcb.oss-cn-wulanchabu.aliyuncs.com/1d/e0/20250812/b1be3297/20250812175256936406_style3_w52l3kpz6i.jpg?Expires=xxxx
Input image limits
Portrait image
Image resolution: The resolution must be at least
256*256pixels and no more than5760*3240pixels. The aspect ratio of the longer side to the shorter side cannot exceed 2:1.Image quality: To ensure high-quality output, upload a clear photo of a face. The face should not be too small in the frame. Avoid exaggerated poses and expressions.
Image format: JPEG, PNG, JPG, BMP, WEBP.
Image size: No larger than 10 MB.
Image URL:
HTTP/HTTPS URLs accessible over the public network are supported. The URL cannot contain Chinese characters. Base64-encoded strings are also supported.
For local files, you can obtain a valid parameter value in one of two ways:
Obtain a URL: For more information, see Upload a file to obtain a temporary URL.
Generate a Base64-encoded string: For more information, see Pass an image as a Base64-encoded string.
Style reference image
Image resolution: The resolution must be at least
256*256pixels and no more than5760*3240pixels. For best results, the aspect ratio of the longer side to the shorter side should not exceed 2:1. Otherwise, generation may be affected or an error may occur.Image format: JPEG, PNG, JPG, BMP, WEBP.
Image size: No larger than 10 MB.
Image URL:
HTTP/HTTPS URLs accessible over the public network are supported. The URL cannot contain Chinese characters. Base64-encoded strings are also supported.
For local files, you can obtain a valid parameter value in one of two ways:
Obtain a URL: For more information, see Upload a file to obtain a temporary URL.
Generate a Base64-encoded string: For more information, see Pass an image as a Base64-encoded string.
Pass an image as a Base64-encoded string
You can convert a local image file to a Base64-formatted string and concatenate it in the following format: data:{MIME_type};base64,{base64_data}.
{MIME_type}: The media type of the image, which must correspond to the file format.
{base64_data}: The complete data string of the image file after Base64 encoding.
The mapping between image formats and Multipurpose Internet Mail Extensions (MIME) types is as follows:
Image format
MIME Type
JPEG
image/jpeg
JPG
image/jpeg
PNG
image/png
BMP
image/bmp
WEBP
image/webp
Example value:
"image_url": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABDg......".Note: The Base64 string is truncated for display purposes. In practice, you must pass the complete encoded string.
Sample code: Obtain the Base64-encoded string of an image.
import base64 import mimetypes # --- For Base64 encoding --- # Format is data:{MIME_type};base64,{base64_data} def encode_file(file_path): mime_type, _ = mimetypes.guess_type(file_path) if not mime_type or not mime_type.startswith("image/"): raise ValueError("Unsupported or unrecognized image format") with open(file_path, "rb") as image_file: encoded_string = base64.b64encode(image_file.read()).decode('utf-8') return f"data:{mime_type};base64,{encoded_string}" if __name__ == "__main__": print(encode_file("./image_demo_input.png"))
Billing and throttling
Billing rules
-
Billable item: You are billed for the number of successfully generated images on a pay-as-you-go basis.
-
Billing formula: Fee = Unit price × Number of images.
-
Consumption order: Free quotas are consumed first. After your free quota is used up, the pay-as-you-go billing method is used by default.
-
You can enable the "Free quota only" option to prevent charges after your free quota is exhausted. For more information, see Free quota for new users.
-
-
No charge for failures: Failed model calls or processing errors do not incur fees or consume free quotas.
Free quotas
For more information about how to claim, query, and use free quotas, see Free quota for new users.
Query usage
Approximately one hour after a model call is complete, you can go to the Monitoring page to view metrics such as usage, number of calls, and success rate.
Rate limiting
For rate limiting rules and FAQ, see Rate limits.
API reference
For the API input and response parameters, see Portrait style repainting.
FAQ
Q: How do I process local images?
A: This API supports public URLs and Base64 encoding. To use a local file, you can obtain a valid parameter value in one of two ways:
Obtain a URL: Upload the image to an object storage service, such as Alibaba Cloud OSS, or use the temporary storage provided by Alibaba Cloud Model Studio.
Generate a Base64-encoded string: For more information, see Pass an image as a Base64-encoded string.
Q: How can I optimize the image generation quality?
A: The quality of the output depends on the quality of the input. You can try the following methods to optimize the results:
Improve portrait photo quality: Use a high-definition, well-lit, frontal photo with clear, unobstructed facial features.
Select a style reference image: Choose an image with a distinct style that matches the subject of the portrait.
Q: Can I use preset and custom styles at the same time?
A: No, you cannot. These modes are mutually exclusive. You must choose one of the two modes:
Use a preset style: Set style_index to a value other than -1. For a list of enumeration values, see Portrait style repainting.
Use a custom style: Provide a style reference image URL (style_ref_url) and set style_index to -1.
If you pass both and do not set style_index to -1, the system may default to the preset style, causing the custom style to not take effect.
Q: Is the size of the output image the same as the input image?
A: No. The output image maintains the aspect ratio of the input image. However, its shorter side is fixed at 1536 pixels, and the longer side is scaled proportionally.