Cloudflare Images로 사진에 글씨 넣기: Worker 텍스트 오버레이

Cloudflare Images와 Workers로 사진에 글씨 넣기를 구현하는 방법을 알아봅니다. .text(), .draw(), .output() 사용법부터 폰트 제한, 레이어 합성, 캐시, 고유 변환 과금 기준과 실전 자동화 사례까지 정리했습니다.

Monday, September 7, 2026Omid Saffari
Cloudflare Images로 사진에 글씨 넣기: Worker 텍스트 오버레이

Cloudflare Worker 안에서 제품 사진 한 장과 실시간 문자열 하나만으로 완성된 소셜 카드를 만들 수 있습니다. 새로 추가된 .text() 소스는 래스터 텍스트 레이어를 만들고, .draw()는 이를 이미지에 배치하며, .output()은 최종 파일을 반환합니다. 이제 고정 레이아웃 게시 워크플로 하나로 크기 조정, 사진에 글씨 넣기, 인코딩, 에셋 제공까지 이어서 처리할 수 있습니다. 브라우저 렌더러나 두 번째 이미지 API로 작업을 넘길 필요도 없습니다.

사진에 글씨 넣기: 가장 짧은 Cloudflare Images 파이프라인

먼저 언제나 같은 결과를 내는 레이아웃 하나부터 만듭니다. 이 예제는 1200 by 630 제품 카드를 만들고, ?text=에서 헤드라인을 가져오며, 고정된 브랜드 폰트를 사용해 WebP로 반환합니다. example.com으로 된 에셋 URL 두 개는 직접 관리하는 URL로 바꾸십시오.

Wrangler 설정에 Images 바인딩을 추가하고 Workers Cache를 활성화합니다.

Jsonc
{
  "images": {
    "binding": "IMAGES"
  },
  "cache": {
    "enabled": true
  }
}

그다음 Worker에서 바인딩을 사용합니다.

JavaScript
const CARD_IMAGE = "https://assets.example.com/product-card.jpg";
const BRAND_FONT = "https://assets.example.com/fonts/Brand-Bold.woff2";

export default {
  async fetch(request, env) {
    const url = new URL(request.url);
    const headline = (url.searchParams.get("text") || "AUTUMN DROP").trim();

    // This is a layout limit for this card, not Cloudflare's 1,000-character ceiling.
    if (!headline || [...headline].length > 120) {
      return new Response("Text must contain 1 to 120 characters", { status: 400 });
    }

    const source = await fetch(CARD_IMAGE);
    if (!source.ok || !source.body) {
      return new Response("Source image unavailable", { status: 502 });
    }

    const textLayer = env.IMAGES.text(headline, {
      font: { url: BRAND_FONT },
      size: 72,
      color: "#FFFFFF"
    });

    const result = await env.IMAGES
      .input(source.body)
      .transform({ width: 1200, height: 630, fit: "cover" })
      .draw(textLayer, { left: 72, bottom: 72 })
      .output({ format: "image/webp" });

    return result.response({
      headers: {
        "Cache-Control": "public, max-age=86400, stale-while-revalidate=604800"
      }
    });
  }
};

/card?text=Autumn%20Drop을 요청하면 전달한 문구가 왼쪽과 아래쪽 가장자리에서 각각 72픽셀 떨어진 1200 by 630 WebP가 반환됩니다. 바뀌는 텍스트가 이미지 URL에 들어가므로 이 예제에서는 캡션마다 자연스럽게 별도 URL이 생깁니다. 운영 환경에서는 가능하면 변경되지 않는 캠페인 ID나 제품 ID를 사용하십시오. 공개 쿼리 문자열에 자유 형식 텍스트를 허용하면 변형 수가 무한히 늘어날 수 있어 비용과 악용 위험이 모두 커집니다.

원본 이미지와 폰트를 가져오는 출처는 고정하거나 허용 목록으로 제한해야 합니다. 이 예제는 방문자가 임의의 가져오기 대상을 선택하지 못하게 합니다. 공개 Worker가 원격 에셋을 가져올 수 있다면 반드시 지켜야 할 경계입니다.

Cloudflare 내부에서는 실제로 무엇을 처리할까?

