📁 File5. 애플리케이션 파일05 · Extraction & Rendering

05 · Extraction & Rendering

이 문서가 답하는 질문: 업로드된 PDF / docx / xlsx / 이미지에서 텍스트 · 메타 · 이미지 · 썸네일 을 어떻게 뽑아내는가? 어떤 도구를, 어떤 순서로 호출하는가? 사용처: 검색 인덱싱, 미리보기, OCR 파이프라인, 컴플라이언스 검사


한 줄 답 (Pyramid Top)

추출은 “무엇이 있는가 (메타) → 본문 텍스트 → 시각 표현 (썸네일)” 의 3단 파이프라인이다. 가벼운 도구(pdftotext, mammoth, openpyxl)가 첫 번째 패스, Apache Tika 가 만능 fallback, 시각 표현은 LibreOffice / pdf.js / Poppler 의 헤드리스 렌더가 끝낸다.


Why — 왜 통합 파이프라인이 필요한가

업로드 1 개에서 다음을 모두 만들어야 한다:

목적필요한 산출물
검색본문 텍스트 + 메타 (제목·저자·날짜)
미리보기첫 페이지 PNG / 전체 페이지 PNG
컴플라이언스매크로 / 외부 링크 / GPS 검출
다운로드 변환docx → PDF, xlsx → CSV

각 포맷마다 다른 도구가 필요 → 포맷 → 도구 매핑 이 파이프라인의 핵심.

또한 샌드박스 — 신뢰 못 할 입력을 서버 main process 에서 처리하면 RCE / DoS 위험. 도커 컨테이너 / Lambda / firejail 로 격리.


How — 3단 파이프라인의 구체

단계 1 — 식별 (앞 단원의 결과)

file.bin  →  매직 검사  →  MIME 결정  →  파이프라인 분기

file --mime-type 또는 libmagic, 보안 민감 시 직접 매직 검사.

단계 2 — 메타 추출 (가벼운 패스)

포맷도구명령
PDFpdfinfo (Poppler)pdfinfo file.pdf
이미지exiftoolexiftool photo.jpg
비디오ffprobeffprobe -v error -show_format file.mp4
OOXMLunzip + docProps/core.xmlunzip -p f.docx docProps/core.xml
모든 것Apache Tikatika --metadata file

Tika 의 강점: 1,400+ 포맷 지원, 자바 한 도구로 끝.

$ tika --metadata report.pdf
Author: Finance Team
Content-Type: application/pdf
Creation-Date: 2026-05-01T09:00:00Z
producer: LibreOffice 7.5
xmpTPg:NPages: 12

단계 3 — 텍스트 추출 (포맷별 최적 도구)

포맷1순위 (가벼움)2순위 (만능)3순위 (스캔 PDF)
PDFpdftotext -layoutpdfplumber (표)pdftoppm + tesseract (OCR)
docxmammoth (HTML/MD)python-docxTika
xlsxopenpyxl / pandasTika
pptxpython-pptxTika
HWP (한글)pyhwpLibreOffice → docx → mammothOCR
이미지tesseract -l kor+eng
RTFunrtfLibreOffice → txt
# 일반 PDF
$ pdftotext -layout report.pdf - | head -5
 
# 표가 있는 PDF
$ python -c "
import pdfplumber
with pdfplumber.open('finance.pdf') as p:
    for table in p.pages[0].extract_tables():
        for row in table: print(row)
"
 
# 스캔 PDF
$ pdftoppm -r 300 scan.pdf page -png
$ for f in page-*.png; do tesseract "$f" stdout -l kor+eng; done > all.txt
 
# docx → Markdown (mammoth)
$ npx mammoth report.docx --output-format=markdown > report.md
 
# Tika 만능 fallback
$ tika --text any.unknown > extracted.txt

단계 4 — 렌더링 (썸네일·미리보기)

