Apinoa Docs

이미지 번역

상품 이미지 속 텍스트를 원본 시각 스타일(자형 굵기 · 색상 · 레이아웃 · 배지 배경)을 유지한 채 다른 언어로 치환합니다.

원본 .mdx 보기

엔드포인트

POST /v1/image-translate/translate

상품 이미지를 원시 바이트(raw binary) 로 전송하면, 원본 텍스트가 지워지고 선택한 대상 언어로 치환된 이미지를 반환합니다. 폰트 · 굵기 · 렌더 모드는 호출자가 쿼리 스트링으로 지정합니다.

  • 입력 언어 — 중국어(간체 또는 번체), 일본어, 영어. auto 를 보내면 스크립트 필터를 건너뜁니다.
  • 출력 언어 — ISO-639 형식의 임의 코드. 시각 품질은 선택한 font 가 해당 스크립트의 글리프를 가지고 있는지에 달려 있습니다. 한국어 · 중국어 간체 · 일본어 · 라틴 계열이 1순위 지원이며, 실시간 폰트 · 원본 언어 코드 목록은 /supported-fonts 에서 확인하세요.

요청 형식

엔드포인트는 HTTP body에 원시 이미지 바이트 만 받습니다. JSON + base64는 허용되지 않습니다.

헤더필수비고
Content-Typeimage/jpeg, image/png, image/webp, 또는 application/octet-stream
x-api-keyAPI 키

이외의 모든 파라미터는 쿼리 스트링 으로 전달합니다.

파라미터타입필수기본값설명
source_languagestringch, zh, zh-CN, zh-TW, chinese_cht, ja, japan, en, auto 중 하나. auto 는 스크립트 필터를 끄고 번역이 있는 모든 영역을 렌더합니다.
target_languagestring (2–8자)ISO-639 형식의 대상 언어 코드. 자유 입력.
fontstring아니오Pretendard/supported-fontsallFonts 중 하나. ASCII 외 문자가 포함된 경우 URL 인코딩하세요. 기본값은 Pretendard — 한글, CJK 구두점(×, ( ), 《 》, · 등), Latin Extended-A 까지 모두 커버하는 가변 굵기 한글 산세리프입니다. 렌더러가 내장 fallback chain 을 돌리기 때문에, 선택한 폰트가 갖지 못한 글리프(예: 한자)는 PretendardNotoSansSC 순서로 자동으로 채워집니다.
font_weightstring아니오ExtraBoldauto, Thin, Light, Regular, Medium, SemiBold, Bold, ExtraBold, Black 중 하나.
renderboolean아니오truetrue 는 최종 번역 이미지(바이너리) 반환. false 는 텍스트가 지워진 이미지와 영역별 메타데이터를 JSON 으로 반환합니다.

응답

render=true (기본) — 바이너리 이미지

render=true 일 때 응답 body는 렌더된 JPEG 바이트 이며 Content-Type: image/jpeg 입니다. 메타데이터는 응답 헤더로 전달됩니다.

헤더설명
X-Apinoa-Request-Id요청 ID (이슈 신고 시 인용하세요)
X-Apinoa-Regions-Count감지/치환된 텍스트 영역 수

텍스트가 감지되지 않은 경우 응답 body는 원본 이미지 바이트이고 X-Apinoa-Regions-Count: 0 입니다.

render=false — JSON + 영역 정보

render=false 일 때 응답은 JSON 입니다.

{
  "success": true,
  "requestId": "550e8400e29b41d4a716446655440000",
  "data": {
    "inpainted_base64": "<텍스트 제거된 이미지의 base64 JPEG>",
    "regions": [
      {
        "polygon": [[10, 20], [210, 20], [210, 60], [10, 60]],
        "bbox": { "x": 10, "y": 20, "w": 200, "h": 40 },
        "text": "免费送货",
        "text_kr": "무료 배송",
        "confidence": 0.98,
        "text_color": { "r": 255, "g": 255, "b": 255 },
        "bg_color": { "r": 200, "g": 50, "b": 50 },
        "font_weight": "Bold",
        "is_badge": true
      }
    ],
    "regions_count": 5
  }
}
필드타입설명
inpainted_base64string원본 텍스트가 제거된 base64 JPEG
regions[].polygonnumber[][]원본 좌표계의 4점 폴리곤
regions[].bboxobject원본 좌표계의 축정렬 경계 박스
regions[].textstring인식된 원문
regions[].text_krstring요청한 target_language 의 번역문.
regions[].confidencenumber인식 신뢰도, 0–1
regions[].text_color / bg_colorobjectRGB 색상 추정
regions[].font_weightstring감지된 굵기: Thin, Regular, Bold
regions[].is_badgeboolean가격표 · 세일 배지 같은 채워진 사각 라벨이면 true