텍스트 래스터화는 글자를 픽셀로 바꾸는 과정입니다. .text()를 투명 스티커를 인쇄하는 작은 조판기로 생각하면 쉽습니다. .draw()가 그 스티커를 사진 위에 올리고, .output()이 둘을 하나의 최종 파일로 굳힙니다.

이 관점으로 보면 API 구조도 명확해집니다. 텍스트는 브라우저에서 이미지 위에 떠 있는 HTML 요소가 아닙니다. 렌더링이 끝나면 이미지 픽셀의 일부가 됩니다.

제어 항목입력값현재 제한
content렌더링할 문자열필수, 최대 1,000자
fontTTF, OTF, WOFF 또는 WOFF2 파일의 URL폰트 파일은 최대 20 MB, 가져오기 또는 파싱 실패 시 오류 반환
size픽셀 단위 폰트 크기기본값은 12, Cloudflare가 별도의 최솟값이나 최댓값을 공개하지 않음
colorHEX, CSS 색상 이름 또는 CSS 색상 함수기본값은 검은색
텍스트 이미지래스터화된 텍스트 레이어최대 4096 by 4096픽셀
기본 입력원시 이미지 바이트.input()을 통해 최대 20 MB

기본 이미지가 최종 캔버스 크기를 결정합니다. 텍스트 위치는 top, left, bottom, right의 픽셀 오프셋으로 지정합니다. 위치를 지정하지 않으면 가운데에 놓입니다. 같은 오버레이에 leftright를 동시에 쓰거나 topbottom을 동시에 쓸 수는 없습니다. 불투명도 범위는 0부터 1까지이며, 기본 합성 모드는 over입니다.

.draw() 호출은 여러 번 연결할 수 있습니다. 호출 순서가 곧 레이어 순서이므로 마지막으로 그린 항목이 맨 위에 놓입니다. Cloudflare는 text 항목을 URL 기반 변환용 cf.image.draw 배열에도 추가했습니다. 다만 기본 이미지가 R2, Cloudflare Images, 요청 본문 또는 다른 fetch에서 원시 바이트로 들어온다면 바인딩 방식이 더 잘 맞습니다.

빠져 있는 핵심은 레이아웃 판단 기능입니다. 현재 Cloudflare가 텍스트 스타일로 문서화한 항목은 font, size, color입니다. 텍스트 상자, 줄바꿈, 자동 맞춤, 줄 높이, 자간, 정렬, 외곽선, 그림자, 폰트 폴백은 문서에 없습니다. 줄을 어디서 바꿀지, 안전 영역을 어떻게 잡을지, 제품명이 너무 길 때 어떻게 처리할지는 애플리케이션이 결정해야 합니다.

원본이 아니라 완성된 카드를 캐시해야 하는 이유

Images 바인딩 응답은 자동으로 캐시되지 않습니다. Workers Cache가 없으면 같은 요청이 반복될 때마다 Worker가 실행되고 원본 디코딩과 인코딩도 다시 수행됩니다. 캐시를 활성화하고 Cache-Control을 설정하면 Cloudflare가 이 작업을 반복하지 않고 완성된 응답을 제공할 수 있습니다.

캐싱과 Images 과금은 서로 다른 문제를 해결합니다. Cloudflare는 바인딩 사용량을 고유 변환 기준으로 청구합니다. 원본 이미지와 매개변수의 고유 조합 하나는 한 달에 한 번만 집계되며, 같은 달에 동일한 변환이 반복되어도 Images 사용량이 추가되지 않습니다. 그래도 캐시 적중은 Worker 재실행과 이미지 처리 지연을 피할 수 있으므로 중요합니다.

Cloudflare는 고유성 계산에서 텍스트 문자열을 어떻게 정규화하는지 별도로 설명하지 않습니다. 자체 사용 데이터로 달리 확인하기 전까지는 기본 이미지, 캡션, 스타일, 출력의 조합이 하나라도 다르면 새로운 변환으로 보는 편이 안전합니다. 제품 2,000개에 카드 크기 다섯 가지를 쓰는 카탈로그라면 각 카드가 수천 번 조회되더라도 변형 수는 10,000개처럼 집계될 수 있습니다.

