Clothing Recoloring

Description

Recolor clothing in an image using a specified color. Provide the original image and a clothing segmentation mask. Set the target color with color_str, select the clothing category with cloth_category, and use inpaint to enable or disable edge refinement.

Version

1.0

Image Requirements

  • Supported formats: JPG and PNG.
  • The examples follow the source document's input order: the original image first, followed by the clothing segmentation mask.
  • For image URLs, explicitly set media_data_type to url. Do not Base64-encode URLs.

Request URL

Task submission endpoint:

https://openapi.meitu.com/api/v1/sdk/sync/push
Task name (`task`): `/v1/change_cloth_color/495824`
Task type (`task_type`): `formula`

HTTP Method

POST

Content-Type: application/json

Authentication

Use an AK/SK pair with access to this capability and sign requests with the signing SDK. See API Request Signing.

Request Parameters

RequiredParameterTypeDescription
YestaskstringFixed value: /v1/change_cloth_color/495824.
Yestask_typestringFixed value: formula.
Yesinit_imagesarrayInput images. The examples provide the original image first, then the clothing segmentation mask.
YesparamsstringA JSON-serialized string containing the algorithm parameters described below.
Nosync_timeoutintegerSynchronous waiting period in seconds. Default: 30.

init_images Element

RequiredParameterTypeDescription
YesurlstringImage URL or Base64-encoded data, matching profile.media_profiles.media_data_type.
YesprofileobjectImage properties.

profile

RequiredParameterTypeDescription
YesversionstringFixed value: v1.
Yesmedia_profilesobjectImage data type.
Nomedia_extraobjectAdditional image information. Omit when not needed.

media_profiles

RequiredParameterTypeDescription
Nomedia_data_typestringurl: image URL; jpg: Base64-encoded image data. The original algorithm defaults to jpg; explicitly specify url for URL inputs.

params

params must be a string. Serialize the following object, assign the resulting string to params, and then serialize the entire request:

{
  "parameter": {
    "rsp_media_type": "jpg",
    "color_str": "#FFC0CB",
    "cloth_category": "None",
    "inpaint": 0
  }
}
RequiredParameterTypeDescription
YesparameterobjectClothing recoloring parameters.
NoextraobjectAdditional processing information in the algorithm protocol. Omit when not needed.

parameter

RequiredParameterTypeDescription
Norsp_media_typestringjpg: return result images as Base64-encoded data. The request examples use jpg.
Yescolor_strstringTarget color as a hexadecimal color code, such as #FFC0CB.
Yescloth_categorystringClothing category; see the values below. The source specifies None as the default and also marks the field as required. Set it explicitly.
YesinpaintintegerEdge refinement: 0 disables it; 1 enables it. The source specifies 0 as the default and also marks the field as required. Set it explicitly.

cloth_category values:

ValueDescription
NoneDefault in the source document; its specific processing behavior is not documented.
dressDress.
upUpper-body clothing.
downLower-body clothing, such as trousers and skirts.
coatOuterwear.
up-downRecolor upper- and lower-body clothing together.
jumpsuitJumpsuit.

The source parameter table documents only rsp_media_type = jpg, while its success example uses url. This discrepancy is retained here; the response example does not establish that this task accepts url as a request value.

Request Example

Replace the image URLs with accessible URLs for your original image and clothing segmentation mask.

