🏝️ Hwani Studio

Home › Guides › 1인 메이커 개발 노트

서버 없이 브라우저에서 인쇄용 PDF 만들기: pocaprint를 만들며 정한 것들

2026-10-18 · Hwani Studio

pocaprint는 사용자가 올린 이미지로 포토카드 인쇄 시트를 PDF로 만들어 주는 도구입니다. 만들 때 가장 먼저 정한 원칙은 이미지를 서버로 보내지 않는다였습니다. 개인 사진을 받는 순간 저장, 삭제, 유출 책임이 생기고 서버 비용도 듭니다. 브라우저 안에서 모든 것을 처리하면 이런 문제가 사라집니다. 이 글은 그 구조를 정리합니다.

구성

단위는 mm로 통일

인쇄물은 픽셀이 아니라 길이로 생각해야 합니다. 그래서 모든 배치 계산을 mm로 합니다. 카드는 55×85mm, 블리드 3mm, 칸은 61×91mm, 종이 가장자리 최소 여백은 10mm입니다. jsPDF도 문서를 mm 단위로 만들 수 있어서, 계산한 숫자를 그대로 좌표로 씁니다. 용지별로 세로·가로 두 방향의 칸 수를 계산해 더 많이 들어가는 쪽을 고르고, 카드 묶음을 가운데에 놓습니다. 계산 과정은 A4와 Letter 비교 글에 자세히 있습니다.

미리보기와 PDF가 같은 코드로 그린다

미리보기는 화면 캔버스에, 최종 결과는 PDF에 그립니다. 두 곳의 그리기 코드가 따로 있으면 언젠가 결과가 어긋납니다. 그래서 페이지 하나를 그리는 함수는 "그리는 도구(painter)"만 받도록 만들었습니다. 같은 함수에 캔버스용 painter를 넘기면 미리보기가, PDF용 painter를 넘기면 PDF가 됩니다. painter는 배경, 이미지, 사각형, 둥근 사각형, 선, 글자 같은 몇 가지 동작만 구현하면 됩니다.

이미지는 300dpi로 다시 그려서 넣는다

원본 이미지를 PDF에 그대로 넣으면 두 가지 문제가 생깁니다. 4000px짜리 사진 9장이면 PDF가 지나치게 커지고, 크롭과 확대를 PDF 좌표로 표현하기 번거롭습니다. 그래서 칸마다 캔버스를 하나 만들어 61×91mm를 300dpi로 환산한 약 720×1075px 크기로 잘라 그린 다음, 그 결과를 JPEG로 PDF에 넣습니다. 크기는 일정해지고, 화면에서 본 크롭이 그대로 반영됩니다.

크롭: cover + 위치 + 확대

칸 비율과 원본 비율이 다르면 빈 공간이 생기지 않도록 더 긴 쪽을 잘라 냅니다(CSS의 object-fit: cover와 같은 개념). 여기에 0~1 범위의 가로·세로 위치 값과 1 이상의 확대 값을 더해, 사용자가 드래그와 슬라이더로 남길 부분을 고르게 했습니다. 확대할수록 원본에서 쓰는 영역이 줄어드는 점은 해상도 글에서 설명했습니다.

인쇄를 위한 장치

검증

사람 눈으로만 확인하면 1mm 오차를 놓칩니다. 그래서 테스트 스크립트가 브라우저를 자동으로 띄워 PDF를 내려받고, 별도 스크립트가 PDF의 페이지 크기와 이미지 위치를 읽어 계산값과 비교하게 했습니다. 정적 도구라도 이런 자동 검증 하나가 있으면 고칠 때 마음이 편합니다.

남은 과제

브라우저 안 처리의 한계는 메모리입니다. 아주 큰 이미지를 수십 장 넣으면 휴대폰에서는 느려질 수 있습니다. 이미지를 읽을 때 미리 줄여 두는 방식으로 개선할 여지가 있습니다.