예제

기본 번역 (cURL)

curl -X POST "https://gateway.apinoa.com/v1/image-translate/translate?source_language=zh-CN&target_language=ko" \
  -H "x-api-key: $APINOA_API_KEY" \
  -H "Content-Type: image/jpeg" \
  --data-binary @product.jpg \
  -o translated.jpg

폰트 지정 (Python)

import requests

with open("product.jpg", "rb") as f:
    img_bytes = f.read()

r = requests.post(
    "https://gateway.apinoa.com/v1/image-translate/translate",
    headers={
        "x-api-key": "YOUR_API_KEY",
        "Content-Type": "image/jpeg",
    },
    params={
        "source_language": "zh-CN",
        "target_language": "ko",
        "font": "Pretendard",
        "font_weight": "Bold",
    },
    data=img_bytes,
    timeout=300,  # 서버 타임아웃은 5분 — 아래 "타임아웃" 섹션 참고
)
r.raise_for_status()
with open("translated.jpg", "wb") as f:
    f.write(r.content)
print("regions:", r.headers.get("X-Apinoa-Regions-Count"))

인페인트만 받아 클라이언트에서 렌더 (Node.js / TypeScript)

import { readFileSync, writeFileSync } from "node:fs";

const image = readFileSync("product.jpg");

const url = new URL("https://gateway.apinoa.com/v1/image-translate/translate");
url.searchParams.set("source_language", "zh-CN");
url.searchParams.set("target_language", "ko");
url.searchParams.set("render", "false");

const res = await fetch(url, {
  method: "POST",
  headers: {
    "x-api-key": process.env.APINOA_API_KEY!,
    "Content-Type": "image/jpeg",
  },
  body: image,
});

const { data } = (await res.json()) as {
  data: { inpainted_base64: string; regions: any[] };
};
writeFileSync("inpainted.jpg", Buffer.from(data.inpainted_base64, "base64"));

제한

항목
최대 이미지 크기8192 × 8192 px
최대 요청 본문20 MB
API 키별 QPS플랜의 초당 한도와 동일
이미지 포맷JPEG, PNG, WebP

크기 초과 이미지는 413 Payload Too Large 를, QPS 초과는 retry-after 가 포함된 429 Too Many Requests 를 반환합니다.

오류

코드HTTP발생 조건대응
BAD_REQUEST400빈 본문 또는 잘못된 쿼리 파라미터요청 형식을 점검
UNAUTHORIZED401API 키 누락 또는 무효x-api-key 헤더 확인
UNSUPPORTED_MEDIA_TYPE415Content-Type 이 바이너리 이미지 형식이 아님Content-Type: image/jpeg (또는 png/webp) 로 원시 바이트 전송
PAYLOAD_TOO_LARGE413본문 > 20 MB클라이언트에서 다운스케일
INSUFFICIENT_BALANCE402잔액이 호출 비용에 못 미침대시보드 > 잔액에서 충전; 재시도로는 해결되지 않음
UPSTREAM_ERROR502처리 일시 불가재시도; 보통 60초 이내 회복
SERVICE_UNAVAILABLE503일시적 용량 초과백오프 후 재시도

타임아웃

부하가 높을 때는 요청 하나가 최대 5분(300초) 까지 걸릴 수 있습니다. 느린 응답이 클라이언트 측에서 중단되지 않도록 HTTP 클라이언트의 타임아웃을 최소 300초 이상으로 설정하세요.

지연일반적최악
일반 부하1.5 – 3 s< 10 s
높은 부하5 – 30 s5 분

대부분의 요청은 수 초 이내에 완료됩니다. 5분 한도는 지속적인 버스트 트래픽 환경에서만 의미가 있습니다. 5분 한도에 자주 근접한다면 동시성을 낮추거나 지원팀에 문의하세요.

가격

각 호출은 요금 페이지에 안내된 image-translate 단가로 잔액에서 차감됩니다.

지원

5xx 오류가 반복되거나 품질 회귀가 명확히 보이면 X-Apinoa-Request-Id 응답 헤더의 값을 첨부해 apinoa.com/contact 에서 문의하세요.

이 페이지 내용