{
  "task": "/v1/change_cloth_color/495824",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://example.com/input.jpg",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    },
    {
      "url": "https://example.com/cloth-mask.png",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"parameter\":{\"rsp_media_type\":\"jpg\",\"color_str\":\"#FFC0CB\",\"cloth_category\":\"None\",\"inpaint\":0}}",
  "sync_timeout": 30
}

Response Fields

See Task Query for gateway task states and querying. Common gateway fields are listed below; the exact result nesting for this task has not been verified against a response sample.

FieldTypeDescription
codeintegerGateway business status code. 0 does not mean the algorithm task has completed; also check the task status.
messagestringGateway response message.
dataobjectTask information.
data.task_idstringGateway task ID used to query results.
data.statusintegerTask status; see below.
data.resultobjectTask result. The internal field nesting for this task remains unconfirmed.
data.statusDescription
-1Task not found.
0Task created.
1Running.
2Failed.
9Synchronous wait timed out. Continue querying; this does not indicate task failure.
10Succeeded.

Algorithm Result Fields

These fields come from the original direct algorithm endpoint. They are not documented here as root-level gateway response fields.

FieldTypeDescription
parameterobjectOutput image type and version information.
parameter.rsp_media_typestringOutput data type. The source field description specifies jpg, while its success example uses url.
parameter.versionstringAlgorithm version shown in the source success example, such as 1.0.0.
media_info_listarrayThe source success example returns the recolored image first, followed by the clothing segmentation mask.
media_info_list[].media_datastringBase64 data or an image URL, depending on media_data_type.
media_info_list[].media_profilesobjectOutput image properties.
media_info_list[].media_profiles.media_data_typestringjpg indicates Base64 data; url indicates an image URL.

Algorithm Error Fields

FieldTypeDescription
ErrorCodeintegerAlgorithm error code.
ErrorMsgstringAlgorithm error message.
Datastring / nullAdditional information. The source error example uses null.

Response Examples

The following examples are from the original direct endpoint. Only JSON syntax and illustrative URLs have been corrected or replaced. They are not live responses from this task or complete gateway response examples.

Algorithm Success Example

HTTP status in the source: 200.

{
  "parameter": {
    "rsp_media_type": "url",
    "version": "1.0.0"
  },
  "media_info_list": [
    {
      "media_data": "https://example.com/recolored.jpg",
      "media_profiles": {
        "media_data_type": "url"
      }
    },
    {
      "media_data": "https://example.com/cloth-mask.png",
      "media_profiles": {
        "media_data_type": "url"
      }
    }
  ]
}

When to Query

If the gateway returns data.status = 9, use data.task_id with Task Query to retrieve the result. Do not treat a waiting timeout as a failed task and submit it again.

Algorithm Error Example

HTTP status in the source: 400.

{
  "ErrorCode": 20003,
  "ErrorMsg": "detect no face",
  "Data": null
}

Common Error Codes

See API Error Codes.

SDK Examples

Each example embeds the complete request body and requires no separate JSON file. Replace the AK, SK, original image URL, and clothing segmentation mask URL. Set up the signing SDK using the documentation for your language.

The examples submit once and print the response. If the task has not completed, retrieve its result using Task Query.

Python

Python Signing SDK

import json

import requests
from sign_sdk import sign

def main():
    key = "YOUR_ACCESS_KEY"
    secret = "YOUR_SECRET_KEY"
    url = "https://openapi.meitu.com/api/v1/sdk/sync/push"
    params = {
        "parameter": {
            "rsp_media_type": "jpg",
            "color_str": "#FFC0CB",
            "cloth_category": "None",
            "inpaint": 0
        }
    }
    payload = {
        "task": "/v1/change_cloth_color/495824",
        "task_type": "formula",
        "init_images": [
            {
                "url": "https://example.com/input.jpg",
                "profile": {
                    "media_profiles": {
                        "media_data_type": "url"
                    },
                    "version": "v1"
                }
            },
            {
                "url": "https://example.com/cloth-mask.png",
                "profile": {
                    "media_profiles": {
                        "media_data_type": "url"
                    },
                    "version": "v1"
                }
            }
        ],
        "params": json.dumps(params, ensure_ascii=True),
        "sync_timeout": 30
    }
    body = json.dumps(payload, ensure_ascii=True)
    headers = {
        "Content-Type": "application/json",
        sign.HeaderHost: "openapi.meitu.com",
    }
    signer = sign.Signer(key, secret)
    signed_request = signer.sign(url, "POST", headers, body)
    with requests.Session() as session:
        response = session.send(
            signed_request, timeout=(10, 60), verify=True, allow_redirects=False
        )
        print("Status:", response.status_code)
        print("Response:", response.text)

if __name__ == "__main__":
    main()

Go

Go Signing SDK

package main

import (
    "fmt"
    "io"
    "net/http"
    "time"

    "github.com/mtlab/api/signer"
)

func main() {
    url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
    body := `{
  "task": "/v1/change_cloth_color/495824",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://example.com/input.jpg",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    },
    {
      "url": "https://example.com/cloth-mask.png",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"parameter\":{\"rsp_media_type\":\"jpg\",\"color_str\":\"#FFC0CB\",\"cloth_category\":\"None\",\"inpaint\":0}}",
  "sync_timeout": 30
}`
    headers := make(http.Header)
    headers.Set("Content-Type", "application/json")
    headers.Set(signer.HeaderHost, "openapi.meitu.com")
    signObj := signer.NewSigner("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY")
    req, err := signObj.Sign(url, http.MethodPost, headers, body)
    if err != nil {
        fmt.Println("Sign request failed:", err)
        return
    }
    client := &http.Client{
        Timeout: 60 * time.Second,
        CheckRedirect: func(req *http.Request, via []*http.Request) error {
            return http.ErrUseLastResponse
        },
    }
    resp, err := client.Do(req)
    if err != nil {
        fmt.Println("Send request failed:", err)
        return
    }
    defer resp.Body.Close()
    responseBody, err := io.ReadAll(resp.Body)
    if err != nil {
        fmt.Println("Read response failed:", err)
        return
    }
    fmt.Println("Status:", resp.StatusCode)
    fmt.Println("Response:", string(responseBody))
}

PHP

PHP Signing SDK

<?php
require_once __DIR__ . '/signer.php';

$params = json_encode([
    'parameter' => [
        'rsp_media_type' => 'jpg',
        'color_str' => '#FFC0CB',
        'cloth_category' => 'None',
        'inpaint' => 0,
    ],
]);
$body = json_encode([
    'task' => '/v1/change_cloth_color/495824',
    'task_type' => 'formula',
    'init_images' => [
        [
            'url' => 'https://example.com/input.jpg',
            'profile' => [
                'media_profiles' => ['media_data_type' => 'url'],
                'version' => 'v1',
            ],
        ],
        [
            'url' => 'https://example.com/cloth-mask.png',
            'profile' => [
                'media_profiles' => ['media_data_type' => 'url'],
                'version' => 'v1',
            ],
        ],
    ],
    'params' => $params,
    'sync_timeout' => 30,
], JSON_UNESCAPED_SLASHES);
$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$headers = [
    'Content-Type' => 'application/json',
    'Host' => 'openapi.meitu.com',
];
$signer = new Signer('YOUR_ACCESS_KEY', 'YOUR_SECRET_KEY');
$curl = $signer->sign($url, 'POST', $headers, $body);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);
$response = curl_exec($curl);
if ($response === false) {
    echo 'Error: ' . curl_error($curl) . PHP_EOL;
} else {
    echo 'Status: ' . curl_getinfo($curl, CURLINFO_HTTP_CODE) . PHP_EOL;
    echo 'Response: ' . $response . PHP_EOL;
}
curl_close($curl);

