ottijp blog

PDFの綴じ方向を変更するツールをDockerHubで公開した

2020-05-08 Tags: 自炊iTextdockergradleOpenJDK

本を自炊する際,右綴じ本の綴じ方向(Direction, Binding Edge)をR2L(Right-to-Left)に変えるために, PDF InfoMakerというツールに長らくお世話になってきました. このツールは,シンプルながらとても便利で大変重宝していたのですが, 普段Macを使っているので,このためだけ(ではないけど)にWindowsを使っているのはちょっと嫌なのと, 古いソフトでいつまでサポートが続くかわからないので,iText 7 Communityを使ってツールを自作しました.

全コードはottijp/pdf-r2lに置いてあります.

使い方

Dockerのインストールだけしてあれば,次のコマンドで実行可能です.

$ docker run --rm -v "$PWD":/work ottijp/pdf-r2l pdf-r2l R2L book.pdf book-r2l.pdf

R2Lの部分をL2Rにすると,Left-to-Rightに変更もできます.


2020/05/23 追記

Homebrewでのインストールにも対応しました.

$ brew install ottijp/tap/pdf-r2l

iText 7 CommunityでPDF綴じ方向の設定

iTextを使った綴じ方向の変更は,次のようなサイトでいくつかコード例があったのですが,iText 7ではAPIが変わったようで,うまく動きませんでした.

そこで,公式のこちらの例を参考に,次のように書きました.

src/main/java/PdfR2L.java
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfReader;
import com.itextpdf.kernel.pdf.PdfViewerPreferences;
import com.itextpdf.kernel.pdf.PdfWriter;

import java.io.File;
import java.io.IOException;

public class PdfR2L {

  public enum  Mode {
    R2L,
    L2R
  }

  protected void convert(String src, String dest, Mode mode) throws IOException {
    // create dest dir
    var destFile = new File(dest);
    if (destFile.getParentFile() != null) {
      destFile.getParentFile().mkdirs();
    }

    var pdfDoc = new PdfDocument(new PdfReader(src), new PdfWriter(dest));

    // get or create view preference
    var viewerPreferences = pdfDoc.getCatalog().getViewerPreferences();
    if (viewerPreferences == null) {
      viewerPreferences = new PdfViewerPreferences();
      pdfDoc.getCatalog().setViewerPreferences(viewerPreferences);
    }

    // set reading direction
    viewerPreferences.setDirection(mode == Mode.R2L ?
        PdfViewerPreferences.PdfViewerPreferencesConstants.RIGHT_TO_LEFT :
        PdfViewerPreferences.PdfViewerPreferencesConstants.LEFT_TO_RIGHT);

    pdfDoc.close();
  }
}

OpenJDKの理解

iText 7はJavaライブラリとして提供されている(.Netへの移植版もあるようですが)ので, 普段あまり使わないJavaを使ったのですが, 前からイマイチよくわかっていなかったOpenJDKやJavaライセンス関係のことを学べてよかったです. こちら↓の解説がとってもわかりやすかったです.

参考: 最適なOpenJDKディストリビューションの選び方

結局,gradleのdockerがAdoptOpenJDKを使っていたので,AdoptOpenJDKを使いました.

gradleでデプロイ可能なアプリケーションをビルドする

grandleもバージョンによってDSLが変わっていて,昔のブログ記事を参考にしても動かなかったり Deprecatedの警告が出たりするので,基本的には公式のドキュメントを見たほうがよいです.

今回使った6.4だと,Applicationプラグインを使えば, 依存パッケージや実行スクリプトもまとめてくれるので, そのままDockerFileでCOPYしてあげるだけでアプリケーションがデプロイできて便利でした.

build.properties
apply plugin: 'application'

mainClassName = "App"

repositories {
  jcenter()
}

dependencies {
  implementation 'com.itextpdf:itext7-core:7.1.11'
  implementation 'org.slf4j:slf4j-log4j12:1.7.30'
}

jar {
  manifest {
    attributes(
      'Main-Class': 'App'
    )
  }
  from 'LICENSE'
}
Dockerfile
FROM adoptopenjdk:11-jre-hotspot
LABEL maintainer "Satoshi SAKAO <ottijp@users.noreply.github.com>"

WORKDIR /work
COPY build/install/pdf-r2l /opt/pdf-r2l

ENV PATH $PATH:/opt/pdf-r2l/bin

CMD ["pdf-r2l"]

DockerHubへのDockerイメージの公開

DockerHubへのDockerイメージの公開は今回初めて行ったのですが, これはdocker loginしてdocker pushするだけなので簡単でした.

リポジトリはこちらです.

ref


ottijp
Satoshi SAKAO (@ottijp)

都内でアプリケーションエンジニアをしています

...