QwenCloudBRASIL
Tradução de apoio para consulta. Código e identificadores técnicos preservados. Consultar referência original ↗

Wan 2.5 — Edite uma imagem

Assíncrono Wan2.5 edição de imagem

Obtenha uma chave de API e defini-lo como uma variável de ambiente. Se estiver usando o SDK, instale-o.

Edite imagens usando instruções de texto, preservando a consistência do assunto. Suporta fusão de múltiplas imagens com até três imagens de referência.

OpenAPI

openapi: 3.1.0
info:
  title: Wan2.5 General Image Editing API
  description: Wan2.5 general image editing API. Edits images using text prompts, preserving subject consistency. Supports single-image editing and multi-image fusion with up to three reference images.
  version: 1.0.0
servers:
  - url: https://maas.qwencloudapi.com/api/v1
    description: Singapore
security:
  - BearerAuth: []
paths:
  /services/aigc/image2image/image-synthesis:
    post:
      operationId: createWan25ImageEdit
      summary: Create image editing task
      description: Create an image editing task using Wan2.5. Requires DashScope Python SDK 1.25.2 or later.
      parameters:
        - name: X-DashScope-Async
          in: header
          required: true
          description: Enables asynchronous processing. Must be `enable`. HTTP requests only support asynchronous processing. Omitting this header returns a "current user api does not support synchronous calls" error.
          schema:
            type: string
            enum:
              - enable
            default: enable
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Wan25ImageEditRequest"
      responses:
        "200":
          description: Task submitted successfully. Use `task_id` to poll for results.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AsyncTaskSubmitResponse"
              example:
                output:
                  task_status: PENDING
                  task_id: 0385dc79-5ff8-4d82-bcb6-xxxxxx
                request_id: 4909100c-7b5a-9f92-bfe5-xxxxxx
        "400":
          description: Invalid request parameters.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DashScopeErrorResponse"
              example:
                code: InvalidParameter
                message: Invalid request parameters.
                request_id: 7438d53d-6eb8-4596-8835-xxxxxx
        "401":
          description: Authentication failed. Invalid API key.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DashScopeErrorResponse"
              example:
                code: InvalidApiKey
                message: No API-key provided.
                request_id: 7438d53d-6eb8-4596-8835-xxxxxx
      x-codeSamples:
        - lang: curl
          label: Single-image editing
          source: |-
            curl --location 'https://maas.qwencloudapi.com/api/v1/services/aigc/image2image/image-synthesis' \
              -H 'X-DashScope-Async: enable' \
              -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
              -H 'Content-Type: application/json' \
              -d '{
              "model": "wan2.5-i2i-preview",
              "input": {
                "prompt": "Change the floral dress to a vintage-style lace long dress with exquisite embroidery details on the collar and cuffs.",
                "images": [
                  "https://img.alicdn.com/imgextra/i2/O1CN01vHOj4h28jOxUJPwY8_!!6000000007968-49-tps-1344-896.webp"
                ]
              },
              "parameters": {
                "prompt_extend": true,
                "n": 1
              }
            }'
        - lang: curl
          label: Multi-image fusion
          source: |-
            curl --location 'https://maas.qwencloudapi.com/api/v1/services/aigc/image2image/image-synthesis' \
              -H 'X-DashScope-Async: enable' \
              -H "Authorization: Bearer $DASHSCOPE_API_KEY" \
              -H 'Content-Type: application/json' \
              -d '{
              "model": "wan2.5-i2i-preview",
              "input": {
                "prompt": "Place the alarm clock from Image 1 next to the vase on the dining table in Image 2.",
                "images": [
                  "https://img.alicdn.com/imgextra/i3/O1CN0157XGE51l6iL9441yX_!!6000000004770-49-tps-1104-1472.webp",
                  "https://img.alicdn.com/imgextra/i3/O1CN01SfG4J41UYn9WNt4X1_!!6000000002530-49-tps-1696-960.webp"
                ]
              },
              "parameters": {
                "n": 1
              }
            }'
        - lang: python
          label: Python SDK - Synchronous
          source: |-
            import base64
            import mimetypes
            from http import HTTPStatus
            from urllib.parse import urlparse, unquote
            from pathlib import PurePosixPath

            import dashscope
            import requests
            from dashscope import ImageSynthesis
            import os

            dashscope.base_http_api_url = 'https://maas.qwencloudapi.com/api/v1'

            api_key = os.getenv("DASHSCOPE_API_KEY")

            # --- Image input: Use Base64 encoding ---
            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}"

            """
            Image input methods:
            1. Use a public URL - Suitable for publicly accessible images.
            2. Use a local file - Suitable for local development and testing.
            3. Use Base64 encoding - Suitable for private images or scenarios that require encrypted transmission.
            """

            # [Method 1] Use a public image URL
            image_url_1 = "https://img.alicdn.com/imgextra/i3/O1CN0157XGE51l6iL9441yX_!!6000000004770-49-tps-1104-1472.webp"
            image_url_2 = "https://img.alicdn.com/imgextra/i3/O1CN01SfG4J41UYn9WNt4X1_!!6000000002530-49-tps-1696-960.webp"

            # [Method 2] Use a local file (supports absolute and relative paths)
            # image_url_1 = "file://" + "/path/to/your/image_1.png"     # Linux/macOS
            # image_url_2 = "file://" + "C:/path/to/your/image_2.png"  # Windows

            # [Method 3] Use a Base64-encoded image
            # image_url_1 = encode_file("./image_1.png")
            # image_url_2 = encode_file("./image_2.png")

            print('----sync call, please wait a moment----')
            rsp = ImageSynthesis.call(api_key=api_key,
                                      model="wan2.5-i2i-preview",
                                      prompt="Place the alarm clock from Image 1 next to the vase on the dining table in Image 2.",
                                      images=[image_url_1, image_url_2],
                                      negative_prompt="",
                                      n=1,
                                      # size="1280*1280",
                                      prompt_extend=True,
                                      watermark=False,
                                      seed=12345)
            print('response: %s' % rsp)
            if rsp.status_code == HTTPStatus.OK:
              for result in rsp.output.results:
                file_name = PurePosixPath(unquote(urlparse(result.url).path)).parts[-1]
                with open('./%s' % file_name, 'wb+') as f:
                  f.write(requests.get(result.url).content)
            else:
              print('sync_call Failed, status_code: %s, code: %s, message: %s' %
                      (rsp.status_code, rsp.code, rsp.message))
        - lang: python
          label: Python SDK - Asynchronous
          source: |-
            import os
            from http import HTTPStatus
            from urllib.parse import urlparse, unquote
            from pathlib import PurePosixPath
            import dashscope
            import requests
            from dashscope import ImageSynthesis

            dashscope.base_http_api_url = 'https://maas.qwencloudapi.com/api/v1'

            api_key = os.getenv("DASHSCOPE_API_KEY")

            image_url_1 = "https://img.alicdn.com/imgextra/i3/O1CN0157XGE51l6iL9441yX_!!6000000004770-49-tps-1104-1472.webp"
            image_url_2 = "https://img.alicdn.com/imgextra/i3/O1CN01SfG4J41UYn9WNt4X1_!!6000000002530-49-tps-1696-960.webp"

            def async_call():
              print('----create task----')
              task_info = create_async_task()
              print('----wait task----')
              wait_async_task(task_info)

            def create_async_task():
              rsp = ImageSynthesis.async_call(api_key=api_key,
                              model="wan2.5-i2i-preview",
                              prompt="Place the alarm clock from Image 1 next to the vase on the dining table in Image 2.",
                              images=[image_url_1, image_url_2],
                              negative_prompt="",
                              n=1,
                              # size="1280*1280",
                              prompt_extend=True,
                              watermark=False,
                              seed=12345)
              print(rsp)
              if rsp.status_code == HTTPStatus.OK:
                print(rsp.output)
              else:
                print('Failed, status_code: %s, code: %s, message: %s' %
                          (rsp.status_code, rsp.code, rsp.message))
              return rsp

            def wait_async_task(task):
              rsp = ImageSynthesis.wait(task=task, api_key=api_key)
              print(rsp)
              if rsp.status_code == HTTPStatus.OK:
                print(rsp.output)
                for result in rsp.output.results:
                  file_name = PurePosixPath(unquote(urlparse(result.url).path)).parts[-1]
                  with open('./%s' % file_name, 'wb+') as f:
                    f.write(requests.get(result.url).content)
              else:
                print('Failed, status_code: %s, code: %s, message: %s' %
                          (rsp.status_code, rsp.code, rsp.message))

            def fetch_task_status(task):
              status = ImageSynthesis.fetch(task=task, api_key=api_key)
              print(status)
              if status.status_code == HTTPStatus.OK:
                print(status.output.task_status)
              else:
                print('Failed, status_code: %s, code: %s, message: %s' %
                          (status.status_code, status.code, status.message))

            def cancel_task(task):
              rsp = ImageSynthesis.cancel(task=task, api_key=api_key)
              print(rsp)
              if rsp.status_code == HTTPStatus.OK:
                print(rsp.output.task_status)
              else:
                print('Failed, status_code: %s, code: %s, message: %s' %
                          (rsp.status_code, rsp.code, rsp.message))

            if __name__ == '__main__':
              async_call()
        - lang: java
          label: Java SDK - Synchronous
          source: |-
            // Copyright (c) Alibaba, Inc. and its affiliates.

            import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
            import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
            import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
            import com.alibaba.dashscope.exception.ApiException;
            import com.alibaba.dashscope.exception.NoApiKeyException;
            import com.alibaba.dashscope.utils.Constants;
            import com.alibaba.dashscope.utils.JsonUtils;

            import java.io.IOException;
            import java.nio.file.Files;
            import java.nio.file.Path;
            import java.nio.file.Paths;
            import java.util.*;

            // SDK version >= 2.22.2 required
            public class Image2Image {

              static {
                Constants.baseHttpApiUrl = "https://maas.qwencloudapi.com/api/v1";
              }

              static String apiKey = System.getenv("DASHSCOPE_API_KEY");

              /**
                 * Image input methods:
                 * 1. Use a public URL - Suitable for publicly accessible images.
                 * 2. Use a local file - Suitable for local development and testing.
                 * 3. Use Base64 encoding - Suitable for private images or scenarios that require encrypted transmission.
                 */

              //[Method 1] Public URL
              static String imageUrl_1 = "https://img.alicdn.com/imgextra/i3/O1CN0157XGE51l6iL9441yX_!!6000000004770-49-tps-1104-1472.webp";
              static String imageUrl_2 = "https://img.alicdn.com/imgextra/i3/O1CN01SfG4J41UYn9WNt4X1_!!6000000002530-49-tps-1696-960.webp";

              //[Method 2] Local file path (file://+absolute path or file:///+absolute path)
              // static String imageUrl_1 = "file://" + "/your/path/to/image_1.png";
              // static String imageUrl_2 = "file:///" + "C:/your/path/to/image_2.png";

              //[Method 3] Base64 encoding
              // static String imageUrl_1 = encodeFile("/your/path/to/image_1.png");
              // static String imageUrl_2 = encodeFile("/your/path/to/image_2.png");

              static List<String> imageUrls = new ArrayList<>();
              static {
                imageUrls.add(imageUrl_1);
                imageUrls.add(imageUrl_2);
              }

              public static void syncCall() {
                Map<String, Object> parameters = new HashMap<>();
                parameters.put("prompt_extend", true);
                parameters.put("watermark", false);
                parameters.put("seed", 12345);

                ImageSynthesisParam param =
                    ImageSynthesisParam.builder()
                        .apiKey(apiKey)
                        .model("wan2.5-i2i-preview")
                        .prompt("Place the alarm clock from Image 1 next to the vase on the dining table in Image 2.")
                        .images(imageUrls)
                        .n(1)
                        //.size("1280*1280")
                        .negativePrompt("")
                        .parameters(parameters)
                        .build();

                ImageSynthesis imageSynthesis = new ImageSynthesis();
                ImageSynthesisResult result = null;
                try {
                  System.out.println("---sync call, please wait a moment----");
                  result = imageSynthesis.call(param);
                } catch (ApiException | NoApiKeyException e){
                  throw new RuntimeException(e.getMessage());
                }
                System.out.println(JsonUtils.toJson(result));
              }

              /**
                 * Encodes a file into a Base64 string.
                 * @param filePath The file path.
                 * @return A Base64 string in the format: data:{MIME_type};base64,{base64_data}
                 */
              public static String encodeFile(String filePath) {
                Path path = Paths.get(filePath);
                if (!Files.exists(path)) {
                  throw new IllegalArgumentException("File does not exist: " + filePath);
                }
                String mimeType = null;
                try {
                  mimeType = Files.probeContentType(path);
                } catch (IOException e) {
                  throw new IllegalArgumentException("Cannot detect file type: " + filePath);
                }
                if (mimeType == null || !mimeType.startsWith("image/")) {
                  throw new IllegalArgumentException("Unsupported or unrecognized image format");
                }
                byte[] fileBytes = null;
                try{
                  fileBytes = Files.readAllBytes(path);
                } catch (IOException e) {
                  throw new IllegalArgumentException("Cannot read file content: " + filePath);
                }
                String encodedString = Base64.getEncoder().encodeToString(fileBytes);
                return "data:" + mimeType + ";base64," + encodedString;
              }

              public static void main(String[] args) {
                syncCall();
              }
            }
        - lang: java
          label: Java SDK - Asynchronous
          source: |-
            // Copyright (c) Alibaba, Inc. and its affiliates.

            import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesis;
            import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisListResult;
            import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisParam;
            import com.alibaba.dashscope.aigc.imagesynthesis.ImageSynthesisResult;
            import com.alibaba.dashscope.exception.ApiException;
            import com.alibaba.dashscope.exception.NoApiKeyException;
            import com.alibaba.dashscope.task.AsyncTaskListParam;
            import com.alibaba.dashscope.utils.Constants;
            import com.alibaba.dashscope.utils.JsonUtils;

            import java.util.ArrayList;
            import java.util.HashMap;
            import java.util.List;
            import java.util.Map;

            // SDK version >= 2.22.2 required
            public class Image2Image {

              static {
                Constants.baseHttpApiUrl = "https://maas.qwencloudapi.com/api/v1";
              }

              static String apiKey = System.getenv("DASHSCOPE_API_KEY");

              static String imageUrl_1 = "https://img.alicdn.com/imgextra/i3/O1CN0157XGE51l6iL9441yX_!!6000000004770-49-tps-1104-1472.webp";
              static String imageUrl_2 = "https://img.alicdn.com/imgextra/i3/O1CN01SfG4J41UYn9WNt4X1_!!6000000002530-49-tps-1696-960.webp";

              static List<String> imageUrls = new ArrayList<>();
              static {
                imageUrls.add(imageUrl_1);
                imageUrls.add(imageUrl_2);
              }

              public static void asyncCall() {
                Map<String, Object> parameters = new HashMap<>();
                parameters.put("prompt_extend", true);
                parameters.put("watermark", false);
                parameters.put("seed", 12345);

                ImageSynthesisParam param =
                    ImageSynthesisParam.builder()
                        .apiKey(apiKey)
                        .model("wan2.5-i2i-preview")
                        .prompt("Place the alarm clock from Image 1 next to the vase on the dining table in Image 2.")
                        .images(imageUrls)
                        .n(1)
                        //.size("1280*1280")
                        .negativePrompt("")
                        .parameters(parameters)
                        .build();
                ImageSynthesis imageSynthesis = new ImageSynthesis();
                ImageSynthesisResult result = null;
                try {
                  System.out.println("---async call, please wait a moment----");
                  result = imageSynthesis.asyncCall(param);
                } catch (ApiException | NoApiKeyException e){
                  throw new RuntimeException(e.getMessage());
                }

                System.out.println(JsonUtils.toJson(result));

                String taskId = result.getOutput().getTaskId();
                System.out.println("taskId=" + taskId);

                try {
                  result = imageSynthesis.wait(taskId, apiKey);
                } catch (ApiException | NoApiKeyException e){
                  throw new RuntimeException(e.getMessage());
                }
                System.out.println(JsonUtils.toJson(result));
                System.out.println(JsonUtils.toJson(result.getOutput()));
              }

              public static void listTask() throws ApiException, NoApiKeyException {
                ImageSynthesis is = new ImageSynthesis();
                AsyncTaskListParam param = AsyncTaskListParam.builder().build();
                param.setApiKey(apiKey);
                ImageSynthesisListResult result = is.list(param);
                System.out.println(result);
              }

              public void fetchTask(String taskId) throws ApiException, NoApiKeyException {
                ImageSynthesis is = new ImageSynthesis();
                ImageSynthesisResult result = is.fetch(taskId, apiKey);
                System.out.println(result.getOutput());
                System.out.println(result.getUsage());
              }

              public static void main(String[] args) {
                asyncCall();
              }
            }
