Skip to content

2026년 최고의 Rust PDF 크레이트

PDF Oxide를 대표적인 Rust PDF 크레이트인 lopdf, printpdf, pdf-rs, pdf_extract와 정면 비교합니다. 각 크레이트는 추상화 수준과 타깃 유스케이스가 다릅니다 — 이 페이지는 프로젝트에 맞는 크레이트를 고르는 기준을 제공합니다.

요약

PDF Oxide lopdf printpdf pdf-rs pdf_extract
API 수준 고수준 저수준 중수준 (생성) 저수준 (읽기) 중수준 (읽기)
PDF 읽기 아니오
PDF 쓰기 아니오 아니오
텍스트 추출 예 (고수준) 수동 아니오 수동 예 (기본)
이미지 추출 예 (고수준) 수동 아니오 수동 아니오
폼 필드 읽기 + 쓰기 수동 아니오 읽기 전용 아니오
PDF 생성 아니오 아니오
Markdown/HTML 입력 아니오 아니오 아니오 아니오
기존 PDF 편집 예 (저수준) 아니오 아니오 아니오
주석 읽기 + 쓰기 수동 아니오 읽기 전용 아니오
암호화 읽기 + 쓰기 아니오 아니오 아니오 아니오
PDF/A 검증 아니오 아니오 아니오 아니오
렌더링 예 (tiny-skia) 아니오 아니오 부분적 아니오
Python 바인딩 아니오 아니오 아니오 아니오
라이선스 MIT MIT MIT MIT Apache-2.0

모든 라이브러리는 허용적 라이선스입니다. 차이점은 범위와 추상화 수준에 있습니다.

성능 비교

전체 코퍼스 벤치마크 (3,830개 PDF)

전체 3,830개 PDF 코퍼스에서 테스트했습니다 — PDF 사양 호환성(veraPDF, 2,907개 파일), 실제 브라우저 렌더링 엣지 케이스(Mozilla pdf.js, 897개 파일), 비정상 구조 및 퍼즈 생성 손상을 포함한 보안/안정성 스트레스 테스트(DARPA SafeDocs, 26개 파일)의 세 가지 독립적이고 공개적으로 이용 가능한 테스트 스위트를 포함합니다. 전체 코퍼스 세부 정보를 참조하세요.

라이브러리 평균 p99 통과율 텍스트 추출 비고
PDF Oxide 0.8ms 9ms 100% 내장, 프로덕션급 Unicode, CJK, 읽기 순서
oxidize_pdf 13.5ms 11ms 99.1% 기본 48초 최대 이상치
unpdf 2.8ms 10ms 95.1% 기본 전체 코퍼스에서 185개 실패
pdf_extract 4.08ms 37ms 91.5% 기본 복잡한 레이아웃 누락
lopdf 0.3ms 2ms 80.2% 내장 추출 없음 PDF의 20% 실패

lopdf는 파싱 가능한 PDF에서 더 빠르지만, 코퍼스의 20%에서 실패하며 텍스트 추출을 제공하지 않습니다. 폰트 디코딩, CMap 해석, 간격 분석을 직접 구축해야 합니다.

pdf_extract는 기본적인 텍스트 추출을 제공하지만 91.5% 통과율이며, 복잡한 레이아웃, CJK 텍스트, 태그된 PDF에서 어려움을 겪습니다. oxidize_pdf는 적절한 신뢰성(99.1%)을 보이지만 평균 추출 시간이 pdf_oxide보다 17배 느리며, 최악의 경우 48초의 이상치가 있습니다. unpdf는 전체 코퍼스를 처리하지만 185개 PDF에서 실패합니다.

PDF Oxide는 100% 신뢰성과 프로덕션급 텍스트 추출을 결합한 유일한 Rust 크레이트입니다.

API 설계 비교

PDF Oxide: 고수준, 작업 지향

PDF Oxide는 일반적인 작업을 위한 전용 메서드를 제공합니다. 텍스트, 이미지, 폼 필드를 다루며 — PDF 오브젝트나 딕셔너리가 아닙니다.

use pdf_oxide::PdfDocument;

let mut doc = PdfDocument::open("report.pdf")?;

// 텍스트 추출 -- 한 번의 호출
let text = doc.extract_text(0)?;
println!("{}", text);

// 폰트 메타데이터가 포함된 스타일 스팬
let spans = doc.extract_spans(0)?;
for span in &spans {
    println!("'{}' font={} size={:.1}pt", span.text, span.font_name, span.font_size);
}

// 이미지 추출
let images = doc.extract_images(0)?;
for img in &images {
    println!("{}x{} {:?}", img.width, img.height, img.format);
}

// 폼 필드
let fields = doc.extract_form_fields()?;
for field in &fields {
    println!("{}: {:?}", field.name, field.value);
}

PDF 생성도 마찬가지로 간단합니다:

use pdf_oxide::api::Pdf;

