Clothing Wrinkle Removal

Description

Reduces wrinkles in clothing in the input image. Set the wrinkle removal strength with alpha, and retrieve the processed image as a URL or Base64-encoded data.

Image Requirements

  • Input formats: JPG, JPEG, PNG, BMP, and HEIF.
  • Input file size: up to 30 MB.
  • Input images: one.

Request URL

The task type (task_type) is fixed to formula. Use the endpoint and task name for the appropriate region:

RegionEndpointTask Name (task)Signing Host
Chinahttps://openapi.meitu.com/api/v1/sdk/sync/push/v1/Clothes_wrinkle_removal/470438openapi.meitu.com
Singaporehttps://openapi.starii.com/api/v1/sdk/sync/push/v1/Clothes_wrinkle_removal/251001openapi.starii.com
Frankfurthttps://openapi-fra.starii.com/api/v1/sdk/sync/push/v1/Clothes_wrinkle_removal/47611openapi-fra.starii.com

The request and SDK examples use the China endpoint. To switch regions, update the endpoint, task, and signing Host header together using values from the same row.

HTTP Method

POST

Content-Type: application/json

Authentication

Sign requests using your Access Key (AK) and Secret Key (SK). See API Request Signing.

Request Parameters

RequiredParameterTypeDescription
YestaskstringTask name for the selected region. For China, use /v1/Clothes_wrinkle_removal/470438.
Yestask_typestringFixed value: formula.
Yesinit_imagesobject[]Input image list containing one image to process.
YesparamsstringA JSON-encoded string containing the algorithm parameters described below.
Nosync_timeoutintSynchronous wait time in seconds. Default: 30. Set to -1 to return without waiting. If data.status = 9, use the Task Status API to retrieve the result.

init_images Item

RequiredParameterTypeDescription
YesurlstringImage URL or Base64-encoded image data. Specify the transmission type in profile.media_profiles.media_data_type.
NoprofileobjectImage transmission information.

profile

RequiredParameterTypeDescription
Nomedia_extraobjectAdditional media parameters.
Nomedia_profilesobjectMedia transmission information.
NoversionstringThe examples use v1.

media_profiles

RequiredParameterTypeDescription
Nomedia_data_typestringurl: provide an image URL. jpg: provide Base64-encoded image data.

params

Construct the following parameter object, then encode it as a JSON string for the params field in the request body.

RequiredParameterTypeDescription
YesparameterobjectClothing wrinkle removal parameters.

parameter

RequiredParameterTypeDescription
Norsp_media_typestringOutput transmission type: url for image URLs or jpg for Base64-encoded image data. Default: url.
NoalphaintWrinkle removal strength in the range [0, 100]. The examples use 100.

Both rsp_media_type and alpha belong to the parameter object inside the params string.

Request Example

This example uses the China endpoint, provides the source image by URL, sets the wrinkle removal strength to 100, and returns the result as a URL. Replace https://example.com/input.jpg with an accessible image URL.

{
  "task": "/v1/Clothes_wrinkle_removal/470438",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://example.com/input.jpg",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"parameter\":{\"rsp_media_type\":\"url\",\"alpha\":100}}",
  "sync_timeout": 30
}

Response Fields

The following descriptions and examples use URL output and show the task status and result returned by the synchronous task API. After the task succeeds, retrieve the output images from data.result.urls.

FieldTypeDescription
codeintRequest processing status. 0 indicates normal request processing; a nonzero value indicates failure. Also check data.status to determine whether the task has completed.
messagestringResponse message or error information.
dataobject/nullTask information. May be null if the request fails.

data

FieldTypeDescription
statusintTask status: -1 not found; 0 created; 1 processing; 2 failed; 9 result query required; 10 succeeded.
resultobjectTask ID and processing result.
progressnumberTask progress, for example 0.1, 0.85, or 1.

result

FieldTypeDescription
idstringTask ID. Pass this value as task_id when querying the result.
urlsstring[]Result image URLs available after the task succeeds.

When data.status = 9, use data.result.id to call the Task Status API. For China, send a signed GET request to https://openapi.meitu.com/api/v1/sdk/status?task_id=<TASK_ID>. Use the same region endpoint and corresponding Host for task submission and querying.