입력도구명령
PDF → PNGPopplerpdftoppm -r 150 a.pdf out -png
PDF → PNGMuPDFmutool draw -o out-%d.png a.pdf
docx → PDFLibreOfficelibreoffice --headless --convert-to pdf a.docx
pptx → PNGLibreOfficelibreoffice --headless --convert-to png a.pptx
xlsx → PDFLibreOfficelibreoffice --headless --convert-to pdf a.xlsx
HTML → PNGChromium headless / Puppeteerchromium --headless --screenshot a.html
SVG → PNGrsvg-convert / inkscapersvg-convert a.svg > a.png

전형적 파이프라인 — Office → PDF → PNG:

# 1) docx → PDF
libreoffice --headless \
  -env:UserInstallation=file:///tmp/lo-$$ \
  --convert-to pdf --outdir /tmp/out report.docx
 
# 2) PDF → PNG (1 페이지만, 200 DPI, 너비 800)
pdftoppm -r 200 -f 1 -l 1 -scale-to-x 800 /tmp/out/report.pdf /tmp/thumb -png
 
# 3) thumb-1.png 가 산출물

What — 도구 카탈로그 + 컨테이너 레시피

도구 카탈로그

도구언어/런타임강점약점
Poppler (pdftotext, pdftoppm, pdfinfo)C++PDF 표준 도구표 추출 약함
MuPDFC빠르고 가벼움라이선스 (GPL/상용)
pdfplumberPython표·좌표 보존큰 PDF 느림
pdf.jsJS브라우저 단독서버에서는 무거움
mammothJS/Pythondocx → 의미 보존 MD/HTML표 약함
python-docx / openpyxl / python-pptxPython정확한 셀/단락변환 X
LibreOffice headlessJava/UNO만능 변환무겁고 동시성 어려움
Apache TikaJava1,400 포맷 메타+텍스트정확도 보통
tesseractC++OCR (100+ 언어)정확도는 입력 품질 의존
exiftoolPerl이미지/비디오 메타표는 X
ImageMagick / GraphicsMagickC이미지 변환RCE 이력 다수 (정책 파일 필요)
ffmpegC비디오/오디오 변환·스냅샷CLI 복잡

컨테이너 레시피 (Dockerfile 일부)

FROM debian:12-slim
 
