百变滤镜

描述

为图片应用指定滤镜,并可调整滤镜透明度、美颜透明度和虚化程度。使用素材 ID 选择滤镜效果。

版本

1.0

图片要求

支持 JPG、PNG。通过 URL 传入时,不对 URL 进行 Base64 编码。

调用 URL

任务提交接口:

https://openapi.meitu.com/api/v1/sdk/sync/push

任务名称(task):/v1/Image_Filter/496525

任务类型(task_type):formula

调用方法

POST

Content-Type: application/json

权限

使用已开通该能力的 AK/SK,通过签名 SDK 生成请求签名。详见开放平台接口签名。

请求参数

是否必选参数名类型参数说明
是taskstring固定为 /v1/Image_Filter/496525。
是task_typestringformula。
是init_imagesobject[]输入图片列表。
是paramsstring算法参数对象序列化后的 JSON 字符串。
否sync_timeoutinteger同步等待时长,单位为秒,默认值为 30。

init_images 元素

是否必选参数名类型参数说明
是urlstring图片 URL 或 Base64 编码数据,与媒体类型对应。
是profileobject图片属性。

profile

是否必选参数名类型参数说明
是versionstring网关媒体配置版本,固定为 v1。
是media_profilesobject图片传输属性。
否media_extraobject图片附加信息,无需传入时可省略。

media_profiles

是否必选参数名类型参数说明
否media_data_typestringjpg:Base64 编码数据,原算法默认值;url:图片 URL。使用 URL 时显式传入 url。

params

解码后的对象包含以下字段:

是否必选参数名类型参数说明
是parameterobject滤镜参数。
否extraobject额外处理信息,无需传入时可省略。

parameter

是否必选参数名类型参数说明
否filterTypestring滤镜素材 ID,见下方素材表,例如 Fa0145JwLfwjjbch。
否filterAlphainteger滤镜透明度,默认值为 70。原文未说明取值范围。
否beautyAlphainteger美颜透明度,默认值为 0。原文未说明取值范围。
否virtualTypeinteger虚化程度,默认值为 0,取值范围为 0–100,值越大虚化越明显。
否versionstring算法版本,默认值为 1.0。不同于 profile.version。
否rsp_media_typestring原文请求示例使用 url,参数表另列 base64;两者分别表示 URL 和 Base64 返回方式,实际支持情况需以接入结果为准。

原文将 filterType 标为整数、默认值为 0,但实际请求示例和素材表均使用字符串 ID。本文按素材 ID 传字符串;建议显式选择下表中的 ID,不依赖原文含义未明的默认值。

原文的请求表、请求示例和返回示例分别出现 base64、url、jpg,未给出统一说明。本文请求沿用原请求示例的 url,返回示例保留原文的 Base64 结构,二者不是同一次实测调用。

滤镜素材

素材 ID滤镜名称
Fa0145JwLfwjjbch彩铅
Fa0415o4g8OfwAw8Hana
Fa0436P7QKK0zKRL中央公园
Fa0108HAz4MlDLVx优格
Fa0535samdIjz0Wq兰桂坊
Fa0727hdRPZAndOR粉镜

输入值示例

替换图片 URL。示例使用“彩铅”滤镜。

{
  "task": "/v1/Image_Filter/496525",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://example.com/input.jpg",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"parameter\":{\"filterType\":\"Fa0145JwLfwjjbch\",\"filterAlpha\":70,\"beautyAlpha\":0,\"virtualType\":0,\"version\":\"1.0\",\"rsp_media_type\":\"url\"}}",
  "sync_timeout": 30
}

params 解码后的对象:

{
  "parameter": {
    "filterType": "Fa0145JwLfwjjbch",
    "filterAlpha": 70,
    "beautyAlpha": 0,
    "virtualType": 0,
    "version": "1.0",
    "rsp_media_type": "url"
  }
}

返回值说明

以下按统一网关规范说明响应。算法原始结果位于 data.result.data。响应为结构示例,未经真实接口调用验证。

字段类型说明
codeinteger网关业务状态码,0 不代表任务已经完成。
messagestring响应消息。
data.statusinteger-1 未找到任务;0 已创建;1 执行中;2 失败;9 同步等待超时;10 成功。
data.task_idstring网关任务 ID,用于任务查询,不使用算法 msg_id。
data.progressnumber任务进度。
data.resultobject算法结果封装。
data.result.idstring任务 ID。
data.result.codeinteger算法状态码。
data.result.dataobject原始算法响应。

result.data