Query status 0 or 1 means the task is not yet complete; 10 means success; 2 means failure. Query and save results promptly. Tasks expire after 24 hours, and historical task queries are not supported.

Response Examples

Successful Response

{
  "code": 0,
  "message": "",
  "data": {
    "status": 10,
    "result": {
      "id": "50309bd5-a827-4125-bc96-62039c93770b",
      "urls": [
        "https://example.com/result.png"
      ]
    },
    "progress": 1
  }
}

Query-Required Response

Pass the returned data.result.id as the task_id parameter to the Task Status API.

{
  "code": 0,
  "message": "",
  "data": {
    "status": 9,
    "result": {
      "id": "50309bd5-a827-4125-bc96-62039c93770b"
    },
    "progress": 0
  }
}

Failed Response

{
  "code": 20008,
  "message": "UNSUITABLE_IMAGE",
  "data": null
}

API-Specific Error Codes

Error CodeError MessageDescription
20001PROCESS_ERRORProcessing error
20003DETECT_NOT_FACENo face detected
20004MORE_THAN_ONE_FACEMore than one face detected
20007MISSING_LANDMARK_ARGUMENTSFace landmarks are missing
20008UNSUITABLE_IMAGEImage does not meet the requirements
20009UNSUPPORT_TYPEUnsupported type
20010DETECT_NOT_FACENo face detected in the second image
20011UNSUITABLE_VERTICAL_IMAGEImage height does not meet the requirements
20012UNSUITABLE_HORIZONTAL_IMAGEImage width does not meet the requirements
20013RESOLUTION_TOO_LARGE_ERRORImage resolution is too high
20014NOT_FOUNDImage not found
20015PICTURE_OVERRUN_ERRORImage exceeds the limit
20020DETECT_FACE_OUTOFIMAGEFacial features are missing
20021DETECT_FACE_PITCHANGLE_BIGFace pitch angle is too large
20022DETECT_FACE_YAWANGLE_BIGFace yaw angle is too large
20023DETECT_FACE_LOWAREAFace area is too small or has insufficient pixels
21001LOAD_MODEL_ERRORFailed to load the model
21002HAIR_MASK_LOSSHair mask is missing
21003FACE_NUM_ERRORInvalid number of faces
21004AR_PARSE_FAULTFailed to parse the AR plist
21005AR_EEEOR_COUNTAR face error
21006AR_FACE_OUTAR extends beyond the face region
21007JSON_ERRORInvalid JSON content
21008BACKGROUND_IMAGE_LOSSBackground image is missing
21009BODY_MASK_LOSSBody mask is missing
21010FACE_ANGLE_ERRORInvalid face angle
21011SKIN_MASK_LOSSSkin mask is missing
21012BODY_INFO_LOSSBody keypoints or contour points are missing
21013RECT_OUT_IMAGERegion extends beyond the image
30001GEN_ERRORGeneration error

Common Error Codes

See API Error Codes.

SDK Examples

The following examples use the China endpoint, set alpha = 100, and return the processed image as a URL. Replace the AK, SK, and input image URL before running the code.

The examples print the API response. If data.status = 9, query the task result as described above. To switch regions, update the endpoint, task, and Host together according to the Request URL table.

Python

Set up the SDK as described in the Python Signing SDK documentation.

import json

import requests
from sign_sdk import sign

def api_call_example():
    key = "your_access_key"
    secret = "your_secret_key"
    url = "https://openapi.meitu.com/api/v1/sdk/sync/push"
    headers = {
        "Content-Type": "application/json",
        sign.HeaderHost: "openapi.meitu.com",
    }
    inner_params = {
        "parameter": {
            "rsp_media_type": "url",
            "alpha": 100
        }
    }
    payload = {
        "task": "/v1/Clothes_wrinkle_removal/470438",
        "task_type": "formula",
        "init_images": [
            {
                "url": "https://example.com/input.jpg",
                "profile": {
                    "media_profiles": {
                        "media_data_type": "url"
                    },
                    "version": "v1"
                }
            }
        ],
        "params": json.dumps(inner_params, ensure_ascii=False),
        "sync_timeout": 30
    }
    body = json.dumps(payload, ensure_ascii=False)

    signer = sign.Signer(key, secret)
    signed_request = signer.sign(url, "POST", headers, body)
    with requests.Session() as session:
        response = session.send(signed_request, timeout=60)
        print("Status:", response.status_code)
        print("Response:", response.text)

