Java를 사용하여 QR 코드 PDF 읽는 방법
소개
수백 개의 PDF 청구서, 배송 라벨 또는 재고 문서에서 바코드 정보를 추출해야 했던 적이 있나요? 페이지를 일일이 수동으로 스캔하는 일은 번거롭고 오류가 발생하기 쉽습니다. 자동 문서 처리 시스템을 구축하든 제품 진위 여부를 확인하든, PDF에서 바코드를 효율적으로 찾는 것은 어려운 과제일 수 있습니다.
이 가이드에서는 QR 코드 PDF 문서를 GroupDocs.Signature API를 사용해 효율적으로 읽는 방법을 배웁니다. 강력한 이 API는 수시간이 걸리던 작업을 몇 줄의 코드로 처리하게 해 줍니다. 전체 문서를 스캔하고, 특정 바코드 유형(QR 코드 또는 Code128 등)을 찾아 데이터를 자동으로 추출할 수 있습니다.
배우게 될 내용:
- 몇 분 만에 Java용 GroupDocs.Signature 설정하기
- PDF 문서 내 바코드 서명 검색하기
- 정확하고 목표 지향적인 결과를 위한 검색 옵션 구성하기
- 다양한 바코드 유형(QR 코드, EAN, Code128 등) 처리하기
- 일반적인 문제 해결 및 성능 최적화
시작해 봅시다!
빠른 답변
- GroupDocs.Signature가 PDF에서 QR 코드를 읽을 수 있나요? 예, QR, Data Matrix, PDF417 및 다수의 1D 바코드를 감지합니다.
- 프로덕션 사용에 라이선스가 필요합니까? 상업용 라이선스가 필요합니다; 평가용 무료 체험판을 사용할 수 있습니다.
- 필요한 Java 버전은? Java 8+ (Java 11+ 권장).
- 특정 페이지만 검색하도록 제한하려면?
BarcodeSearchOptions.setAllPages(false)를 사용하고setPageNumber()를 설정합니다. - 배치 처리 시 API가 스레드‑안전한가요? 예, 스레드당 별도의
Signature인스턴스를 생성하면 안전합니다.
왜 PDF에서 바코드를 검색할까요?
실제 비즈니스 애플리케이션에서 이 기능이 중요한 이유는 다음과 같습니다.
Common Business Scenarios
- Invoice Processing – 공급업체 청구서에서 주문 번호 또는 추적 코드를 자동으로 추출합니다.
- Inventory Management – 제품 카탈로그를 스캔하고 SKU 바코드를 추출해 데이터베이스를 업데이트합니다.
- Shipping & Logistics – 선적 명세서에서 패키지 추적 코드를 검증합니다.
- Document Authentication – 보안 바코드를 확인해 서명된 문서의 진위를 검증합니다.
- Healthcare Records – 의료 문서에서 환자 ID 또는 처방 코드와 같은 바코드를 추출합니다.
GroupDocs.Signature API가 복잡한 이미지 처리, 바코드 디코딩 알고리즘, PDF 렌더링 등을 모두 처리해 주므로 별도로 신경 쓸 필요가 없습니다.
사전 요구 사항
필수 라이브러리 및 종속성
Java 프로젝트에 GroupDocs.Signature 라이브러리를 포함해야 합니다. Maven 또는 Gradle을 사용해 추가하는 방법은 다음과 같습니다.
Maven:
<dependency>
<groupId>com.groupdocs</groupId>
<artifactId>groupdocs-signature</artifactId>
<version>23.12</version>
</dependency>
Gradle:
implementation 'com.groupdocs:groupdocs-signature:23.12'
Note: 최신 버전은 GroupDocs.Signature for Java releases에서 확인하세요. 최신 버전을 사용하면 버그 수정 및 새로운 기능을 바로 이용할 수 있습니다.
환경 설정
- JDK 8 이상 – GroupDocs.Signature는 최소 Java 8이 필요합니다 (성능을 위해 Java 11+ 권장).
- IDE – 텍스트 편집기만 사용해도 되지만, IntelliJ IDEA 또는 Eclipse를 사용하면 자동 완성 및 디버깅이 편리합니다.
- PDF Document – 바코드가 포함된 테스트 PDF를 준비하세요(청구서, 배송 라벨, 제품 카탈로그 등).
지식 사전 요구 사항
다음에 익숙해야 합니다:
- 기본 Java 문법 및 객체 지향 개념
try‑catch블록을 이용한 예외 처리- IDE에서 외부 라이브러리 사용
타사 Java 라이브러리를 처음 접하더라도 걱정 마세요. 단계별로 모두 안내합니다.
Java용 GroupDocs.Signature 설정
GroupDocs.Signature를 시작하는 데는 몇 분이면 충분합니다. 전체 설정 과정을 살펴보세요.
Step 1: Add the Dependency
Maven 또는 Gradle을 사용해 라이브러리를 포함합니다(위 코드 참고). 의존성을 추가한 뒤 프로젝트를 새로 고쳐 JAR 파일을 다운로드합니다.
Step 2: License Acquisition
GroupDocs는 여러 라이선스 옵션을 제공합니다:
- Free Trial – 테스트에 적합합니다. GroupDocs releases에서 다운로드하세요.
- Temporary License – Temporary License Page에서 30일 동안 전체 기능을 사용할 수 있습니다.
- Commercial License – 프로덕션 사용을 위해서는 GroupDocs Purchase에서 라이선스를 구매하세요.
Pro Tip: 먼저 무료 체험판으로 개념 증명을 만든 뒤, API가 필요에 맞는지 확인하고 상용 라이선스로 전환하세요.
Step 3: Basic Initialization
PDF와 함께 작업하기 위해 Signature 객체를 만드는 예시입니다:
import com.groupdocs.signature.Signature;
String filePath = "YOUR_DOCUMENT_DIRECTORY/sample_signed.pdf"; // Replace with your PDF path
Signature signature = new Signature(filePath);
Signature 클래스가 메인 진입점이며, PDF를 메모리로 로드하고 검색·검증·데이터 추출(바코드 포함) 메서드를 제공합니다.
Important: 파일 경로가 정확하고 PDF가 존재하는지 확인하세요. 흔히 저지르는 실수는 Windows 경로에서 역슬래시를 이스케이프하지 않는 것입니다(C:\\Documents\\file.pdf가 올바른 형식).
구현 가이드
이제 재미있는 부분—PDF에서 바코드를 검색하는 코드를 작성해 보겠습니다.
Searching for Barcode Signatures in a Document
PDF를 스캔해 모든 바코드 서명을 찾는 방법을 단계별로 설명합니다.
Step 1: Initialize the Signature Object
PDF 문서를 로드합니다:
import com.groupdocs.signature.Signature;
String filePath = "YOUR_DOCUMENT_DIRECTORY/sample_signed.pdf"; // Replace with actual file path
Signature signature = new Signature(filePath);
What’s Happening HereSignature 클래스가 PDF를 열고 처리 준비를 합니다. 텍스트 편집기에서 파일을 여는 것과 비슷하게, 문서를 메모리로 로드해 작업할 수 있게 합니다.
Real‑World Note
사용자 업로드 파일을 처리할 경우, Signature 객체를 만들기 전에 파일 경로와 존재 여부를 반드시 검증하세요. 이렇게 하면 나중에 발생할 수 있는 모호한 오류를 방지할 수 있습니다.
Step 2: Create BarcodeSearchOptions
바코드 검색 옵션을 설정합니다:
import com.groupdocs.signature.options.search.BarcodeSearchOptions;
// Configure options for searching barcodes
BarcodeSearchOptions options = new BarcodeSearchOptions();
options.setAllPages(true); // Search every page in the document
Key Configuration Options
setAllPages(true): 모든 페이지를 스캔합니다. 특정 페이지만 확인하려면false로 설정하고setPageNumber()로 페이지를 지정합니다.- Why This Matters: 바코드가 항상 1페이지에 있다면 전체 페이지를 검색하는 것은 자원을 낭비합니다. 다페이지 선적 명세서의 경우
setAllPages(true)가 필요합니다.
Pro Tip: 바코드 유형을 필터링하면(아래 Supported Barcode Types 섹션 참고) 검색 속도가 빨라집니다.
Step 3: Execute Search and Handle Results
검색을 실행하고 결과를 처리합니다:
import com.groupdocs.signature.domain.signatures.BarcodeSignature;
import java.util.List;
try {
// Execute the barcode search
List<BarcodeSignature> signatures = signature.search(BarcodeSignature.class, options);
// Check if any barcodes were found
if (signatures.isEmpty()) {
System.out.println("No barcode signatures found in the document.");
} else {
System.out.println("Found " + signatures.size() + " barcode signature(s):\n");
// Loop through each barcode and display details
for (BarcodeSignature barcodeSignature : signatures) {
System.out.println("----------------------------------------");
System.out.println("Barcode Type: " + barcodeSignature.getEncodeType().getTypeName());
System.out.println("Barcode Text: " + barcodeSignature.getText());
System.out.println("Page Number: " + barcodeSignature.getPageNumber());
System.out.println("Position: X=" + barcodeSignature.getLeft() +
", Y=" + barcodeSignature.getTop());
System.out.println("Size: Width=" + barcodeSignature.getWidth() +
", Height=" + barcodeSignature.getHeight());
System.out.println("----------------------------------------\n");
}
}
} catch (Exception e) {
System.err.println("Error searching for barcodes: " + e.getMessage());
e.printStackTrace();
} finally {
// Always dispose of the signature object to free resources
if (signature != null) {
signature.dispose();
}
}
What’s Happening in This Code
- Search Execution –
signature.search()가 PDF를 스캔하고BarcodeSignature객체 리스트를 반환합니다. - Empty Check – 바코드가 실제로 발견됐는지 확인해 NullPointerException을 방지합니다.
- Data Extraction – 각 바코드에서 다음 정보를 추출합니다:
- Type – 바코드 형식(QR Code, Code128, EAN13 등)
- Text – 디코딩된 데이터(주문 번호, 추적 코드, SKU 등)
- Location – 페이지 번호와 X/Y 좌표
- Dimensions – 너비와 높이(검증에 유용)
- Error Handling –
try‑catch블록이 PDF 손상, 파일 누락 등 예외 상황을 안전하게 처리합니다. - Resource Cleanup –
finally블록에서Signature객체를 적절히 해제해 메모리를 회수합니다.
Real‑World Application
예를 들어 배송 라벨을 처리한다면 getText() 값을 추적 번호로 데이터베이스에 저장하고, 페이지 번호를 이용해 배치 문서 내 어느 라벨이 어떤 배송에 해당하는지 파악할 수 있습니다.
Filtering by Barcode Type
바코드 유형을 지정해 검색 속도를 높일 수 있습니다:
import com.groupdocs.signature.domain.barcodes.BarcodeTypes;
BarcodeSearchOptions options = new BarcodeSearchOptions();
options.setEncodeType(BarcodeTypes.QR); // Only search for QR codes
options.setAllPages(true);
When to Filter
청구서에 Code128 바코드만 포함된 경우, 유형을 지정하면 대용량 문서에서 처리 시간이 30‑50 % 단축됩니다.
지원되는 바코드 유형
GroupDocs.Signature는 다양한 바코드 형식을 감지합니다. 아래는 검색 가능한 형식 목록입니다.
1D Barcodes (Linear)
- Code128 – 배송 및 포장에 흔히 사용
- Code39 – 자동차·방위 산업에서 사용
- EAN13/EAN8 – 소매 제품 바코드(모든 제품에 표시)
- UPC‑A/UPC‑E – 북미 소매 표준
- Interleaved2of5 – 창고·유통 분야
2D Barcodes (Matrix)
- QR Code – 가장 보편적이며 URL, Wi‑Fi 비밀번호, 결제 정보 등에 사용
- Data Matrix – 전자 부품 등 작은 아이템에 적합한 고밀도 형식
- PDF417 – 정부 ID, 탑승권, 운전면허증 등
- Aztec Code – 교통 티켓 등
Filtering by Type(위 예시 참고)를 활용하면 필요한 형식만 집중적으로 검색할 수 있습니다.
실제 사용 사례
개발자들이 프로덕션에서 바코드 검색을 활용하는 방법을 소개합니다.
1. Automated Invoice Processing
Scenario – 회계 부서는 하루에 500개 이상의 공급업체 청구서를 PDF 형태로 받습니다.
Solution – PDF에서 Code39 바코드(청구서 번호)를 스캔해 ERP 시스템의 구매 주문과 자동 매칭합니다. 이를 통해 수작업 입력을 없애고 오류를 크게 줄입니다.
// Pseudo-code workflow
for (PDF invoice : invoiceBatch) {
List<BarcodeSignature> barcodes = searchBarcodes(invoice);
String invoiceNumber = barcodes.get(0).getText();
updateERPSystem(invoiceNumber, invoice);
}
2. Warehouse Inventory Updates
Scenario – 창고에 도착한 물품의 PDF 포장 명세서에 EAN13 바코드가 포함되어 있습니다.
Solution – 포장 명세서에서 모든 바코드를 추출해 재고 수량을 자동으로 업데이트하고, 차이가 있는 경우 검토하도록 알립니다.
3. Document Authentication
Scenario – 법률 문서에 보안 QR 코드가 삽입되어 암호화 서명을 포함합니다.
Solution – 서명된 계약서에서 QR 코드를 검색·디코딩하고, 신뢰할 수 있는 인증 기관과 비교해 문서가 변조되지 않았는지 검증합니다.
4. Healthcare Records Management
Scenario – 병원에서 PDF 형태의 검사 보고서에 Code128 바코드(표본 ID)가 포함됩니다.
Solution – 표본 ID를 자동으로 추출해 환자 기록 시스템(HIS)과 연동함으로써 검사 결과를 정확히 환자에게 연결합니다.
Common Issues and Solutions
다음은 자주 마주치는 문제와 해결 방법입니다.
Issue 1: “No Barcodes Found” (But You Know They Exist)
Possible Causes
- 바코드 이미지 품질이 낮음(흐릿하거나 픽셀화)
- PDF가 이미지 기반이지만 바코드가 너무 작음
- 잘못된 바코드 유형을 검색하고 있음
Solutions
- Check Image Resolution – 바코드 감지를 위해 최소 200 DPI가 필요합니다. 스캔 시 300 DPI 이상을 권장합니다.
- Remove Type Filtering – 처음에는
setEncodeType()을 지정하지 말고 모든 유형을 검색해 보세요. 이후에 어떤 유형이 포함되어 있는지 확인하고 필터링합니다. - Verify Barcode Quality – Adobe Acrobat에서 PDF를 열고 확대해 보세요. 사람이 보기에도 흐릿하면 API도 인식하기 어렵습니다.
Issue 2: OutOfMemoryError with Large PDFs
Cause – 500페이지 이상의 고해상도 이미지가 포함된 PDF를 한 번에 로드하면 메모리가 크게 소모됩니다.
Solution
- Process Pages in Batches –
setAllPages(true)대신 50페이지씩 나눠 처리합니다:
for (int startPage = 1; startPage <= totalPages; startPage += 50) {
BarcodeSearchOptions options = new BarcodeSearchOptions();
options.setPageNumber(startPage);
options.setPagesSetup(new PagesSetup());
options.getPagesSetup().setLastPage(Math.min(startPage + 49, totalPages));
List<BarcodeSignature> batchResults = signature.search(BarcodeSignature.class, options);
// Process results...
}
- Increase JVM Heap Size – 실행 명령에
-Xmx4g를 추가해 4 GB 메모리를 할당합니다(필요에 따라 조정).
Issue 3: Slow Performance on Multi‑Page Documents
Cause – 모든 페이지를 순차적으로 검색하면 특히 PDF417 같은 복잡한 바코드에서는 시간이 오래 걸립니다.
Solutions
- Parallel Processing – 바코드가 항상 특정 페이지(예: 청구서 1페이지)에 있다면 해당 페이지만 검색합니다.
- Cache Results – 동일 문서를 여러 번 처리해야 한다면 바코드 데이터를 캐시해 재검색을 피합니다.
- Use SSDs – 대용량 PDF 로딩 시 I/O 속도가 중요합니다. SSD를 사용하면 로딩 시간이 HDD 대비 60‑70 % 단축됩니다.
Issue 4: False Positives (Detecting Random Patterns as Barcodes)
Cause – 표, 격자, 선 패턴 등이 바코드로 오인될 수 있습니다.
Solution – 디코딩된 텍스트 길이와 형식을 검증해 실제 바코드인지 확인합니다:
for (BarcodeSignature barcode : signatures) {
String text = barcode.getText();
// Example: Invoice numbers are always 10 digits
if (text.matches("\\d{10}")) {
// Valid invoice number
processBarcode(barcode);
} else {
System.out.println("Skipping invalid barcode: " + text);
}
}
Performance Tips for Large Documents
수천 개의 PDF를 처리해야 하나요? 최적화 방법을 소개합니다.
1. Batch Processing Strategy
파일을 하나씩 처리하는 대신 스레드 풀을 이용해 여러 PDF를 동시에 처리합니다:
ExecutorService executor = Executors.newFixedThreadPool(4); // 4 parallel threads
for (String pdfPath : pdfFiles) {
executor.submit(() -> {
try (Signature sig = new Signature(pdfPath)) {
List<BarcodeSignature> results = sig.search(BarcodeSignature.class, options);
// Process results...
} catch (Exception e) {
e.printStackTrace();
}
});
}
executor.shutdown();
executor.awaitTermination(1, TimeUnit.HOURS);
Performance Gain – 1 000개 파일을 처리하는 시간이 2시간에서 30분으로 단축됩니다(쿼드 코어 머신 기준).
2. Reduce Search Scope
비즈니스 로직이 허용한다면 검색 범위를 제한합니다:
// Only search the top‑right corner where barcodes are typically placed
options.setRectangle(new Rectangle(400, 50, 150, 150)); // X, Y, Width, Height
Performance Gain – 바코드 위치가 일정한 문서에서는 40‑60 % 빠르게 처리됩니다.
3. Monitor Memory Usage
장시간 배치 작업 시 힙 사용량을 모니터링하고 필요 시 명시적으로 가비지 컬렉션을 요청합니다:
Runtime runtime = Runtime.getRuntime();
long usedMemory = runtime.totalMemory() - runtime.freeMemory();
if (usedMemory > (runtime.maxMemory() * 0.8)) {
System.gc(); // Suggest garbage collection
}
Best Practices
프로덕션 수준 코드를 작성하려면 다음 가이드를 따르세요.
1. Always Dispose of Signature Objects
Java 7 이상의 try‑with‑resources 구문을 사용해 리소스를 자동으로 해제합니다:
try (Signature signature = new Signature(filePath)) {
// Your search code here...
} // Automatically disposed
2. Validate Input Files
처리 전 파일 존재 여부와 유효한 PDF인지 확인합니다:
File pdfFile = new File(filePath);
if (!pdfFile.exists() || !pdfFile.canRead()) {
throw new FileNotFoundException("PDF not found or not readable: " + filePath);
}
// Optional: Verify it's actually a PDF (check magic bytes)
3. Log Barcode Detection Results
디버깅 및 감사 목적을 위해 검색 결과를 로그에 남깁니다:
Logger logger = Logger.getLogger(BarcodeSearcher.class.getName());
for (BarcodeSignature barcode : signatures) {
logger.info(String.format("Detected %s barcode '%s' on page %d at (%.2f, %.2f)",
barcode.getEncodeType().getTypeName(),
barcode.getText(),
barcode.getPageNumber(),
barcode.getLeft(),
barcode.getTop()));
}
4. Handle Different Barcode Formats
산업마다 사용하는 표준이 다릅니다. 코드를 유연하게 설계하세요:
switch (barcode.getEncodeType().getTypeName()) {
case "QR":
// QR codes might contain URLs or JSON data
processQRCode(barcode.getText());
break;
case "Code128":
// Code128 typically contains alphanumeric order/tracking numbers
processTrackingNumber(barcode.getText());
break;
default:
logger.warning("Unexpected barcode type: " + barcode.getEncodeType());
}
5. Test with Real‑World Documents
완벽한 샘플 PDF만으로 테스트하지 마세요. 실제 운영 환경에서 사용되는 문서를 활용해 테스트합니다:
- 커피 얼룩이 있는 스캔 청구서
- 잡음이 섞인 팩스 배송 라벨
- 모바일 사진을 PDF로 변환한 저해상도 파일
이렇게 하면 데모에서는 보이지 않던 엣지 케이스를 발견할 수 있습니다.
Frequently Asked Questions
Q: 무료 체험판으로 QR 코드 PDF 파일을 읽을 수 있나요?
A: 무료 체험판으로는 평가 목적의 QR 코드 PDF 읽기가 가능하지만, 프로덕션 배포 시에는 상용 라이선스가 필요합니다.
Q: API가 비밀번호로 보호된 PDF를 지원하나요?
A: 예. Signature 객체를 생성할 때 비밀번호를 전달하면 됩니다: new Signature(filePath, "password").
Q: 저해상도 스캔에서 감지를 개선하려면 어떻게 해야 하나요?
A: 원본 스캔 DPI를 최소 200 DPI로 높이고, 바코드 유형을 지정해 검색 범위를 좁히면 오탐이 감소합니다.
Q: 병렬 처리 시 검색이 스레드‑안전한가요?
A: 각 스레드가 자체 Signature 인스턴스를 사용하면 API는 스레드‑안전하게 동작합니다.
Q: 이 튜토리얼은 어떤 버전의 GroupDocs.Signature와 검증되었나요?
A: 코드는 GroupDocs.Signature 23.12 버전으로 검증되었습니다.
Conclusion
Java와 GroupDocs.Signature API를 사용해 QR 코드 PDF 문서를 읽는 방법을 방금 배웠습니다. 다룬 내용은 다음과 같습니다:
✅ Setup – 프로젝트에 GroupDocs.Signature 추가 및 라이선스 옵션
✅ Implementation – 바코드 데이터 검색·추출·처리 전체 코드
✅ Barcode Types – 지원되는 1D·2D 형식 이해
✅ Real‑World Use Cases – 청구서 처리, 재고 관리, 문서 인증, 의료 기록 등
✅ Troubleshooting – 메모리 오류·오탐·성능 저하 등 일반 문제 해결법
✅ Performance – 대규모 문서 처리 최적화 전략
GroupDocs.Signature API가 PDF 파싱과 바코드 감지의 복잡성을 대신 처리해 주므로 비즈니스 로직 구현에 집중할 수 있습니다. 청구서 자동화, 배송 라벨 검증, 재고 데이터 추출 등 어떤 시나리오든 이제 강력한 솔루션을 갖추게 되었습니다.
마지막 업데이트: 2026-03-01
테스트 환경: GroupDocs.Signature 23.12
작성자: GroupDocs