RUN apt-get update && apt-get install -y --no-install-recommends \
    libreoffice \
    poppler-utils \
    tesseract-ocr tesseract-ocr-kor tesseract-ocr-eng \
    fonts-noto-cjk \
    ghostscript \
    imagemagick \
    ffmpeg \
    python3 python3-pip \
    && rm -rf /var/lib/apt/lists/*
 
# Tika
RUN curl -L -o /opt/tika.jar \
    https://archive.apache.org/dist/tika/3.0.0/tika-app-3.0.0.jar
 
RUN pip3 install --break-system-packages \
    pdfplumber python-docx openpyxl python-pptx mammoth pillow
 
# ImageMagick — 기본 정책에서 PDF 처리 막혀있음, 필요시 풀어주되 신중히
# /etc/ImageMagick-6/policy.xml 의 PDF/EPS rights 조정

Lambda / Cloud Function 패턴

LibreOffice 는 무거움 (수백 MB). Lambda Layer 또는 Container Image 로 구성. 콜드 스타트 부담 → Provisioned Concurrency 또는 별도 변환 워커 권장.

[ Upload S3 ] → [ EventBridge ]
       → [ Lambda: 메타·텍스트 (가벼움, JS/Python) ]
       → [ Lambda Container: LibreOffice 변환 (무거움) ]
       → [ Lambda: pdftoppm 썸네일 ]
       → [ S3 산출물 ]

미디어 변환 파이프라인의 fan-out/fan-in 패턴과 동일 (07-pipeline-theory/03-fan-out-fan-in 참조).

검색 파이프라인과의 결합

원본 → Tika (텍스트+메타) → ES bulk index
                         → meta facet (author, date, page_count)

쿼리 → ES match → 점수 → 썸네일 URL (S3) → UI

pg_trgm 트라이그램 / tsvector 도 한국어/영어 적당히 작동. 한국어는 형태소 분석기 필요 (Mecab, Nori).


What-if — 파이프라인이 깨지는 지점

1) LibreOffice 동시 실행 락

같은 user profile 디렉토리를 잠금. 두 번째 요청이 hang. 대응: 요청별 -env:UserInstallation=file:///tmp/lo-$$.

2) ImageMagick RCE (CVE-2016-3714 “ImageTragick”)

MVG, MSL 형식이 임의 명령 실행 가능. 대응: /etc/ImageMagick-6/policy.xml 에서 위험 코더 차단:

<policy domain="coder" rights="none" pattern="MVG" />
<policy domain="coder" rights="none" pattern="MSL" />
<policy domain="coder" rights="none" pattern="EPHEMERAL" />

3) PDF 의 폰트 미임베딩

서버에서 PDF 렌더 시 한글이 □□□. 대응: 컨테이너에 fonts-noto-cjk 포함, LibreOffice 가 이걸 fallback 으로 사용.

4) 무한 페이지 PDF / 100K 슬라이드 pptx

DoS 우려. 첫 페이지만 렌더하더라도 LibreOffice 는 전체 로드 시도. 대응:

  • 입력 페이지 수 사전 검사 (pdfinfo 결과 페이지 수 한계).
  • 시간/메모리 제한 (timeout 30s, cgroup).

5) Tika 의 OOM

큰 첨부 PDF (수백 MB) 에서 Tika JVM 힙 폭발. 대응: 별도 프로세스, -Xmx2g 등 제한, 실패 시 가벼운 도구로 fallback.

6) OCR 의 환각

Tesseract 가 빈 페이지에서 ”…의 의 의 의” 같은 환각 텍스트 생성. 대응: 신뢰도(-c tessedit_create_hocr=1) 낮은 결과 필터링.

7) 변환 결과의 fidelity 손실

docx → PDF 변환 시 폰트 fallback 으로 줄바꿈 위치 변경 → 페이지 수 변경. 검증 필요: 사용자에게 “원본 보기” 옵션 제공.


Insight — 흥미로운 이야기

“왜 LibreOffice 가 사실상 표준 변환기인가”

Microsoft Office Online 은 클라우드에 묶여있고, 서버 라이선스는 비싸고, API 가 제한적. LibreOffice 는 LGPL — 회사 서버에 무한정 설치 가능, headless 모드 지원, OOXML 호환성이 점점 좋아지고 있음. 단점은 무거움 (200+ MB) 과 동시성 — 그래서 보통 별도 변환 워커로 격리.

“Apache Tika 의 시작은 Lucene”

2007년 Lucene 검색 인덱싱을 위해 시작. “검색하려면 모든 포맷을 텍스트로 바꿔야 한다” → 자바 생태계의 모든 파서를 한 자켓으로. 지금은 Solr/Elasticsearch 의 첨부 파이프라인의 표준.

“OCR 의 30년 — Tesseract 의 부활”

1985년 HP Labs 에서 시작 → 1995년 사장 → 2005년 Google 이 인수해 오픈소스화. 2018년 v4 가 LSTM 신경망 기반으로 전환 → 한국어 정확도 폭발. 지금은 무료로 100+ 언어를 처리하는 사실상 유일한 오픈소스 OCR.

“Office → PDF → PNG 패턴이 보편적인 이유”

직접 Office → PNG 가 불안정 (LibreOffice 의 PNG export 가 슬라이드 단위 안정성 떨어짐). 중간에 PDF 를 거치면 벡터 → 래스터 의 마지막 한 단계만 잘 만들면 됨 → Poppler / MuPDF 가 이걸 30년간 다듬음. “복잡한 변환 = PDF 경유” 가 사실상의 모범사례.


요약 + Mermaid

추출 파이프라인은 메타 → 텍스트 → 렌더 의 3단계. 포맷별로 1순위 가벼운 도구가 따로 있고, Apache Tika 가 만능 fallback, 시각 표현은 LibreOffice → PDF → Poppler/MuPDF → PNG 의 패턴이 보편적이다. 모든 단계는 샌드박스 + 자원 한계 + 보안 정책 위에서 돌려야 한다.