components:
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: DashScope API Key. Create one in the [QwenCloud console](https://home.qwencloud.com/api-keys).
  schemas:
    Wan25ImageEditRequest:
      type: object
      required:
        - model
        - input
      properties:
        model:
          type: string
          description: Model name.
          enum:
            - wan2.5-i2i-preview
          example: wan2.5-i2i-preview
        input:
          $ref: "#/components/schemas/Wan25ImageEditInput"
        parameters:
          $ref: "#/components/schemas/Wan25ImageEditParameters"
    Wan25ImageEditInput:
      type: object
      required:
        - prompt
        - images
      description: Input data for image editing.
      properties:
        prompt:
          type: string
          description: "A positive prompt describes the elements and visual characteristics that you want the generated image to include. Accepts Chinese and English. Maximum: 2,000 characters; longer content is truncated."
          example: Change the floral dress to a vintage-style lace long dress with exquisite embroidery details on the collar and cuffs.
        images:
          type: array
          description: |-
            An array of URLs pointing to the input images. Maximum: 3 images per request. For multiple images, array order defines the sequence (Image 1, Image 2, etc.).

            **Image limits:**
            - Supported formats: JPEG, JPG, PNG, BMP, and WEBP. PNG alpha channels are ignored.
            - Resolution: Width and height must each be between 384 and 5,000 pixels.
            - Maximum file size: 10 MB.

            **Supported input formats:**
            - **Public URL**: Both HTTP and HTTPS are supported.
            - **Base64-encoded string**: Format: `data:{MIME_type};base64,{base64_data}`.
          items:
            type: string
          minItems: 1
          maxItems: 3
          example:
            - https://img.alicdn.com/imgextra/i2/O1CN01vHOj4h28jOxUJPwY8_!!6000000007968-49-tps-1344-896.webp
        negative_prompt:
          type: string
          description: "The negative prompt. Elements to exclude from the generated image. Accepts Chinese and English. Maximum: 500 characters; longer content is truncated."
          example: low resolution, error, worst quality, low quality, disfigured, extra fingers, bad proportions
    Wan25ImageEditParameters:
      type: object
      description: Controls output resolution, prompt rewriting, watermarks, and other processing options.
      properties:
        size:
          type: string
          description: |-
            Output resolution in `width*height` format. Default: `1280*1280`. Total pixels must fall between 589,824 (`768*768`) and 1,638,400 (`1280*1280`). Aspect ratio must be between 1:4 and 4:1.

            Recommended resolutions:
            - `1280*1280` (1:1)
            - `1024*1024` (1:1)
            - `800*1200` (2:3)
            - `1200*800` (3:2)
            - `960*1280` (3:4)
            - `1280*960` (4:3)
            - `720*1280` (9:16)
            - `1280*720` (16:9)
            - `1344*576` (21:9)

            If not specified, the system outputs an image with `1280*1280` total pixels and preserves an aspect ratio similar to the input:
            - Single-image input: The aspect ratio matches the input image.
            - Multi-image input: The aspect ratio matches the last input image.
          default: 1280*1280
          example: 1280*1280
        n:
          type: integer
          description: "The number of images to generate. Valid values: 1 to 4. Default: 4. The `n` parameter directly impacts billing -- higher values mean higher costs. To control costs, it is recommended to explicitly set it to 1 for testing."
          default: 4
          minimum: 1
          maximum: 4
          example: 1
        watermark:
          type: boolean
          description: Whether to add a watermark in the bottom-right corner of the image that displays the fixed text "AI-generated".
          default: false
          example: false
        prompt_extend:
          type: boolean
          description: Enables smart prompt rewriting. When enabled, the Large Language Model enhances your prompt for better results, at the cost of longer processing time.
          default: true
          example: true
        seed:
          type: integer
          description: "The random number seed. Value range: [0, 2147483647]. If not specified, the algorithm automatically generates a random number as the seed. If specified, the algorithm generates a separate seed value for each of the `n` images (seed, seed+1, seed+2, ...). To reproduce specific results, use a fixed seed value. Note: Due to inherent randomness, identical seeds may not produce exactly identical results."
          minimum: 0
          maximum: 2147483647
    AsyncTaskSubmitResponse:
      type: object
      properties:
        output:
          type: object
          properties:
            task_id:
              type: string
              description: The ID of the task. Can be used to query the task for up to 24 hours.
            task_status:
              type: string
              description: The status of the task.
              enum:
                - PENDING
                - RUNNING
                - SUCCEEDED
                - FAILED
                - CANCELED
                - UNKNOWN
        request_id:
          type: string
          description: Unique identifier for the request. Use for tracing and troubleshooting issues.
    ImageEditTaskStatusResponse:
      type: object
      properties:
        request_id:
          type: string
          description: Unique identifier for the request.
        output:
          type: object
          properties:
            task_id:
              type: string
              description: The ID of the task. Can be used to query the task for up to 24 hours.
            task_status:
              type: string
              description: The status of the task.
              enum:
                - PENDING
                - RUNNING
                - SUCCEEDED
                - FAILED
                - CANCELED
                - UNKNOWN
            submit_time:
              type: string
              description: "The time when the task was submitted. Time is in UTC+8. Format: `YYYY-MM-DD HH:mm:ss.SSS`."
            scheduled_time:
              type: string
              description: "The time when the task started running. Time is in UTC+8. Format: `YYYY-MM-DD HH:mm:ss.SSS`."
            end_time:
              type: string
              description: "The time when the task was completed. Time is in UTC+8. Format: `YYYY-MM-DD HH:mm:ss.SSS`."
            results:
              type: array
              description: An array of generation results. Each entry contains the image URL, prompt, or error details for failed generations.
              items:
                type: object
                properties:
                  orig_prompt:
                    type: string
                    description: The original input prompt.
                  actual_prompt:
                    type: string
                    description: The actual optimized prompt used when prompt rewriting is enabled. Not returned when this feature is disabled.
                  url:
                    type: string
                    description: The URL of the generated image. Valid for 24 hours.
                  code:
                    type: string
                    description: The error code for a failed image generation. Returned only for partial failures.
                  message:
                    type: string
                    description: The error message for a failed image generation. Returned only for partial failures.
            task_metrics:
              type: object
              description: Statistics about the task results.
              properties:
                TOTAL:
                  type: integer
                  description: Total number of tasks.
                SUCCEEDED:
                  type: integer
                  description: Number of successful tasks.
                FAILED:
                  type: integer
                  description: Number of failed tasks.
            code:
              type: string
              description: The error code. Returned only when the task fails.
            message:
              type: string
              description: Detailed error message. Returned only when the task fails.
        usage:
          type: object
          description: Output statistics. Only successful results are counted.
          properties:
            image_count:
              type: integer
              description: "Number of images successfully generated. Billing formula: Fee = (Number of images) x (Unit price)."
    DashScopeErrorResponse:
      type: object
      properties:
        code:
          type: string
          description: Error code identifying the type of error.
        message:
          type: string
          description: Detailed error message.
        request_id:
          type: string
          description: Unique request identifier for troubleshooting.