PDF 어노테이션 → AcroForm 변환기
스캔된 PDF엔 입력란이 없다. 그 위에 칸을 직접 그려 위치만 넘기면, 채울 수 있는 양식으로 구워진다. 좌표가 오가는 과정을 그대로 옮겨 봤다.
POST payload · bbox_norm
{
"fields": [
{
"field_name": "text_0",
"field_type": "text",
"bbox_norm": {
"x0": 0.12,
"y0": 0.16,
"x1": 0.62,
"y1": 0.24
}
},
{
"field_name": "checkbox_1",
"field_type": "checkbox",
"bbox_norm": {
"x0": 0.12,
"y0": 0.42,
"x1": 0.18,
"y1": 0.48
}
}
]
}병원 사전승인 양식은 대부분 그냥 스캔한 PDF였다. 입력란이 없으니 출력해서 손으로 적는 수밖에 없다. 자동으로 채우려면 “여기에 이런 칸이 있다”는 걸 먼저 알려줘야 한다. 그래서 사람이나 AI가 그 자리를 오버레이로 찍어 주면, 백엔드가 실제로 입력 가능한 양식으로 바꿔 준다.
처음엔 화면 픽셀 좌표를 그대로 보냈다. 그런데 화면 크기나 DPI가 달라지면 칸이 어긋났다. 그래서 모든 박스를 페이지 대비 0~1 비율(bbox_norm)로 저장하기로 했다. 오른쪽 payload가 드래그할 때마다 바뀌는데, 이 값이면 어떤 해상도에서도 같은 자리에 다시 그릴 수 있다. 화면 좌표와 정규화 좌표 사이에 경계를 둔 게 이 데모의 핵심이다.
렌더링, 필드 파싱, 드래그 오버레이, 변환을 각각 따로 떼어 놨다. UI는 화면 좌표로 움직이고 API는 정규화 좌표로만 말하게 해서, 한쪽을 손봐도 다른 쪽이 휘청이지 않는다. 이 층들을 눈으로 펼쳐 본 게 옆에 있는 “레이어드 아키텍처 익스플로러” 포스트다.
여기선 진짜 pdfjs나 pdf-lib, 백엔드 호출을 쓰지 않는다. 데이터가 흐르는 모양만 똑같이 따라 했다. 가짜 페이지에 칸을 놓고 → 정규화 payload를 만들고 → 변환 단계를 흉내 낸 뒤, 박스가 입력 위젯으로 바뀐 결과까지 보여 준다.