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_typetourl. 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/jsonAuthentication
Use an AK/SK pair with access to this capability and sign requests with the signing SDK. See API Request Signing.
Request Parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | task | string | Fixed value: /v1/change_cloth_color/495824. |
| Yes | task_type | string | Fixed value: formula. |
| Yes | init_images | array | Input images. The examples provide the original image first, then the clothing segmentation mask. |
| Yes | params | string | A JSON-serialized string containing the algorithm parameters described below. |
| No | sync_timeout | integer | Synchronous waiting period in seconds. Default: 30. |
init_images Element
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | url | string | Image URL or Base64-encoded data, matching profile.media_profiles.media_data_type. |
| Yes | profile | object | Image properties. |
profile
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | version | string | Fixed value: v1. |
| Yes | media_profiles | object | Image data type. |
| No | media_extra | object | Additional image information. Omit when not needed. |
media_profiles
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | media_data_type | string | url: 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
}
}| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | parameter | object | Clothing recoloring parameters. |
| No | extra | object | Additional processing information in the algorithm protocol. Omit when not needed. |
parameter
| Required | Parameter | Type | Description |
|---|---|---|---|
| No | rsp_media_type | string | jpg: return result images as Base64-encoded data. The request examples use jpg. |
| Yes | color_str | string | Target color as a hexadecimal color code, such as #FFC0CB. |
| Yes | cloth_category | string | Clothing category; see the values below. The source specifies None as the default and also marks the field as required. Set it explicitly. |
| Yes | inpaint | integer | Edge 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:
| Value | Description |
|---|---|
| None | Default in the source document; its specific processing behavior is not documented. |
| dress | Dress. |
| up | Upper-body clothing. |
| down | Lower-body clothing, such as trousers and skirts. |
| coat | Outerwear. |
| up-down | Recolor upper- and lower-body clothing together. |
| jumpsuit | Jumpsuit. |
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.
| Field | Type | Description |
|---|---|---|
| code | integer | Gateway business status code. 0 does not mean the algorithm task has completed; also check the task status. |
| message | string | Gateway response message. |
| data | object | Task information. |
| data.task_id | string | Gateway task ID used to query results. |
| data.status | integer | Task status; see below. |
| data.result | object | Task result. The internal field nesting for this task remains unconfirmed. |
| data.status | Description |
|---|---|
| -1 | Task not found. |
| 0 | Task created. |
| 1 | Running. |
| 2 | Failed. |
| 9 | Synchronous wait timed out. Continue querying; this does not indicate task failure. |
| 10 | Succeeded. |
Algorithm Result Fields
These fields come from the original direct algorithm endpoint. They are not documented here as root-level gateway response fields.
| Field | Type | Description |
|---|---|---|
| parameter | object | Output image type and version information. |
| parameter.rsp_media_type | string | Output data type. The source field description specifies jpg, while its success example uses url. |
| parameter.version | string | Algorithm version shown in the source success example, such as 1.0.0. |
| media_info_list | array | The source success example returns the recolored image first, followed by the clothing segmentation mask. |
| media_info_list[].media_data | string | Base64 data or an image URL, depending on media_data_type. |
| media_info_list[].media_profiles | object | Output image properties. |
| media_info_list[].media_profiles.media_data_type | string | jpg indicates Base64 data; url indicates an image URL. |
Algorithm Error Fields
| Field | Type | Description |
|---|---|---|
| ErrorCode | integer | Algorithm error code. |
| ErrorMsg | string | Algorithm error message. |
| Data | string / null | Additional 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
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
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
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
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();
}
}
}