레이아웃을 이미 보유했다면 달라지는 비용 계산

Cloudflare Images Free에는 매달 고유 변환 5,000개가 포함됩니다. 유료 플랜에서도 첫 5,000개는 포함되며, 이후에는 1,000개당 $0.50가 부과됩니다. Cloudflare가 직접 제시한 고유 변환 10,000개 예시에서 한 달 Images 변환 비용은 $2.50입니다.

Bannerbear의 현재 요금표는 API 크레딧 1,000개를 제공하는 Automate 플랜을 월 $49, 10,000개를 제공하는 Scale 플랜을 월 $149로 안내합니다. 일반 이미지 렌더링 한 번에는 크레딧 하나가 들며, 추가 포맷, 배율 또는 AI 레이어에 따른 배수 비용은 별도입니다.

$146.50의 차액이 곧바로 손에 들어오는 절감액은 아닙니다. Bannerbear는 템플릿 편집기, 연동 기능, 팀 워크플로를 갖춘 완성형 디자인 제품을 판매합니다. Cloudflare가 제공하는 것은 렌더링 기본 요소이므로 직접 설계하고 코딩하며 검증, 모니터링, 유지보수해야 합니다. Images 변환 요금 외에 원본 저장 비용과 개발 시간도 들 수 있고, Cloudflare Images 내부 저장 공간에는 별도 요금이 있습니다.

그래도 선택 기준은 분명합니다. 팀이 이미 디자인 규칙을 보유하고 있고 이미지 요청도 Cloudflare에서 실행된다면 별도의 렌더링 구독은 선택 사항이 될 수 있습니다. 반대로 마케터가 매주 레이어를 눈으로 보며 옮겨야 한다면, 구독료는 비싼 픽셀 처리비가 아니라 편집기와 운영 체계에 지불하는 비용입니다.

효과가 큰 일곱 가지 워크플로 순위

1. 카탈로그 상품 카드

수백 개 SKU를 다루는 소매업체라면 승인된 배경 레이아웃 하나를 유지하면서 현재 제품명, 가격, 재고 안내 또는 프로모션을 각 카드에 그려 넣을 수 있습니다. 재고나 캠페인 데이터가 Worker를 실행하면 완성된 마켓플레이스 또는 소셜 에셋이 반환됩니다. 가격이 바뀌어도 수동 내보내기 작업이 쌓이지 않고, 원본 사진을 건드리지 않은 채 같은 승인 레이아웃을 다시 만들 수 있어 효과적입니다.

가장 잘 맞는 것은 길이가 제한된 문구입니다. 제품명 두 줄과 가격 배지 하나는 예측할 수 있지만, 프로모션 문단 전체는 그렇지 않습니다.

2. 퍼블리셔 및 CMS 소셜 카드

매체는 글이 게시될 때 헤드라인이나 변경되지 않는 글 ID를 전달해 엔드포인트 하나를 호출할 수 있습니다. Worker가 대표 이미지를 가져와 제목을 렌더링하고 Open Graph 또는 소셜 카드를 반환합니다. 게시 과정에서 스크린샷 브라우저를 기다릴 필요가 없고, 누락되거나 오래된 공유 이미지도 줄어듭니다.

CMS가 이미 Cloudflare 뒤에서 실행 중이라면 특히 매력적입니다. 이미지를 제공하는 동일한 엣지 계층에서 생성하고, 완성된 URL을 캐시해 반복 공유에 활용할 수 있습니다.

3. 마켓플레이스 상태 이미지

마켓플레이스는 상품 카드에 NEW, RESERVED, SOLD 같은 상태와 상품 컨디션 또는 위치를 표시할 수 있습니다. 상품 등록 서비스가 짧은 텍스트 값만 바꾸면 이미지 엔드포인트가 새로운 시각적 상태를 만듭니다. 판매자는 원본 사진을 편집할 필요가 없고, 구매자는 카드가 어디에 삽입되든 이미지 안에서 상태를 확인할 수 있습니다.

사업적 효과는 정확성에서 나옵니다. 오래된 상태 카드는 고객 지원 업무와 실망스러운 클릭을 만듭니다. 결정론적 오버레이는 레코드와 함께 바뀔 수 있습니다.