// Markdown에서 생성
let pdf = Pdf::from_markdown("# Report\n\n| A | B |\n|---|---|\n| 1 | 2 |")?;
pdf.save("report.pdf")?;

// HTML에서 생성
let pdf = Pdf::from_html("<h1>Report</h1><p>Content here.</p>")?;
pdf.save("report.pdf")?;

lopdf: 저수준 오브젝트 조작

lopdf는 PDF 오브젝트, 스트림, 크로스 레퍼런스 테이블에 직접 접근할 수 있습니다. 효과적으로 사용하려면 PDF 사양을 이해해야 합니다. 내장 텍스트 추출이 없으므로 — 딕셔너리를 탐색하고 스트림을 직접 디코딩해야 합니다.

use lopdf::Document;

let doc = Document::load("report.pdf")?;

// 페이지 딕셔너리 가져오기
let page_id = doc.page_iter().next().unwrap();
let page = doc.get_dictionary(page_id)?;

// 콘텐츠 스트림 가져오기 -- 수동 작업
let contents = page.get("Contents")?;
let stream = doc.get_object(contents.as_reference()?)?;

// 텍스트를 추출하려면 다음을 수행해야 합니다:
// 1. 콘텐츠 스트림 연산자 파싱
// 2. /Resources에서 폰트 참조 해석
// 3. CMap/ToUnicode 매핑 디코딩
// 4. 텍스트 매트릭스 변환 적용
// 5. 인코딩 차이 처리
//
// lopdf는 이 중 어떤 것도 제공하지 않습니다 -- 원시 오브젝트 접근만 가능합니다
println!("Page has {} objects", doc.objects.len());

lopdf는 PDF 구조를 직접 조작해야 할 때 적합한 도구입니다: 문서 병합, 오브젝트 스트림 재작성, 또는 특수 PDF 프로세서 구축 등에 사용합니다.

printpdf: PDF 생성 전용

printpdf는 생성 전용 라이브러리입니다. 기존 PDF를 읽거나 파싱할 수 없습니다. 텍스트, 이미지, 벡터 그래픽으로 PDF 문서를 처음부터 구축하기 위한 타입 API를 제공합니다.

use printpdf::*;

let (doc, page1, layer1) = PdfDocument::new(
    "Report", Mm(210.0), Mm(297.0), "Layer 1"
);

let current_layer = doc.get_page(page1).get_layer(layer1);

// 텍스트 추가 -- 수동 폰트 로딩 필요
let font = doc.add_builtin_font(BuiltinFont::Helvetica)?;
current_layer.use_text("Hello World", 24.0, Mm(10.0), Mm(280.0), &font);

// 저장
doc.save(&mut std::io::BufWriter::new(
    std::fs::File::create("output.pdf")?,
))?;

// 기존 PDF를 읽을 수 없음
// 텍스트, 이미지, 폼 필드 추출 불가

printpdf는 새 PDF만 생성하면 되고 깔끔하고 집중된 생성 API를 원할 때 적합한 도구입니다.

pdf-rs: 저수준 PDF 읽기

pdf-rs는 PDF 구조를 Rust 타입으로 파싱하지만 최소한의 고수준 기능을 제공합니다. PDF 오브젝트에 대한 타입 접근은 가능하지만 텍스트 디코딩, 폰트 해석, 콘텐츠 스트림 파싱은 직접 처리해야 합니다.

use pdf::file::FileOptions;

let file = FileOptions::cached().open("report.pdf")?;

// 페이지 오브젝트 접근
let page = file.get_page(0)?;
let media_box = page.media_box()?;
println!("Page size: {:?}", media_box);

// 콘텐츠 스트림 접근 -- 저수준
if let Some(ref contents) = page.contents {
    // 원시 연산을 반환합니다 -- 직접 해석해야 합니다
    // 내장 텍스트 조립, 폰트 디코딩, 레이아웃 분석 없음
}

// PDF를 쓰거나 수정할 수 없음

pdf-rs는 분석, 검증, 또는 커스텀 렌더러 구축을 위해 사양 호환 파서가 필요할 때 적합한 도구입니다.

작업별 기능 비교

텍스트 추출

라이브러리 내장 지원 품질 필요한 작업
PDF Oxide 프로덕션급 (Unicode, CJK, 읽기 순서) 메서드 한 번 호출
pdf_extract 기본 (복잡한 레이아웃 누락) 메서드 한 번 호출
lopdf 아니오 N/A 수백 줄의 커스텀 코드
printpdf 아니오 N/A 불가능 (쓰기 전용)
pdf-rs 아니오 N/A 상당한 커스텀 코드 필요

PDF Oxide는 CMap/ToUnicode 디코딩, 폰트 메트릭 기반 간격, 구조 트리 읽기 순서, 합자 재구성을 처리합니다. lopdf나 pdf-rs 위에 동등한 기능을 구현하려면 수천 줄의 코드와 깊은 PDF 사양 지식이 필요합니다.

