1.2.5 ページを上下左右に分割

images/DividePage-top.png

狙い・効果

PDF文書のページを上下・左右に分割ページを上下または左右に分割します。

処理の概要

PDF Tool APIでは、MediaBoxとCropBox の交わりを表示矩形(ViewBox)と呼びます。

  1. 入力PDF文書の表示矩形を取得して、指定方向の半分の長さを求めます。
  2. PDFを複製して、複製後のPDF文書の表示矩形の座標値を、半分の長さを使って再設定します。

MediaBox、CropBoxが表示矩形の値に設定されます。BleedBox、Trim、ArtBoxは削除されます。

PDF Tool APIの主な機能

プログラム例

package cookbook;

import jp.co.antenna.ptl.*;

public class DividePage {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        if (args.length < 3)
        {
            System.out.println("usage: java DividePage in-pdf-file out-pdf-file 分割方向");
            System.out.println("分割方向\n0 : ページを上下に分割  1 : ページを左右に分割");
            return;
        }

        String direction = args[2];
        switch (direction) {
        case "0":
        case "1":
            break;
        default:
            System.err.println("分割方向を正しく指定してください。");
            System.err.println("usage: java DividePage in-pdf-file out-pdf-file 分割方向");
            System.err.println("分割方向\n0 : ページを上下に分割  1 : ページを左右に分割");
            return;
        }

        try (PtlParamInput inputFile = new PtlParamInput(args[0]);
             PtlParamOutput outputFile = new PtlParamOutput(args[1]);
             PtlPDFDocument doc = new PtlPDFDocument();
             PtlPDFDocument docNew = new PtlPDFDocument();
             PtlPages pagesNew = docNew.getPages())
        {
            // PDFファイルをロードします。
            doc.load(inputFile);

            // ページ数の取得
            int numPages = doc.getPageCount();
            System.out.println("ページ数:" + numPages);


        ...【RemovePages.javaと同じ処理のため省略
             ・doc.getPages()メソッドを用いてPtlPages pagesにページコンテナを取得
             ・ページコンテナが空だった場合にエラーを出力して終了】...


                for (int i = 0; i < numPages; i++)
                {
                    // 読み込んだページの取得
                    try (PtlPage page = pages.get(i);
                         PtlSize size = page.getSize();
                         PtlRect viewBox = page.getViewBox()) // 読み込んだページの表示矩形取得
                    {
                        float width = size.getWidth();
                         float height = size.getHeight();

                        // ページを分割していくので注釈のLinkアクションを削除しておく
                        removeLinkAction(page);

                        // 読み込んだページを新規PDFに2ページ分追加
                        pagesNew.append(page, PtlPages.OPTION_NONE);
                        pagesNew.append(page, PtlPages.OPTION_NONE);

                        int numPagesNew = pagesNew.getCount();
                        try (PtlPage pageNew1 = pagesNew.get(numPagesNew - 2); // 追加されたページを取得
                             PtlPage pageNew2 = pagesNew.get(numPagesNew - 1); // 追加されたページを取得
                             PtlRect rect1 = new PtlRect(viewBox); // 追加されたページに設定する表示矩形
                             PtlRect rect2 = new PtlRect(viewBox)) // 追加されたページに設定する表示矩形
                        {
                            switch (direction)
                            {
                            case "0":
                                {
                                    // 半分の高さ
                                    float halfHeight = size.getHeight() / 2;
                                    // 矩形の上半分
                                    rect1.setBottom(viewBox.getBottom() + halfHeight);
                                    // 矩形の下半分
                                    rect2.setTop(viewBox.getTop() - halfHeight);
                                }
                                break;
                            case "1":
                                {
                                    // 半分の幅
                                    float halfWidth = size.getWidth() / 2;
                                    // 矩形の左半分
                                    rect1.setRight(viewBox.getRight() - halfWidth);
                                    // 矩形の右半分
                                    rect2.setLeft(viewBox.getLeft() + halfWidth);
                                }
                                break;
                            }
                            // 追加されたページの表示矩形を設定
                            pageNew1.setViewBox(rect1);
                            pageNew2.setViewBox(rect2);
                        }
                    }
                }
            }

            // ファイルに保存します。
            docNew.save(outputFile);
        }

        ...【GatPageCount.javaと同じ処理のため省略
             ・PtlException, Exception, Error を catchするエラー処理
             ・finally文で"--完了--"と表示する処理】...

    }

    public static void removeLinkAction(PtlPage page) throws PtlException, Exception, Error
    {
        if (!page.hasAnnots()) {
            return;
        }
        try (PtlAnnots annots = page.getAnnots())
        {
            int numAnnots = annots.getCount();
            for(int i=0; i<numAnnots; ++i) {
                try (PtlAnnot annot = annots.get(i))
                {
                    switch (annot.getType()) {
                    case TYPE_LINK:
                        {
                            PtlAnnotLink annotLink = (PtlAnnotLink)annot;
                            try (PtlAction action = annotLink.getAction())
                            {
                                switch (action.getType()) {
                                case TYPE_GOTO:
                                    annotLink.removeAction();
                                    break;
                                default:
                                    break;
                                }
                            }
                        }
                        break;
                    default:
                        break;
                    }
                }
            }
        }
    }
}

サンプルファイル名

DividePage.java

入出力操作の例

images/DividePage.png

分割結果は図のようになります。この分割処理ではPDF文書のページを複製して各ページのPDFの境界値を設定し直しています。このため新しいPDF文書のファイルサイズは倍になります。

images/DividePdf-example.png

図1・5 PDFを縦に分割