Java에서 PDF 연산자로 작업
Contents
[
Hide
]
PDF 연산자 및 사용법 소개
연산자는 페이지에 그래픽 모양을 그리는 등 수행해야 할 일부 작업을 지정하는 PDF 키워드입니다. 연산자 키워드는 초기 사선 문자(2Fh)가 없다는 점에서 명명된 개체와 구별됩니다. 연산자는 콘텐츠 스트림 내에서만 의미가 있습니다.
콘텐츠 스트림은 페이지에 그려질 그래픽 요소를 설명하는 지침으로 데이터가 구성된 PDF 스트림 개체입니다. PDF 연산자에 대한 자세한 내용은 PDF 사양에서 확인할 수 있습니다.
명시적 행렬 수학을 사용하여 이미지 배치, XForm을 통해 동일한 그래픽 여러 번 재사용, 페이지에서 하위 수준 그리기 지침 삭제 등 Java에서 PDF 콘텐츠 스트림을 직접 제어해야 하는 경우 이 페이지를 사용하세요.
PDF 연산자로 이미지 추가
더 높은 수준의 레이아웃 API를 통하지 않고 콘텐츠 스트림 수준에서 이미지 배치를 정확하게 제어해야 하는 경우 낮은 수준 연산자를 사용하세요.
Document로 원본 PDF를 열고 대상Page를 가져오세요.- 페이지 리소스에 입력 이미지 스트림을 추가하고 반환된 리소스 이름을 유지하세요.
- 대상 영역을 정의하는
Rectangle을 만들고 그 경계에서Matrix를 만드세요. - 현재 그래픽 상태를 유지하려면
GSave를 사용하고, 이미지를 배치하려면ConcatenateMatrix를 사용하고, 이미지를 그리려면Do를 사용하고, 이전 상태를 복원하려면GRestore를 사용하세요. - 업데이트된 PDF 문서를 저장하세요.
public static void addImageUsingPdfOperators(Path inputFile, Path imageFile, Path outputFile) throws Exception {
try (Document document = new Document(inputFile.toString());
InputStream imageStream = Files.newInputStream(imageFile)) {
Page page = document.getPages().get_Item(1);
String imageName = page.getResources().getImages().add(imageStream);
Rectangle rectangle = new Rectangle(100, 100, 200, 200, true);
Matrix matrix = new Matrix(new double[]{
rectangle.getURX() - rectangle.getLLX(),
0,
0,
rectangle.getURY() - rectangle.getLLY(),
rectangle.getLLX(),
rectangle.getLLY()
});
page.getContents().add(new GSave());
page.getContents().add(new ConcatenateMatrix(matrix));
page.getContents().add(new Do(imageName));
page.getContents().add(new GRestore());
document.save(outputFile.toString());
}
System.out.println("Image added with PDF operators to " + outputFile);
}
페이지에 재사용 가능한 XForm 콘텐츠 그리기
PDF 파일의 리소스를 복제하지 않고 동일한 이미지나 그래픽을 두 번 이상 렌더링해야 하는 경우 이 접근 방식을 사용합니다.
Document로 소스 PDF를 열고 대상Page를 가져온 다음 해당OperatorCollection에 액세스하세요.- 기존 페이지 콘텐츠를
GSave및GRestore로 래핑하여 나중에 변환 시 원본 콘텐츠 스트림으로 유출되지 않도록 하세요. XForm리소스를 만들고 양식 리소스에 이미지를 추가하세요.ConcatenateMatrix와Do를 사용하여 양식 안에 이미지를 그리세요.- 이동 행렬을 추가하고
Do연산자로 양식을 실행하여 같은 양식을 페이지의 여러 좌표에 배치하세요. - 그래픽 상태를 복원하고 출력 PDF를 저장하세요.
public static void drawXFormOnPage(Path inputFile, Path imageFile, Path outputFile) throws Exception {
try (Document document = new Document(inputFile.toString());
InputStream imageStream = Files.newInputStream(imageFile)) {
Page page = document.getPages().get_Item(1);
OperatorCollection pageContents = page.getContents();
pageContents.insert(1, new GSave());
pageContents.add(new GRestore());
pageContents.add(new GSave());
XForm form = XForm.createNewForm(page, document);
page.getResources().getForms().add(form);
form.getContents().add(new GSave());
form.getContents().add(new ConcatenateMatrix(200, 0, 0, 200, 0, 0));
String imageName = form.getResources().getImages().add(imageStream);
form.getContents().add(new Do(imageName));
form.getContents().add(new GRestore());
addFormAt(pageContents, form.getName(), 100, 500);
addFormAt(pageContents, form.getName(), 100, 300);
pageContents.add(new GRestore());
document.save(outputFile.toString());
}
System.out.println("XForm drawn on page in " + outputFile);
}
private static void addFormAt(OperatorCollection pageContents, String formName, double x, double y) {
pageContents.add(new GSave());
pageContents.add(new ConcatenateMatrix(1, 0, 0, 1, x, y));
pageContents.add(new Do(formName));
pageContents.add(new GRestore());
}
페이지에서 그래픽 연산자 제거
페이지의 콘텐츠 스트림에서 벡터 그리기 연산자를 직접 제거해야 하는 경우 이 예제를 사용하세요.
Document로 원본 PDF를 열고 대상Page를 가져오세요.- 페이지 콘텐츠 연산자를 반복하고
Stroke,ClosePathStroke및Fill의 인스턴스를 수집하세요. - 페이지 콘텐츠에서 수집된 연산자를 삭제하고 업데이트된 PDF를 저장하세요.
이 기술은 대상 그리기 지침만 제거합니다. 페이지에 관련 텍스트 레이블이나 기타 비그래픽 연산자도 포함되어 있는 경우 해당 항목은 콘텐츠 스트림에 남아 있으며 별도의 정리 단계가 필요할 수 있습니다.
public static void removeGraphicsObjects(Path inputFile, Path outputFile) {
try (Document document = new Document(inputFile.toString())) {
Page page = document.getPages().get_Item(1);
List<Operator> operatorsToRemove = new ArrayList<>();
for (Object item : page.getContents()) {
Operator operator = (Operator) item;
if (operator instanceof Stroke || operator instanceof ClosePathStroke || operator instanceof Fill) {
operatorsToRemove.add(operator);
}
}
page.getContents().delete(operatorsToRemove);
document.save(outputFile.toString());
}
System.out.println("Graphics operators removed in " + outputFile);
}