Image Layering V2
Description
Image Layering V2 supports three scenarios: editable-text layering for Design Studio, PPT layering, and non-editable-text layering for Design Studio.
Version
4.0
Image Requirements
- Supported image formats: JPG and PNG.
- Supported image dimensions: the longer side must not exceed 4,096 pixels.
API URL
Production environment: https://openapi.meitu.com
Task submission endpoint: https://openapi.meitu.com/api/v1/sdk/sync/push
Task name (task): /v1/poster_trans_rob/491768
Task type (task_type): formulaMethod
POST
Content-Type: application/json
Authentication
Request Parameters
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | params | string | Algorithm parameters (JSON string) |
| Yes | init_images | object[] | Input image list. Pass one image to be layered for this API |
| Yes | task | string | Fixed value: /v1/poster_trans_rob/491768 |
| Yes | task_type | string | Fixed value: formula |
| No | sync_timeout | int | Synchronous timeout, default: 30 |
The structure of each multimedia item in init_images is as follows:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | url | string | Image URL or Base64-encoded data |
| Yes | profile | object | Attribute information |
The profile object is described below:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_profiles | object | Media attribute information |
| Yes | version | string | Fixed value: v1 |
The media_profiles object is described below:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | media_data_type | string | url indicates a URL; types such as jpg indicate Base64-encoded data |
The params inference parameters are provided as a JSON string with the following structure:
| Required | Field | Type | Description |
|---|---|---|---|
| No | rsp_media_type | string | Default: url; jpg indicates Base64-encoded data |
| Yes | parameter | object | Core algorithm parameter object |
Algorithm parameters in parameter:
| Required | Parameter | Type | Description |
|---|---|---|---|
| Yes | eliminate_type | string | Removal type, default: big |
| Yes | only_text_eliminate | boolean | Whether to remove text only, default: false |
| Yes | ori_lang | string | Source language for image layering, default: ch. Supported values: Simplified Chinese ch, Traditional Chinese chinese_cht, English en, Japanese japan, and Korean korean |
| Yes | poster_translate_flag | string | Fixed image-layering parameter. Use 9 for layering scenarios |
| Yes | subject_protect_flag | boolean | Whether text on the main product subject requires layering (subject protection): false for no; true for yes |
| Yes | target_lang | string | Target language, default: ch |
| Yes | business_side_flag | string | Use an empty string by default for editable-text scenarios, design_ppt_layer for PPT layering, and text_none_editable for non-editable-text scenarios |
| Yes | generate_picture_flag | string | Fixed value for layering scenarios: 0 |
| Yes | convert_json_psd_flag | string | Whether to convert the layered result into a PSD file: 0 generates a PSD with non-editable text; 1 generates a PSD with editable text; 2 does not generate a PSD (default). When a PSD is generated, image_psd_url in the response provides its download URL |
Image-layering scenarios:
- Design Studio editable-text version: all text in the image is mapped to 209 Design Studio fonts. Users may use the fonts at their discretion based on whether they hold the corresponding font licenses. Set
poster_translate_flagto9and use the default empty string forbusiness_side_flag. - PPT layering: intended for high-resolution PPT images containing many small icons, thin lines, and similar elements. Set
poster_translate_flagto9andbusiness_side_flagtodesign_ppt_layer. - Design Studio non-editable-text version: image layers are transparent, and text is also provided as a transparent-background layer. Set
poster_translate_flagto9andbusiness_side_flagtotext_none_editable.
Request Examples
Design Studio editable-text version:
{
"task": "/v1/poster_trans_rob/491768",
"task_type": "formula",
"init_images": [
{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc3Mjc4MDQwMA==/fca51ed5-01dd-4e20-6c19-4db3767cadf0.jpeg",
"profile": {
"media_profiles": {
"media_data_type": "url"
},
"version": "v1"
}
}
],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"eliminate_type\":\"big\",\"only_text_eliminate\":false,\"ori_lang\":\"ch\",\"poster_translate_flag\":\"9\",\"business_side_flag\":\"\",\"subject_protect_flag\":true,\"target_lang\":\"ch\",\"generate_picture_flag\":\"0\",\"convert_json_psd_flag\":\"2\"}}",
"sync_timeout": 30
}PPT layering:
{
"task": "/v1/poster_trans_rob/491768",
"task_type": "formula",
"init_images": [
{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc3Mjc4MDQwMA==/fca51ed5-01dd-4e20-6c19-4db3767cadf0.jpeg",
"profile": {
"media_profiles": {
"media_data_type": "url"
},
"version": "v1"
}
}
],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"eliminate_type\":\"big\",\"only_text_eliminate\":false,\"ori_lang\":\"ch\",\"poster_translate_flag\":\"9\",\"business_side_flag\":\"design_ppt_layer\",\"subject_protect_flag\":true,\"target_lang\":\"ch\",\"generate_picture_flag\":\"0\",\"convert_json_psd_flag\":\"2\"}}",
"sync_timeout": 30
}Design Studio non-editable-text version:
{
"task": "/v1/poster_trans_rob/491768",
"task_type": "formula",
"init_images": [
{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc3Mjc4MDQwMA==/fca51ed5-01dd-4e20-6c19-4db3767cadf0.jpeg",
"profile": {
"media_profiles": {
"media_data_type": "url"
},
"version": "v1"
}
}
],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"eliminate_type\":\"big\",\"only_text_eliminate\":false,\"ori_lang\":\"ch\",\"poster_translate_flag\":\"9\",\"business_side_flag\":\"text_none_editable\",\"subject_protect_flag\":true,\"target_lang\":\"ch\",\"generate_picture_flag\":\"0\",\"convert_json_psd_flag\":\"2\"}}",
"sync_timeout": 30
}Response Fields
Note: Generated results are cleaned up periodically. Download and save them promptly.| Field | Type | Description |
|---|---|---|
| request_id | string | Request identifier |
| trace_id | string | Trace identifier |
| code | int | Business status code; 0 indicates that the request was accepted successfully |
| error_code | int | Error code; 0 on success |
| message | string | Business message |
| tips | any | Additional information; may be null |
| data | object | Task status and algorithm result |
Fields in data:
| Field | Type | Description |
|---|---|---|
| status | int | Status code: -1 task not found; 0 created; 1 processing; 2 failed; 9 timed out—use the Query API; 10 succeeded |
| result | object | Algorithm result |
| progress | number | Task progress |
| predict_elapsed | int | Estimated processing time, in milliseconds |
| create_time | int64 | Creation timestamp, in milliseconds |
| task_id | string | Task ID |
| custom_task_id | string | Client-defined task ID |
| trace_id | string | Trace identifier |
| client_info | string | Client information |
| init_images | object[]/null | Echo of input media |
Fields in data.result:
| Field | Type | Description |
|---|---|---|
| id | string | Unique task identifier |
| parameters | object | Algorithm parameter information. return_json_data contains the JSON result for layering or translation |
| data | object | Detailed data returned by the algorithm |
| msg | string | Response message |
| msg_id | string | Message ID |
| mtlab_res | object | Underlying algorithm result |
Fields in data.result.parameters.return_json_data:
| Field | Type | Description |
|---|---|---|
| code | number | Error code; 0 indicates success |
| cost_time | string | Processing time, in seconds |
| error_message | string | Error message |
| json_data | string | JSON string containing the layering or translation result, including template configuration, layer information, and text regions |
Fields after decoding json_data:
| Field | Type | Description |
|---|---|---|
| version | string | Template version |
| name | string | Template name |
| templateConf | array | Layer configuration array, including background layers, text layers, and other layers |
| text_graphic_box_info | array | Text graphic region information |
| preview | string | Preview image URL |
| width | number | Template width |
| height | number | Template height |
| generate_picture_url | string | Generated image URL; returns the translated image in translation scenarios |
| image_psd_url | string | PSD file URL. Returned when convert_json_psd_flag is 0 or 1; no PSD is generated when it is 2 |
Fields for each layer in templateConf:
| Field | Type | Description |
|---|---|---|
| id | string | Unique layer identifier |
| layerType | string | Layer type, such as bg (background) or text (text) |
| width | number | Layer width |
| height | number | Layer height |
| left | number | X-coordinate of the upper-left corner |
| top | number | Y-coordinate of the upper-left corner |
| rotate | number | Rotation angle |
| opacity | number | Opacity |
| hidden | boolean | Whether the layer is hidden |
| text | string | Text content (text layers) |
| ori_rotate | number | Original rotation angle |
| textOri | string | Original text content (preserved after translation) |
| color | string | Text color, such as #040403 |
| fontSize | number | Font size |
| fontFamily | string | Font name |
| url | string | Image resource URL (for background and other layers) |
| sub_name | string | Sublayer name, such as Main_Title, Subtitle, or Horizontal_Text |
Fields in data.result.data:
| Field | Type | Description |
|---|---|---|
| duration | object | Processing-time statistics for each stage |
| error_code | number | Algorithm error code; 0 indicates success |
| error_msg | string | Algorithm error message |
| extra | object | Additional fields |
| media_info_list | array | Media information list |
| msg_id | string | Message ID |
| parameter | object | Echo of parameters |
Fields in data.result.data.duration:
| Field | Type | Description |
|---|---|---|
| alg_process_time | number | Algorithm processing time, in milliseconds |
| created_timestamp | number | Task creation timestamp, in seconds |
| pull_timestamp | number | Resource retrieval timestamp, in seconds |
| repost_time | number | Retry time |
| upload_time | number | Upload time, in milliseconds |
| waiting_time | number | Queue wait time, in milliseconds |
Fields in data.result.mtlab_res:
| Field | Type | Description |
|---|---|---|
| ErrorCode | number | Underlying error code |
| ErrorMsg | string | Underlying error message |
| error_code | number | Error code (compatibility field) |
| error_msg | string | Error message (compatibility field) |
| media_info_list | array | Media information list |
| msg_id | string | Message ID |
| parameter | object | Parameter information |
Error codes and messages specific to this API:
| Error Code | Error Message | Description |
|---|---|---|
| 20001 | PROCESS_ERROR | Processing error |
Response Examples
Successful Response Example
{
"request_id": "",
"trace_id": "",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 10,
"result": {
"id": "t_mt1a3i5n7bcf03ec36-e830-449f-bb0f-173500efaa1c",
"parameters": {
"return_json_data": {
"code": 0,
"cost_time": "22.980",
"error_message": "",
"json_data": "{\"version\":\"11.0.0\",\"name\":\"The aroma of qingtuan fills the air.\",\"templateConf\":[],\"text_graphic_box_info\":[],\"preview\":\"https://mt-deepnet-models-release.oss-cn-beijing.aliyuncs.com/deepnet/cloud/7252e262-60a7-11f1-9f7a-c69948c4966f.jpg\",\"generate_picture_url\":\"\"}"
}
},
"data": {
"duration": {
"alg_process_time": 23204,
"created_timestamp": 1780640770,
"pull_timestamp": 1780640770,
"repost_time": 0,
"upload_time": 0,
"waiting_time": 66
},
"error_code": 0,
"error_msg": "success",
"extra": {},
"media_info_list": [],
"msg_id": "ba2299eb-4392-4845-6aa0-r009c6429cb6",
"parameter": {
"return_json_data": {
"code": 0,
"cost_time": "22.980",
"error_message": "",
"json_data": "{\"version\":\"11.0.0\",\"templateConf\":[],\"text_graphic_box_info\":[]}"
}
}
},
"msg": "success",
"msg_id": "ba2299eb-4392-4845-6aa0-r009c6429cb6",
"mtlab_res": {
"ErrorCode": 0,
"ErrorMsg": "",
"error_code": 0,
"error_msg": "",
"media_info_list": null,
"msg_id": "ba2299eb-4392-4845-6aa0-r009c6429cb6",
"parameter": null
}
},
"progress": 1,
"predict_elapsed": 10000,
"create_time": 1780640770692,
"task_id": "t_mt1a3i5n7bcf03ec36-e830-449f-bb0f-173500efaa1c",
"custom_task_id": "",
"trace_id": "",
"client_info": "",
"init_images": null
}
}Query-Required Response Example
Use the Query API to retrieve the result.
Response Status: 200
Content-Type: application/json; charset=utf-8
{
"request_id": "",
"trace_id": "",
"code": 0,
"error_code": 0,
"message": "success",
"tips": null,
"data": {
"status": 9,
"result": {
"id": "t_mt1a3i5n7b4bcba123-xxxx-45a1-88d1-c625b75c4591"
},
"progress": 0,
"predict_elapsed": 10000,
"create_time": 1770285187417,
"task_id": "t_mt1a3i5n7b4bcba123-xxxx-45a1-88d1-c625b75c4591",
"custom_task_id": "",
"trace_id": "ace75fe5-xxxx-46ad-a1db-cbcfde308f8a",
"client_info": "",
"init_images": null
}
}Failed Response Example
Response Status: 400
Content-Type: application/json; charset=utf-8
{
"request_id": "",
"trace_id": "",
"code": 20001,
"error_code": 20001,
"message": "PROCESS_ERROR",
"tips": null,
"data": {
"status": 2,
"result": {
"error_code": 20001,
"message": "PROCESS_ERROR"
},
"progress": 0,
"predict_elapsed": 0,
"create_time": 0,
"task_id": "",
"custom_task_id": "",
"trace_id": "",
"client_info": "",
"init_images": null
}
}General Error Codes and Messages
See API Error Codes.
SDK Examples
Python
import json
import requests
from sign_sdk import sign
def api_call_example():
key = "your_api_key"
secret = "your_api_secret"
url = "https://openapi.meitu.com/api/v1/sdk/sync/push"
method = "POST"
headers = {
"Content-Type": "application/json",
sign.HeaderHost: "openapi.meitu.com",
}
inner_params = {
"rsp_media_type": "url",
"parameter": {
"eliminate_type": "big",
"only_text_eliminate": False,
"ori_lang": "ch",
"poster_translate_flag": "9",
"business_side_flag": "",
"subject_protect_flag": True,
"target_lang": "ch",
"generate_picture_flag": "0",
"convert_json_psd_flag": "2",
},
}
payload = {
"task": "/v1/poster_trans_rob/491768",
"task_type": "formula",
"init_images": [
{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc3Mjc4MDQwMA==/fca51ed5-01dd-4e20-6c19-4db3767cadf0.jpeg",
"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, method, headers, body)
response = requests.Session().send(signed_request)
print(f"Status: {response.status_code}")
print(f"Response: {response.text}")
if __name__ == "__main__":
api_call_example()Go
package main
import (
"fmt"
"io"
"net/http"
"github.com/mtlab/api/signer"
)
func main() {
key := "your_api_key"
secret := "your_api_secret"
signObj := signer.NewSigner(key, secret)
url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
method := http.MethodPost
headers := make(http.Header)
headers.Set(signer.HeaderHost, "openapi.meitu.com")
headers.Set("Content-Type", "application/json")
body := `{
"task": "/v1/poster_trans_rob/491768",
"task_type": "formula",
"init_images": [{
"url": "https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc3Mjc4MDQwMA==/fca51ed5-01dd-4e20-6c19-4db3767cadf0.jpeg",
"profile": {
"media_profiles": {"media_data_type": "url"},
"version": "v1"
}
}],
"params": "{\"rsp_media_type\":\"url\",\"parameter\":{\"eliminate_type\":\"big\",\"only_text_eliminate\":false,\"ori_lang\":\"ch\",\"poster_translate_flag\":\"9\",\"business_side_flag\":\"\",\"subject_protect_flag\":true,\"target_lang\":\"ch\",\"generate_picture_flag\":\"0\",\"convert_json_psd_flag\":\"2\"}}",
"sync_timeout": 30
}`
req, err := signObj.Sign(url, method, headers, body)
if err != nil {
fmt.Println("Failed to sign request:", err)
return
}
resp, err := http.DefaultClient.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("Read response failed:", err)
return
}
fmt.Println("Response:", resp.StatusCode, string(responseBody))
}PHP
<?php
require 'signer.php';
$key = 'your_api_key';
$secret = 'your_api_secret';
$signer = new Signer($key, $secret);
$url = 'https://openapi.meitu.com/api/v1/sdk/sync/push';
$method = 'POST';
$headers = ['Content-Type' => 'application/json'];
$innerParams = json_encode([
'rsp_media_type' => 'url',
'parameter' => [
'eliminate_type' => 'big',
'only_text_eliminate' => false,
'ori_lang' => 'ch',
'poster_translate_flag' => '9',
'business_side_flag' => '',
'subject_protect_flag' => true,
'target_lang' => 'ch',
'generate_picture_flag' => '0',
'convert_json_psd_flag' => '2',
],
]);
$body = json_encode([
'task' => '/v1/poster_trans_rob/491768',
'task_type' => 'formula',
'init_images' => [
[
'url' => 'https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc3Mjc4MDQwMA==/fca51ed5-01dd-4e20-6c19-4db3767cadf0.jpeg',
'profile' => [
'media_profiles' => ['media_data_type' => 'url'],
'version' => 'v1',
],
],
],
'params' => $innerParams,
'sync_timeout' => 30,
]);
$curl = $signer->sign($url, $method, $headers, $body);
$response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status === 0) {
echo 'Error: ' . curl_error($curl);
} else {
echo "Status: {$status}\n";
echo "Response: {$response}\n";
}
curl_close($curl);
?>Java
package com.meitu.openai.common;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
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_api_key", "your_api_secret");
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/poster_trans_rob/491768\",\n" +
" \"task_type\": \"formula\",\n" +
" \"init_images\": [{\n" +
" \"url\": \"https://obs.mtlab.meitu.com/public/EtRGxLI8ulQ43pGhuZfym9aYUD2PUbMP/MTc3Mjc4MDQwMA==/fca51ed5-01dd-4e20-6c19-4db3767cadf0.jpeg\",\n" +
" \"profile\": {\n" +
" \"media_profiles\": {\"media_data_type\": \"url\"},\n" +
" \"version\": \"v1\"\n" +
" }\n" +
" }],\n" +
" \"params\": \"{\\\"rsp_media_type\\\":\\\"url\\\",\\\"parameter\\\":{\\\"eliminate_type\\\":\\\"big\\\",\\\"only_text_eliminate\\\":false,\\\"ori_lang\\\":\\\"ch\\\",\\\"poster_translate_flag\\\":\\\"9\\\",\\\"business_side_flag\\\":\\\"\\\",\\\"subject_protect_flag\\\":true,\\\"target_lang\\\":\\\"ch\\\",\\\"generate_picture_flag\\\":\\\"0\\\",\\\"convert_json_psd_flag\\\":\\\"2\\\"}}\",\n" +
" \"sync_timeout\": 30\n" +
"}";
Map<String, String> signedHeaders = signer.sign(url, method, headers, body);
HttpURLConnection connection = (HttpURLConnection) new URL(url).openConnection();
connection.setRequestMethod(method);
for (Map.Entry<String, String> entry : signedHeaders.entrySet()) {
connection.setRequestProperty(entry.getKey(), entry.getValue());
}
connection.setDoOutput(true);
connection.getOutputStream().write(body.getBytes(StandardCharsets.UTF_8));
int status = connection.getResponseCode();
InputStream stream = status >= 400
? connection.getErrorStream()
: connection.getInputStream();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
StringBuilder response = new StringBuilder();
String line;
while ((line = reader.readLine()) != null) {
response.append(line);
}
System.out.println("Response: " + status + " " + response);
}
}
}