Java

Java Signing SDK

import com.meitu.openai.common.Signer;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

public class Main {
    public static void main(String[] args) throws Exception {
        String body =
                "{\n" +
                "  \"task\": \"/v1/change_cloth_color/495824\",\n" +
                "  \"task_type\": \"formula\",\n" +
                "  \"init_images\": [\n" +
                "    {\n" +
                "      \"url\": \"https://example.com/input.jpg\",\n" +
                "      \"profile\": {\n" +
                "        \"media_profiles\": {\n" +
                "          \"media_data_type\": \"url\"\n" +
                "        },\n" +
                "        \"version\": \"v1\"\n" +
                "      }\n" +
                "    },\n" +
                "    {\n" +
                "      \"url\": \"https://example.com/cloth-mask.png\",\n" +
                "      \"profile\": {\n" +
                "        \"media_profiles\": {\n" +
                "          \"media_data_type\": \"url\"\n" +
                "        },\n" +
                "        \"version\": \"v1\"\n" +
                "      }\n" +
                "    }\n" +
                "  ],\n" +
                "  \"params\": \"{\\\"parameter\\\":{\\\"rsp_media_type\\\":\\\"jpg\\\",\\\"color_str\\\":\\\"#FFC0CB\\\",\\\"cloth_category\\\":\\\"None\\\",\\\"inpaint\\\":0}}\",\n" +
                "  \"sync_timeout\": 30\n" +
                "}";
        String url = "https://openapi.meitu.com/api/v1/sdk/sync/push";
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put(Signer.HeaderHost, "openapi.meitu.com");
        Signer signer = new Signer("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY");
        Map<String, String> signedHeaders = signer.sign(url, "POST", headers, body);
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        try {
            connection.setRequestMethod("POST");
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(60000);
            connection.setInstanceFollowRedirects(false);
            connection.setDoOutput(true);
            for (Map.Entry<String, String> entry : signedHeaders.entrySet()) {
                connection.setRequestProperty(entry.getKey(), entry.getValue());
            }
            byte[] bodyBytes = body.getBytes(StandardCharsets.UTF_8);
            connection.setFixedLengthStreamingMode(bodyBytes.length);
            try (OutputStream output = connection.getOutputStream()) {
                output.write(bodyBytes);
            }
            int status = connection.getResponseCode();
            System.out.println("Status: " + status);
            InputStream stream = status >= 400
                    ? connection.getErrorStream() : connection.getInputStream();
            if (stream != null) {
                try (InputStream input = stream;
                     ByteArrayOutputStream output = new ByteArrayOutputStream()) {
                    byte[] buffer = new byte[4096];
                    int length;
                    while ((length = input.read(buffer)) != -1) {
                        output.write(buffer, 0, length);
                    }
                    System.out.println("Response: " + output.toString("UTF-8"));
                }
            }
        } finally {
            connection.disconnect();
        }
    }
}