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): formula

Method

POST

Content-Type: application/json

Authentication

Open Platform API Signing

Request Parameters

RequiredParameterTypeDescription
YesparamsstringAlgorithm parameters (JSON string)
Yesinit_imagesobject[]Input image list. Pass one image to be layered for this API
YestaskstringFixed value: /v1/poster_trans_rob/491768
Yestask_typestringFixed value: formula
Nosync_timeoutintSynchronous timeout, default: 30

The structure of each multimedia item in init_images is as follows:

RequiredParameterTypeDescription
YesurlstringImage URL or Base64-encoded data
YesprofileobjectAttribute information

The profile object is described below:

RequiredParameterTypeDescription
Yesmedia_profilesobjectMedia attribute information
YesversionstringFixed value: v1

The media_profiles object is described below:

RequiredParameterTypeDescription
Yesmedia_data_typestringurl 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:

RequiredFieldTypeDescription
Norsp_media_typestringDefault: url; jpg indicates Base64-encoded data
YesparameterobjectCore algorithm parameter object

Algorithm parameters in parameter:

RequiredParameterTypeDescription
Yeseliminate_typestringRemoval type, default: big
Yesonly_text_eliminatebooleanWhether to remove text only, default: false
Yesori_langstringSource language for image layering, default: ch. Supported values: Simplified Chinese ch, Traditional Chinese chinese_cht, English en, Japanese japan, and Korean korean
Yesposter_translate_flagstringFixed image-layering parameter. Use 9 for layering scenarios
Yessubject_protect_flagbooleanWhether text on the main product subject requires layering (subject protection): false for no; true for yes
Yestarget_langstringTarget language, default: ch
Yesbusiness_side_flagstringUse an empty string by default for editable-text scenarios, design_ppt_layer for PPT layering, and text_none_editable for non-editable-text scenarios
Yesgenerate_picture_flagstringFixed value for layering scenarios: 0
Yesconvert_json_psd_flagstringWhether 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:

  1. 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_flag to 9 and use the default empty string for business_side_flag.
  2. PPT layering: intended for high-resolution PPT images containing many small icons, thin lines, and similar elements. Set poster_translate_flag to 9 and business_side_flag to design_ppt_layer.
  3. Design Studio non-editable-text version: image layers are transparent, and text is also provided as a transparent-background layer. Set poster_translate_flag to 9 and business_side_flag to text_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.
FieldTypeDescription
request_idstringRequest identifier
trace_idstringTrace identifier
codeintBusiness status code; 0 indicates that the request was accepted successfully
error_codeintError code; 0 on success
messagestringBusiness message
tipsanyAdditional information; may be null
dataobjectTask status and algorithm result

Fields in data:

FieldTypeDescription
statusintStatus code: -1 task not found; 0 created; 1 processing; 2 failed; 9 timed out—use the Query API; 10 succeeded
resultobjectAlgorithm result
progressnumberTask progress
predict_elapsedintEstimated processing time, in milliseconds
create_timeint64Creation timestamp, in milliseconds
task_idstringTask ID
custom_task_idstringClient-defined task ID
trace_idstringTrace identifier
client_infostringClient information
init_imagesobject[]/nullEcho of input media

Fields in data.result:

FieldTypeDescription
idstringUnique task identifier
parametersobjectAlgorithm parameter information. return_json_data contains the JSON result for layering or translation
dataobjectDetailed data returned by the algorithm
msgstringResponse message
msg_idstringMessage ID
mtlab_resobjectUnderlying algorithm result

Fields in data.result.parameters.return_json_data:

FieldTypeDescription
codenumberError code; 0 indicates success
cost_timestringProcessing time, in seconds
error_messagestringError message
json_datastringJSON string containing the layering or translation result, including template configuration, layer information, and text regions

Fields after decoding json_data:

FieldTypeDescription
versionstringTemplate version
namestringTemplate name
templateConfarrayLayer configuration array, including background layers, text layers, and other layers
text_graphic_box_infoarrayText graphic region information
previewstringPreview image URL
widthnumberTemplate width
heightnumberTemplate height
generate_picture_urlstringGenerated image URL; returns the translated image in translation scenarios
image_psd_urlstringPSD 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:

FieldTypeDescription
idstringUnique layer identifier
layerTypestringLayer type, such as bg (background) or text (text)
widthnumberLayer width
heightnumberLayer height
leftnumberX-coordinate of the upper-left corner
topnumberY-coordinate of the upper-left corner
rotatenumberRotation angle
opacitynumberOpacity
hiddenbooleanWhether the layer is hidden
textstringText content (text layers)
ori_rotatenumberOriginal rotation angle
textOristringOriginal text content (preserved after translation)
colorstringText color, such as #040403
fontSizenumberFont size
fontFamilystringFont name
urlstringImage resource URL (for background and other layers)
sub_namestringSublayer name, such as Main_Title, Subtitle, or Horizontal_Text

Fields in data.result.data:

FieldTypeDescription
durationobjectProcessing-time statistics for each stage
error_codenumberAlgorithm error code; 0 indicates success
error_msgstringAlgorithm error message
extraobjectAdditional fields
media_info_listarrayMedia information list
msg_idstringMessage ID
parameterobjectEcho of parameters

Fields in data.result.data.duration:

FieldTypeDescription
alg_process_timenumberAlgorithm processing time, in milliseconds
created_timestampnumberTask creation timestamp, in seconds
pull_timestampnumberResource retrieval timestamp, in seconds
repost_timenumberRetry time
upload_timenumberUpload time, in milliseconds
waiting_timenumberQueue wait time, in milliseconds

Fields in data.result.mtlab_res:

FieldTypeDescription
ErrorCodenumberUnderlying error code
ErrorMsgstringUnderlying error message
error_codenumberError code (compatibility field)
error_msgstringError message (compatibility field)
media_info_listarrayMedia information list
msg_idstringMessage ID
parameterobjectParameter information

Error codes and messages specific to this API:

Error CodeError MessageDescription
20001PROCESS_ERRORProcessing 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);
        }
    }
}