Bekerja dengan operator PDF di Java

Pengantar operator PDF dan penggunaannya

Operator adalah kata kunci PDF yang menentukan suatu tindakan yang harus dilakukan, seperti menggambar bentuk grafis di halaman. Kata kunci operator dibedakan dari objek bernama dengan tidak adanya karakter solidus awal (2Fh). Operator hanya memiliki makna di dalam aliran konten.

Aliran konten adalah objek aliran PDF yang datanya terdiri dari instruksi yang menggambarkan elemen grafis yang akan digambar pada halaman. Detail lebih lanjut tentang operator PDF dapat ditemukan di spesifikasi PDF.

Gunakan halaman ini ketika Anda membutuhkan kontrol langsung atas aliran konten PDF di Java, seperti menempatkan gambar dengan perhitungan matriks eksplisit, menggunakan kembali grafik yang sama berkali-kali melalui XForm, atau menghapus instruksi gambar tingkat rendah dari halaman.

Menambahkan gambar dengan operator PDF

Gunakan operator tingkat rendah ketika penempatan gambar harus dikontrol secara tepat pada tingkat aliran konten, bukan melalui API tata letak tingkat tinggi.

  1. Buka PDF sumber dengan Document dan dapatkan Page target.
  2. Tambahkan aliran gambar masukan ke sumber daya halaman dan pertahankan nama sumber daya yang dikembalikan.
  3. Buat sebuah Rectangle yang mendefinisikan area target dan bangun sebuah Matrix dari batasnya.
  4. Gunakan GSave untuk mempertahankan keadaan grafik saat ini, ConcatenateMatrix untuk menempatkan gambar, Do untuk melukisnya, dan GRestore untuk mengembalikan keadaan sebelumnya.
  5. Simpan dokumen PDF yang diperbarui.
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);
}

Menggambar konten XForm yang dapat digunakan kembali pada halaman

Gunakan pendekatan ini ketika gambar atau grafik yang sama harus dirender lebih dari satu kali tanpa menggandakan sumber daya dalam file PDF.

  1. Buka PDF sumber dengan Document; dapatkan Page target, dan aksesnya OperatorCollection.
  2. Bungkus konten halaman yang ada dengan GSave dan GRestore sehingga transformasi selanjutnya tidak bocor ke aliran konten asli.
  3. Buat sebuah XForm resource, tambahkan gambar ke sumber daya formulir, dan gunakan ConcatenateMatrix plus Do untuk menggambar gambar di dalam formulir.
  4. Tempatkan formulir yang sama pada beberapa koordinat halaman dengan menambahkan matriks translasi dan mengeksekusi nama formulir dengan Do operator.
  5. Pulihkan keadaan grafik dan simpan PDF keluaran.
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());
}

Menghapus operator grafik dari halaman

Gunakan contoh ini ketika sebuah halaman berisi operator gambar vektor yang harus dihapus langsung dari aliran konten.

  1. Buka PDF sumber dengan Document dan dapatkan Page target.
  2. Iterasikan melalui operator konten halaman dan kumpulkan contoh dari Stroke, ClosePathStroke, dan Fill.
  3. Hapus operator yang terkumpul dari konten halaman dan simpan PDF yang diperbarui.

Teknik ini hanya menghapus instruksi gambar yang ditargetkan. Jika halaman juga berisi label teks terkait atau operator non-grafik lainnya, item-item tersebut tetap berada dalam aliran konten dan mungkin memerlukan proses pembersihan terpisah.

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);
}

Topik terkait