4. 프랜차이즈 및 지역별 프로모션 소재

레스토랑이나 서비스 프랜차이즈는 브랜드 구성을 고정한 채 지역별 도시, 혜택, 날짜 또는 가격만 바꿀 수 있습니다. 캠페인 정의 하나로 여러 지역 버전을 만드는 방식입니다. 반복 제작 작업을 줄이는 동시에 폰트, 색상, 배치처럼 실수 위험이 큰 요소는 지역 운영자가 건드리지 못하게 할 수 있습니다.

긴 지명이 함정입니다. 안전하게 자동화하려면 측정된 텍스트 너비, 대체 크기 또는 사전 승인된 약칭이 필요합니다.

5. 이벤트 및 일정 카드

이벤트 플랫폼은 고정 포스터 위에 연사 이름, 세션 시간, 방 번호 또는 막판의 CANCELLED 상태를 렌더링할 수 있습니다. 원본 일정은 기준 레코드로 유지하고, 카드 생성은 출력 단계로 처리합니다. 행사 직전에 세부 정보가 바뀌어도 디자이너에게 수십 개 파일을 다시 열어 달라고 요청할 필요 없이 빠르게 반영할 수 있습니다.

6. 고객 보고서 스냅샷

보고서 제품은 이메일이나 메시지로 보낼 브랜드 차트 이미지에 기간, 고객명, 핵심 지표를 넣을 수 있습니다. Worker는 이미 렌더링된 차트를 기본 이미지로 받아 달라지는 라벨 몇 개만 추가한 뒤 작은 최종 포맷으로 반환합니다. 대상 환경에서 대시보드 자체를 실행할 수 없을 때 유용합니다.

텍스트 레이어로 대시보드 전체를 그리려 해서는 안 됩니다. 마지막에 정해진 라벨을 붙이는 단계로 쓸 때 가장 강력합니다.

7. 내부 운영 라벨

창고, 현장 서비스팀 또는 콘텐츠 검토 대기열에서는 검사 상태, 배치, 경로, 검토 결과 같은 짧은 상태 텍스트를 항목 사진에 렌더링할 수 있습니다. 주변 메타데이터를 제거하는 시스템을 거쳐도 시각 정보는 잘 전달됩니다. 맥락 없이 이미지만 받은 사람이 별도로 조회하는 수고를 줄일 수 있습니다.

이는 운영 편의를 위한 기능이지 원본 레코드를 대신하지 않습니다. 상태는 데이터베이스에 유지하고 이미지는 하나의 보기로 취급해야 합니다.

구축해 볼 만한 제품 세 가지

최우선 기회: 업종 특화 소셜 카드 엔드포인트

고정 레이아웃을 이미 보유했지만 브라우저 렌더링 스택까지 운영하고 싶지는 않은 퍼블리셔, 에이전시, 다지점 사업자를 위한 브랜드 안전 소셜 카드 서비스를 만들 수 있습니다. 구매자가 대표 이미지와 승인된 문구 필드를 전달하면, 서비스는 소수의 화면 비율에 맞춘 고정 URL을 반환합니다.

미국 키워드 데이터에서 social media post maker의 월간 검색량은 480회, 클릭당 비용은 $19.95로 추정됩니다. 정확한 문구의 범위가 API 구매자보다 넓기는 하지만, 이례적으로 높은 CPC는 공급업체들이 이 제작 업무를 놓고 경쟁한다는 뜻입니다. Bannerbear의 월 $49 및 $149 요금제는 자동 렌더링에 이미 비용을 지불하는 팀의 현재 예산 기준을 보여 줍니다.

판매 가능한 최소 버전에는 Worker 하나, 고정 카드 레이아웃 세 개, 관리자 미리보기, CMS 웹훅, 엄격한 원본 허용 목록, 안정적인 캐시 키, 텍스트가 맞지 않을 때 보낼 실패 대기열이 필요합니다. 단순한 .text() 호출이 아니라 게시 연동의 안정성을 판매해야 합니다.

