밈 생성기 뒤의 기술 아키텍처

발행: (2026년 3월 25일 AM 11:04 GMT+9)
4 분 소요
원문: Dev.to

Source: Dev.to

캔버스 렌더링 파이프라인

핵심적으로, 밈 생성기는 두 레이어 합성 시스템입니다: 배경 이미지와 텍스트 오버레이. HTML5 Canvas API가 필요한 모든 것을 제공합니다.

async function generateMeme(imageUrl, topText, bottomText) {
  const canvas = document.createElement('canvas');
  const ctx = canvas.getContext('2d');

  const img = new Image();
  img.crossOrigin = 'anonymous';

  return new Promise((resolve) => {
    img.onload = () => {
      canvas.width = img.width;
      canvas.height = img.height;

      // Draw background image
      ctx.drawImage(img, 0, 0);

      // Configure text style
      ctx.fillStyle = 'white';
      ctx.strokeStyle = 'black';
      ctx.lineWidth = img.width / 200;
      ctx.textAlign = 'center';
      ctx.font = `bold ${img.width / 12}px Impact`;

      // Top text
      ctx.strokeText(topText, canvas.width / 2, img.width / 8);
      ctx.fillText(topText, canvas.width / 2, img.width / 8);

      // Bottom text
      ctx.strokeText(bottomText, canvas.width / 2, img.height - img.width / 20);
      ctx.fillText(bottomText, canvas.width / 2, img.height - img.width / 20);

      resolve(canvas.toDataURL('image/png'));
    };
    img.src = imageUrl;
  });
}

왜 Impact 폰트가 표준인가

Impact 폰트가 밈 표준이 된 것은 디자인 선택 때문이 아니라 가용성 때문입니다. Windows 98부터 모든 Windows 설치에 기본으로 포함되어 있어 가장 보편적으로 사용할 수 있는 굵고 압축된 산세리프입니다. 두꺼운 획과 촘촘한 간격 덕분에 복잡한 이미지 위에 겹쳐도 작은 크기에서 읽기 쉽습니다.

흰색 텍스트에 검은색 외곽선을 두는 기법은 어떤 배경에서도 가독성을 보장합니다. 외곽선은 strokeText로 먼저 그린 뒤, fillText로 채움을 그립니다. 이 두 단계 방식이 전형적인 밈 텍스트 모양을 만들어냅니다.

캔버스에서 텍스트 줄바꿈

Canvas fillText는 텍스트를 자동으로 줄바꿈하지 않습니다. 텍스트가 이미지보다 넓으면 넘칩니다. 수동으로 단어 줄바꿈을 구현해야 합니다:

function wrapText(ctx, text, maxWidth) {
  const words = text.split(' ');
  const lines = [];
  let currentLine = words[0];

  for (let i = 1; i < words.length; i++) {
    const testLine = currentLine + ' ' + words[i];
    if (ctx.measureText(testLine).width > maxWidth) {
      lines.push(currentLine);
      currentLine = words[i];
    } else {
      currentLine = testLine;
    }
  }
  lines.push(currentLine);
  return lines;
}

measureText 메서드는 현재 폰트 컨텍스트에서 문자열의 픽셀 너비를 반환합니다. 문자 너비가 폰트마다 다르기 때문에 라인 브레이크를 결정할 수 있는 유일하고 신뢰할 수 있는 방법입니다.

동적 폰트 크기 조절

다듬어진 밈 생성기를 위해서는 폰트 크기가 텍스트 길이에 맞게 조절되어야 합니다. 짧은 텍스트는 큰 폰트를, 긴 텍스트는 이미지 안에 맞도록 작은 폰트를 사용합니다.

function fitFontSize(ctx, text, maxWidth, maxSize, minSize) {
  for (let size = maxSize; size >= minSize; size -= 2) {
    ctx.font = `bold ${size}px Impact`;
    if (ctx.measureText(text).width <= maxWidth) {
      return size;
    }
  }
  return minSize;
}

위 코드는 텍스트 줄바꿈, 동적 크기 조절을 처리하고, 앞서 설명한 캔버스 파이프라인을 사용해 깔끔한 PNG를 내보냅니다.

0 조회
Back to Blog

관련 글

더 보기 »

j.s에서 looping이란 무엇인가

JavaScript에서 루프는 같은 코드를 반복해서 작성하지 않고도 동일한 작업을 계속 수행하고 싶을 때 유용합니다. 유형…