← 返回万象 / Back山海万象 · IMAGE API v1

05 · 万象图像模块 / IMAGE MODULE API

给自动化和 AI 用的完整图像 API。

HTTP 在 /api/v1,MCP 在 /api/mcp。浏览器优化台不会调用这些路由;它们是独立的服务器工作流。Agents can send JSON base64 instead of multipart.

GET/api/v1
GET/api/v1/health
GET/api/v1/formats
GET/api/v1/openapi.json
POST/api/v1/inspect
POST/api/v1/optimize
MCP/api/mcp

目录 / Catalog

以 GET /api/v1 发现全部端点、MCP 地址、当前限制与 OpenAPI。无需密钥。Visit the catalog to discover the live contract:

curl https://omniform.shanhai.art/api/v1
curl https://omniform.shanhai.art/api/v1/health
curl https://omniform.shanhai.art/llms.txt
curl https://omniform.shanhai.art/api/v1/openapi.json

OpenAPI 3.1:/api/v1/openapi.json。给模型看的纯文本说明:/llms.txt。GET /inspect 与 GET /optimize 会返回用法说明。

MCP / Agents

Streamable HTTP MCP 挂在 /api/mcp,给 Cursor、Claude Desktop 和其他 MCP 宿主用。工具:get_contract、inspect_image、optimize_image。资源:omniform://contract。无需 OAuth。

{
  "mcpServers": {
    "shanhai-omniform": {
      "url": "https://omniform.shanhai.art/api/mcp"
    }
  }
}

模型更稳妥的 HTTP 写法是 JSON,不要用 multipart:

curl -X POST https://omniform.shanhai.art/api/v1/optimize \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{"image":"<base64>","format":"webp","width":1600}'

试用 / Playground

下面的控制台打到本站 API。图像只在本次请求中驻留内存。The console below calls this origin.

07 / LIVE CONTRACT

在此页直接调用接口

选择一张 JPEG、PNG 或 WebP。检测只读尺寸;优化会返回文件或 JSON。

Loading contract…

尚未选择图像。接口与网页工具分离:这里的请求会到达服务器。

POST /api/v1/optimize

默认返回优化后的图像正文,元数据写在响应头。传 response=json、Accept: application/json,或直接发 JSON 请求,则一次拿到尺寸、节省量与 base64。

imagefile | string

必填之一。multipart 文件,或 JSON 里的 base64 / data URL。Alias: file, image_base64, content, data.

urlstring

JSON/MCP 可选。公开 http(s) JPEG/PNG/WebP。本机与私网地址会被拒绝。

formatstring

auto、original、jpeg、png 或 webp;默认 auto。含透明通道时 auto 在 WebP 与 PNG 中取较小者。

qualityinteger

有损画质 1–100;默认 82。JPEG 在提供 targetBytes 时会搜索画质。

width / heightinteger

输出尺寸 1–20,000。只给一边则按比例计算另一边。

fitstring

contain、cover 或 fill;默认 contain。cover 会先裁切再缩放。

targetBytesinteger

JPEG 搜索不超过该字节数的最接近结果。

autoboolean

省略 format 时设为 false 可保留原格式。

responsestring

image(multipart 默认返回文件)或 json(元数据 + base64)。JSON 请求默认 json。也可发送 Accept: application/json。

metadatastring

兼容字段;编码输出会移除源文件元数据。

POST /api/v1/inspect

验证魔数、解码尺寸、报告透明通道,并按相同的 width / height / fit / format 规则给出计划输出,但不编码。适合在批量任务前做预检。

curl -X POST https://omniform.shanhai.art/api/v1/inspect \
  -F "image=@./photo.jpg" \
  -F "width=1600" \
  -F "fit=contain"

响应 / Response

成功的 optimize 请求返回图像正文(或 JSON),以及这些可检查响应头:

X-Original-Bytes: 4821340
X-Optimized-Bytes: 612804
X-Output-Format: webp
X-Output-Width: 2000
X-Output-Height: 1333
X-Quality: 76

失败一律返回 JSON {"error":"…","code":"unsupported_media"}。常见 code:missing_image、unsupported_media、payload_too_large、dimension_limit、invalid_parameter、rate_limited。

示例 / Examples

curl

curl -X POST https://omniform.shanhai.art/api/v1/optimize \
  -F "image=@./photo.jpg" \
  -F "format=auto" \
  -F "width=2000" \
  -F "quality=82" \
  --output photo-optimized.webp

浏览器 JavaScript

const data = new FormData();
data.append('image', file);
data.append('format', 'webp');
data.append('targetBytes', '500000');

const response = await fetch('/api/v1/optimize', { method: 'POST', body: data });
if (!response.ok) throw new Error((await response.json()).error);
const optimized = await response.blob();

JSON 响应

const data = new FormData();
data.append('image', file);
data.append('format', 'auto');
data.append('response', 'json');
const payload = await (await fetch('/api/v1/optimize', { method: 'POST', body: data })).json();
// payload.content is base64; payload.savedRatio is 0–1.

JSON(给 AI / 脚本)

curl -X POST https://omniform.shanhai.art/api/v1/optimize \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -d '{"image":"<base64>","format":"auto","width":1600}'

Node.js 22+

import { openAsBlob } from 'node:fs';
import { writeFile } from 'node:fs/promises';

const data = new FormData();
data.append('image', await openAsBlob('./photo.jpg'), 'photo.jpg');
data.append('format', 'webp');
const response = await fetch('https://omniform.shanhai.art/api/v1/optimize', { method: 'POST', body: data });
if (!response.ok) throw new Error((await response.json()).error);
await writeFile('./photo-optimized.webp', Buffer.from(await response.arrayBuffer()));

Python

import requests

with open('photo.jpg', 'rb') as image:
    response = requests.post(
        'https://omniform.shanhai.art/api/v1/optimize',
        files={'image': ('photo.jpg', image, 'image/jpeg')},
        data={'format': 'webp', 'width': 1600, 'quality': 82},
    )
response.raise_for_status()
open('photo-optimized.webp', 'wb').write(response.content)

限制与隐私 / Limits & privacy

请求只在处理期间驻留内存,不会保留。默认限制为每文件 25 MB、四千万像素、每运行实例每分钟 30 次;可通过 MAX_API_UPLOAD_BYTES、MAX_API_PIXELS 与 RATE_LIMIT_PER_MINUTE 配置。当前环境的精确值见 GET /api/v1/formats。AVIF 仅用于本地浏览器流程。跨域允许 GET/POST,便于从其他站点调用。

网页工具与 API / Web app vs. API

主优化器始终在本机处理文件,不会调用此接口。HTTP API 是用于自动化的明确服务器工作流,与预览台分离。