문제는 템플릿 소유권입니다. Cloudflare는 고객용 시각 편집기를 제공하지 않으며, 새 레이아웃이 추가될 때마다 별도의 서비스 작업이 생길 수 있습니다. 그럼에도 가장 강력한 기회인 이유는 새 기본 요소가 반복적이고 상업 가치가 높은 워크플로에서 렌더러를 제거하면서, 연동과 브랜드 관리라는 제품 가치는 그대로 남기기 때문입니다.

카탈로그 프로모션 라벨 엔진

이커머스 팀이 제품 이미지에 가격, 할인 상태, 배송 약속 또는 컬렉션 이름을 추가할 수 있는 피드 기반 합성기를 만들 수 있습니다. CSV, PIM 또는 커머스 웹훅이 데이터를 업데이트하면 서비스는 변경된 변형만 다시 생성합니다.

Product label maker는 미국에서 월간 검색량이 320회로 추정되고 상업적 의도가 있으며, 광고주 경쟁도와 함께 CPC $6.03를 기록합니다. 라벨 제작에 유료 수요가 있다는 근거지만, 이 검색어에는 카탈로그 그래픽보다 인쇄용 라벨을 찾는 수요가 많이 섞여 있습니다.

MVP에는 제품 피드 커넥터, 고정 배지 몇 개, 화면 비율 프리셋, 미리보기, 긴 이름과 누락된 가격을 처리할 규칙이 필요합니다. 문제는 범위입니다. 실물 패키징에는 인쇄 해상도, 재단 여백, 바코드, 규제 검토가 따라오며, 이 래스터 오버레이만으로는 해결할 수 없습니다. 이런 시스템까지 제품에 포함하지 않는다면 프로모션 이미지 라벨에 집중해야 합니다.

제품에 삽입하는 텍스트 추가 도구

기존 크리에이터, 마켓플레이스 또는 커뮤니티 제품에 넣을 작은 편집기 컴포넌트를 만들 수 있습니다. 이미지를 고르고, 짧은 텍스트를 입력하고, 승인된 폰트와 색상 중에서 선택해 안전 영역 안에 배치한 뒤 내보내는 방식입니다. Cloudflare는 해당 제품의 자체 인터페이스 뒤에서 최종 래스터화를 처리합니다.

Add text to image의 미국 월간 검색량은 6,600회로 추정됩니다. 거래 의도가 더 강한 add text to image app은 약 320회이며, 같은 데이터 세트에서 전년 대비 23% 증가했습니다. 수요는 분명하지만, 상당수는 무료 범용 편집기를 기대합니다.

MVP는 제한된 미리보기, 텍스트 프리셋 네 개에서 여섯 개, 내보내기 엔드포인트 하나, 완성된 URL을 위한 저장 공간으로 구성할 수 있습니다. 문제는 낮은 방어력입니다. 독립형 범용 도구는 이미 성숙한 무료 편집기와 경쟁해야 합니다. 이미지, 사용자, 게시 대상까지 이미 확보한 제품의 유료 기능으로 넣는 편이 더 타당합니다.

Cloudflare Images가 맞지 않는 경우

Cloudflare Images는 텍스트를 렌더링하고 합성할 수 있습니다. 그러나 어떤 문구를 쓸지 결정하거나, 타이포그래피를 반응형으로 만들거나, 브랜드 레이아웃을 승인하거나, 마케터용 템플릿 편집기를 제공하지는 않습니다. 이런 부분이 더 어려운 과제라면 완성형 디자인 자동화 제품이 직접 유지보수하는 것보다 여전히 저렴할 수 있습니다. 브랜드 시스템 전체를 바꾸는 사례가 궁금하다면 Canva AI 2.0 브랜드 리프레시 테스트를 참고하십시오.

실무에서 중단을 고려해야 할 신호는 다섯 가지입니다.

  • 문구에 정교한 줄바꿈, 자동 맞춤, 리치 텍스트 또는 선택한 폰트로 테스트하지 않은 문자 체계별 조형이 필요합니다.
  • 편집자가 개발자 없이 레이어를 시각적으로 옮기고 새 템플릿을 게시해야 합니다.
  • 공개 엔드포인트가 허용 목록 없이 임의의 원본 URL이나 폰트 URL을 받게 됩니다.
  • 변형 생성을 제한할 수 없어 무작위 쿼리 문자열이 Free의 변환 5,000개 허용량을 소진하고 새 요청이 오류 9422로 실패할 수 있습니다.
  • 로컬 테스트가 텍스트 렌더링에 의존합니다. 저정밀 로컬 Images 구현은 너비, 높이, 회전, 포맷만 지원하므로 이 기능은 npx wrangler dev --remote로 테스트하십시오.