PDF 생성

라이브러리 접근 방식 Markdown/HTML 입력 바코드
PDF Oxide 고수준 + 저수준
lopdf 원시 오브젝트 구성 아니오 아니오 아니오
printpdf 타입 레이어 API 아니오 아니오 아니오
pdf-rs N/A (읽기 전용) N/A N/A N/A

암호화

라이브러리 암호화 읽기 암호화 쓰기 알고리즘
PDF Oxide RC4-40, RC4-128, AES-128, AES-256
lopdf 아니오 아니오
printpdf 아니오 아니오
pdf-rs 부분적 아니오 RC4만

적합성 검증

라이브러리 PDF/A PDF/X PDF/UA
PDF Oxide 검증 + 변환 검증 검증
lopdf 아니오 아니오 아니오
printpdf 부분적 (PDF/A-1b 출력) 아니오 아니오
pdf-rs 아니오 아니오 아니오

의존성 풋프린트

라이브러리 의존성 컴파일 시간 바이너리 크기
PDF Oxide ~40 (코어) ~30초 ~4 MB
lopdf ~15 ~10초 ~1 MB
printpdf ~20 ~15초 ~2 MB
pdf-rs ~25 ~20초 ~2 MB

PDF Oxide는 폰트 파싱, 이미지 디코딩, 콘텐츠 스트림 해석, 암호화를 포함하기 때문에 더 많은 의존성이 있습니다 — 다른 라이브러리가 사용자에게 맡기거나 아예 생략하는 기능입니다. 모든 선택적 기능(rendering, barcodes, office)을 포함하면 ~100개로 늘어납니다.

라이브러리 조합

모든 라이브러리가 허용적 라이선스이므로, 하나의 프로젝트에서 조합할 수 있습니다:

[dependencies]
pdf_oxide = "0.3"
lopdf = "0.32"        # 선택 사항: 엣지 케이스를 위한 원시 오브젝트 접근

일반적인 패턴:

  • PDF Oxide + lopdf: PDF Oxide를 추출과 생성에 사용하고, 원시 오브젝트 조작이 필요한 엣지 케이스에서 lopdf로 폴백합니다.
  • PDF Oxide + printpdf: PDF Oxide를 읽기에, printpdf를 특수 생성 워크플로에 사용합니다.

사용 사례 매트릭스

“PDF에서 텍스트를 추출해야 합니다”

크레이트 적합? 비고
PDF Oxide 최고의 추출 품질, 100% 통과율, 읽기 순서, 폰트 메타데이터
pdf_extract 부분적 기본 추출, 91.5% 통과율
lopdf 아니오 텍스트 추출 없음
printpdf 아니오 PDF를 읽을 수 없음
pdf-rs 부분적 기본 파싱, 고수준 텍스트 추출 없음

“PDF를 생성해야 합니다”

크레이트 적합? 비고
PDF Oxide 고수준 (Markdown/HTML) 및 저수준 API
lopdf 부분적 저수준 오브젝트 구성
printpdf 깔끔한 생성 API, 읽기 불가
pdf-rs 아니오 읽기 전용

“기존 PDF를 편집해야 합니다”

크레이트 적합? 비고
PDF Oxide DOM 스타일 편집, 주석, 폼
lopdf 부분적 저수준 오브젝트 조작
printpdf 아니오 PDF를 읽을 수 없음
pdf-rs 아니오 읽기 전용

“전체 라이프사이클이 필요합니다 (추출 + 생성 + 편집)”

크레이트 적합? 비고
PDF Oxide 세 가지 모두를 지원하는 유일한 크레이트
lopdf + printpdf 부분적 두 크레이트, 텍스트 추출 없음
pdf-rs + printpdf 부분적 두 크레이트, 편집 없음

언제 어떤 것을 사용할까

PDF Oxide를 선택하세요: 하나 이상의 PDF 기능(추출 + 생성, 또는 추출 + 편집)이 필요하고 100% 신뢰성을 갖춘 단일의 잘 테스트된 의존성을 원하는 경우.

lopdf를 선택하세요: 저수준 PDF 구조 조작이 필요하고 PDF 사양을 직접 다루는 것이 편한 경우. 병합, 분할, 배치 PDF 처리에 적합합니다.

printpdf를 선택하세요: PDF만 생성하고 읽을 필요가 없는 경우. 보고서 및 문서 생성을 위한 가장 깔끔한 API입니다.

pdf-rs를 선택하세요: PDF 분석을 위한 사양 호환 파서가 필요하거나 자체 렌더링 파이프라인을 구축하는 경우.

pdf_extract를 선택하세요: 기본적인 텍스트 추출이 필요하고 높은 신뢰성이나 복잡한 레이아웃 지원이 필요하지 않은 경우.

관련 페이지