if __name__ == "__main__":
    api_call_example()

Go

Set up the SDK as described in the Go Signing SDK documentation.

package main

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

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

func main() {
	key := "your_access_key"
	secret := "your_secret_key"
	signObj := signer.NewSigner(key, secret)
	url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
	headers := make(http.Header)
	headers.Set(signer.HeaderHost, "openapi.meitu.com")
	headers.Set("Content-Type", "application/json")

	body := `{
  "task": "/v1/Clothes_wrinkle_removal/470438",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://example.com/input.jpg",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"parameter\":{\"rsp_media_type\":\"url\",\"alpha\":100}}",
  "sync_timeout": 30
}`
	req, err := signObj.Sign(url, http.MethodPost, headers, body)
	if err != nil {
		fmt.Println("Failed to sign request:", err)
		return
	}
	client := &http.Client{Timeout: 60 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		fmt.Println("Failed to send request:", err)
		return
	}
	defer resp.Body.Close()

	responseBody, err := io.ReadAll(resp.Body)
	if err != nil {
		fmt.Println("Failed to read response:", err)
		return
	}
	fmt.Println("Status:", resp.StatusCode)
	fmt.Println("Response:", string(responseBody))
}

PHP

Set up the SDK as described in the PHP Signing SDK documentation.

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

$key = 'your_access_key';
$secret = 'your_secret_key';
$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$headers = [
    'Content-Type' => 'application/json',
    'Host' => 'openapi.meitu.com',
];

$innerParams = json_encode([
    'parameter' => [
        'rsp_media_type' => 'url',
        'alpha' => 100,
    ],
], JSON_UNESCAPED_SLASHES);
$body = json_encode([
    'task' => '/v1/Clothes_wrinkle_removal/470438',
    'task_type' => 'formula',
    'init_images' => [
        [
            'url' => 'https://example.com/input.jpg',
            'profile' => [
                'media_profiles' => [
                    'media_data_type' => 'url',
                ],
                'version' => 'v1',
            ],
        ],
    ],
    'params' => $innerParams,
    'sync_timeout' => 30,
], JSON_UNESCAPED_SLASHES);

$signer = new Signer($key, $secret);
$curl = $signer->sign($url, 'POST', $headers, $body);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_TIMEOUT, 60);
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

Set up the SDK as described in the Java Signing SDK documentation.

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 {
        Signer signer = new Signer("your_access_key", "your_secret_key");
        String url = "https://openapi.meitu.com/api/v1/sdk/sync/push";
        String method = "POST";
        Map<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put(Signer.HeaderHost, "openapi.meitu.com");

        String body = "{\n"
                + "  \"task\": \"/v1/Clothes_wrinkle_removal/470438\",\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"
                + "  \"params\": \"{\\\"parameter\\\":{\\\"rsp_media_type\\\":\\\"url\\\",\\\"alpha\\\":100}}\",\n"
                + "  \"sync_timeout\": 30\n"
                + "}";

        Map<String, String> signedHeaders = signer.sign(url, method, headers, body);
        HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
        try {
            connection.setRequestMethod(method);
            connection.setConnectTimeout(10000);
            connection.setReadTimeout(60000);
            connection.setInstanceFollowRedirects(false);
            for (Map.Entry<String, String> entry : signedHeaders.entrySet()) {
                connection.setRequestProperty(entry.getKey(), entry.getValue());
            }
            connection.setDoOutput(true);
            try (OutputStream output = connection.getOutputStream()) {
                output.write(body.getBytes(StandardCharsets.UTF_8));
            }

            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: "
                            + new String(output.toByteArray(), StandardCharsets.UTF_8));
                }
            }
        } finally {
            connection.disconnect();
        }
    }
}