폰트와 텍스트 제한은 엄격한 경계입니다. 사용자 지정 폰트는 20 MB 이하여야 하고, 렌더링할 콘텐츠는 1,000자를 넘을 수 없으며, 래스터 레이어는 4096 by 4096픽셀 이하여야 합니다. 라벨과 헤드라인에는 넉넉한 한도지만, 이미지 API를 페이지 레이아웃 엔진처럼 사용해도 된다는 뜻은 아닙니다.

텍스트 오버레이가 있는 이미지는 어떻게 만들 수 있나요?

env.IMAGES.input(imageBytes)로 기본 핸들을 만들고, env.IMAGES.text(content, { font, size, color })로 텍스트 레이어를 생성한 뒤, 그 레이어를 .draw()에 전달하고 .output({ format })으로 마무리합니다. 출력 크기는 기본 이미지가 결정합니다.

이미지 위에 오버레이를 추가하려면 어떻게 하나요?

Images 바인딩에서는 이미지 핸들이나 .text() 핸들을 .draw(overlay, options)에 전달합니다. 픽셀 오프셋은 top, left, bottom, right로 지정하고, 오버레이를 반투명하게 만들 때는 opacity를 사용합니다. 레이어를 더 추가하려면 .draw() 호출을 이어 붙이십시오. 마지막으로 그린 항목이 맨 위에 놓입니다.

텍스트 오버레이는 어떻게 구현하나요?

원시 이미지 바이트에는 위의 Images 바인딩 워크플로를 사용합니다. URL 기반 fetch() 변환이라면 text 항목을 cf.image.draw 배열에 추가하고 동일한 font, size, color 옵션을 지정합니다. 원본이 R2, Cloudflare Images, 요청 본문 또는 다른 fetch 응답에 있을 때는 대체로 바인딩 방식이 더 깔끔합니다.

이미지 속 피사체 뒤에 텍스트를 넣으려면 어떻게 하나요?

이 텍스트 기능에는 자동 피사체 분리나 간단한 behind 스위치가 문서화되어 있지 않습니다. 어떤 오버레이가 위에 놓일지는 그리는 순서로 정하고, 픽셀이 합쳐지는 방식은 합성 모드로 제어합니다. 사람이나 제품 뒤에 텍스트를 배치하려면 별도로 피사체 마스크나 전경 레이어를 준비해 텍스트 다음에 그려야 합니다.

사진 속 텍스트에 애니메이션을 적용하려면 어떻게 하나요?

이번 릴리스에 문서화된 것은 래스터 텍스트와 이미지 합성이며, 텍스트 타임라인이나 애니메이션 시스템은 아닙니다. 글자가 움직여야 한다면 비디오 또는 애니메이션 렌더러를 사용하십시오. 애니메이션 입력이 보존된다고 해서 움직이는 타이포그래피 제어 기능까지 제공된다고 가정해서는 안 됩니다.

자체 카탈로그나 게시 시스템을 기반으로 신뢰할 수 있는 이미지 엔드포인트가 필요하다면 AI 프로덕션 시스템부터 시작하는 것이 좋습니다.

마지막 업데이트

2026년 9월 7일

카테고리Design

Google에서 이 사이트를 우선하기

Google 검색에서 omidsaffari.com을 선호 소스로 추가

omidsaffari.com을 선호 소스로 지정하면 Google이 Top Stories, AI Overviews, AI Mode에서 우선적으로 보여 줍니다.

Design의 다른 글

Design 글 전체 보기
뉴스레터

매주 일요일, 한 통의 편지. 뜨거운 의견이 아닌, 돌아가는 시스템.

AI 벤처 포트폴리오 운영에서 나오는 빌드 로그, 가동 중인 시스템, 현장 노트.

주간 발행. 스팸 없음. 언제든 해지 가능합니다.