字段类型说明
media_info_listobject[]处理结果图片列表。
media_info_list[].media_datastring结果图片数据,原文成功示例为 Base64 数据。
media_info_list[].media_profiles.media_data_typestring原文成功示例为 jpg,表示 Base64 数据。
parameterobject返回参数。
parameter.rsp_media_typestring结果媒体类型;原文字段说明为 jpg,成功示例未包含。

返回值示例

以下示例基于统一网关模板和原算法返回资料整理,不是实测返回;请求使用 url,原文返回示例使用 Base64,二者并非同一次调用。结果数据和任务 ID 均为占位值。

请求成功返回示例

{
  "code": 0,
  "message": "success",
  "data": {
    "status": 10,
    "task_id": "example-task-id",
    "result": {
      "id": "example-task-id",
      "code": 0,
      "data": {
        "media_info_list": [
          {
            "media_data": "BASE64_IMAGE_DATA",
            "media_profiles": {
              "media_data_type": "jpg"
            }
          }
        ],
        "parameter": {}
      }
    },
    "progress": 1
  }
}

需要查询返回示例

data.status = 9 表示同步等待超时,不代表任务失败。使用 data.task_id 按任务查询接口继续查询,不要重复提交。

{
  "code": 0,
  "message": "success",
  "data": {
    "status": 9,
    "task_id": "example-task-id",
    "result": {
      "id": "example-task-id"
    },
    "progress": 0
  }
}

请求失败返回示例

以下为 HTTP 400 的处理失败结构示例,不表示所有错误均返回相同状态和错误码。

{
  "code": 20001,
  "error_code": 20001,
  "message": "ALGO_MODEL_CRASH",
  "data": {
    "status": 2,
    "task_id": "example-task-id",
    "result": {
      "id": "example-task-id",
      "code": 20001,
      "msg": "ALGO_MODEL_CRASH",
      "data": {
        "ErrorCode": 20001,
        "ErrorMsg": "process error",
        "Data": null
      }
    }
  }
}

通用的错误代码与信息

本接口原文列出的 20001 / PROCESS_ERROR 表示处理错误。其他错误详见 API 错误码。

SDK 调用示例

以下示例内嵌完整请求体,无需额外 JSON 文件。按对应文档引入签名 SDK 后,替换 AK、SK 和图片 URL。各示例提交一次并打印响应。

Python

Python 签名 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"
    inner_params = {
        "parameter": {
            "filterType": "Fa0145JwLfwjjbch",
            "filterAlpha": 70,
            "beautyAlpha": 0,
            "virtualType": 0,
            "version": "1.0",
            "rsp_media_type": "url"
        }
    }
    payload = {
        "task": "/v1/Image_Filter/496525",
        "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=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 签名 SDK 接入文档

package main

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

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

func main() {
    body := `{
  "task": "/v1/Image_Filter/496525",
  "task_type": "formula",
  "init_images": [
    {
      "url": "https://example.com/input.jpg",
      "profile": {
        "media_profiles": {
          "media_data_type": "url"
        },
        "version": "v1"
      }
    }
  ],
  "params": "{\"parameter\":{\"filterType\":\"Fa0145JwLfwjjbch\",\"filterAlpha\":70,\"beautyAlpha\":0,\"virtualType\":0,\"version\":\"1.0\",\"rsp_media_type\":\"url\"}}",
  "sync_timeout": 30
}`
    url := "https://openapi.meitu.com/api/v1/sdk/sync/push"
    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 签名 SDK 接入文档

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

$innerParams = json_encode([
    'parameter' => [
        'filterType' => 'Fa0145JwLfwjjbch',
        'filterAlpha' => 70,
        'beautyAlpha' => 0,
        'virtualType' => 0,
        'version' => '1.0',
        'rsp_media_type' => 'url'
    ]
], JSON_UNESCAPED_SLASHES);
$body = json_encode([
    'task' => '/v1/Image_Filter/496525',
    '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);
$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 签名 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/Image_Filter/496525\",\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\\\":{\\\"filterType\\\":\\\"Fa0145JwLfwjjbch\\\",\\\"filterAlpha\\\":70,\\\"beautyAlpha\\\":0,\\\"virtualType\\\":0,\\\"version\\\":\\\"1.0\\\",\\\"rsp_media_type\\\":\\\"url\\\"}}\",\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 responseStream = status >= 400
                    ? connection.getErrorStream() : connection.getInputStream();
            if (responseStream != null) {
                try (InputStream input = responseStream;
                     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();
        }
    }
}