第1回 フォルダー内のJPEGファイルを連番でリネームする 第2回 他の画像形式をJPEG形式に変更する 第3回 ピクセルサイズに応じて画像ファイルをリサイズする 第4回 実行先のフォルダーを引数で指定する 第5回 case文でスクリプト内容を整理する
第6回Webページの情報をシェルスクリプトで取得する 第7回取得結果をCSVファイルやテキストファイルに出力する 第8回インターネットショートカットファイルを作成する 第9回散らかったデスクトップを片付ける 第10回時間軸でデスクトップを片付ける
第11回BashからExcelブックにアクセスする 第12回フォルダーの中のエクセル請求書ファイルを合計する 第13回フォルダの中のファイルを一括でPDFにするには 第14回整理整頓!空のフォルダを一括でデスクトップに移送する 第15回ファイル名ではなく内容判断で重複ファイルを削除するには?
第16回文章をMarkdown記法で整える 第17回複数PDFファイルから一括テキスト抽出

見送られたWSLのアップデート

2016年10月25日(現地時間)、MicrosoftはWindows 10 Insider Preview ビルド14955をリリースし、WSL(Windows Subsystem for Linux)も同じように更新しているかと思いきや、リリースノートによるとOSビルド14955でのWSLアップデートは含まれていないという。この背景には、2016年10月19日(現地時間)にリリースしたOSビルド14951の配信トラブルがある。

筆者の環境を含む多くのWindows Insider Program参加者の配信されず、本連載とは関係ないがWindows 10 Mobile Insider Previewは新ビルドを検出しても、0パーセントから進まないというトラブルが発生していた。Windows 10 Insider Previewのファーストリングは、約1週間単位で新ビルドが配信されるため、OSビルド14951からOSビルド14955までの期間は通常どおりながらも、配信トラブルを改善するため、早期に最新ビルドの配信に踏み切ったのだろう。そのため、OSビルド14955の変更点は少なく、WSLのアップデートも見送られた。ちなみに次のビルドはWSLのアップデートも行われる予定である。

PDFファイルから画像ファイルを出力する

さて、前回はPDFファイルからテキストを抜き出すため、LinuxディストリビューションではポピュラーなPDF描画ライブラリである「Poppler」を利用した。同パッケージはテキストを抽出するコマンド「pdftotext」以外にも、PDFファイルに含まれる画像を抽出するコマンド「pdfimages」が含まれている。

使い方は簡単だが、そのまま実行するとPDFファイル内で使用している画像ファイルを"すべて"抽出するため、出力先フォルダー内に大量の画像ファイルが作成されてしまう。そこでpdfimagesのオプション「-list」を使って事前に確認することをお薦めしたい。下図はMicrosoftが作成した592ページにもおよぶPDFファイルに対して同オプションを使ったものだが、約600もの画像ファイルが含まれている。

「pdfimages -list PDFファイル」を実行した例。含まれる画像ファイルの一覧が現れる

また、出力する画像ファイルの形式はPBM(Portable Bitmap Format)もしくはPPM(Portable Pixmap Format)のため、オプション「-png」もしくは「-tiff」を追加して、出力画像ファイル形式を指定した方が、Windows 10では使いやすくなるだろう。興味深いのが両方のオプションを使用できる点だ。その際はCMYK画像をTIFF、それ以外をPNG形式で出力する。

このようにPDFから画像ファイルの抽出は簡単ながらも、前回と同じようにどのようなシェルスクリプトを用意すれば、利用者が"楽"になるかだ。そこで今回は画像ファイルを出力するフォルダーをPDFファイルごとに作成し、出力画像ファイルに用いるimage-rootに元のPDFファイル名を使用するシェルスクリプトを用意した。いつもどおりお使いの環境に合わせて変数の値を変更し、シェルスクリプトに実行権限を与えてからお試し頂きたい。

なお、Ubuntu 14.04の場合、パッケージのバージョンが古いため、今回のシェルスクリプトは正しく動作しない。事前にUbuntu 16.04へ更新するか、pdfimagesのオプション構成を環境に合わせて修正してほしい。

 #!/bin/bash

 IFS=$'\n'
 BaseDir=/mnt/c/Users/kaz/Desktop
 InputDir=$BaseDir/Input
 OutputDir=$BaseDir/Output

 if [ ! -d $OutputDir ]; then
    mkdir $OutputDir
 fi

 cd $InputDir
 for File in *; do
    case ${File##*.} in
        pdf|PDF )
            echo "Extracting PDF:" ${File}
            if [ ! -d ${File%.*} ]; then     
                mkdir ${File%.*}     
            fi
            pushd ${File%.*} >/dev/null 2>&1
                pdfimages -q -p -png -tiff ../${File} ${File%.*}
            popd >/dev/null 2>&1
            ;;
        *) ;;
    esac
 done

前回作成したスクリプトをベースに改良を加えた形だ。17~19行目は抽出した画像を保存するフォルダーを作成する部分だが、拡張子である「.pdf」「.PDF」は不要なため、Bashの変数展開「${変数名%.*}」を利用して拡張子を削除した。20~22行目が今回の核となるが、pdfimagesが抽出先フォルダーを指定するオプションを用意していないため、コマンド「pushd」で抽出先フォルダーに移動し、相対パスでPDFファイルを参照。そしてコマンド「popd」で元のフォルダーに戻している。

シェルスクリプトを実行すると、PDFファイルと同じフォルダーを作成し、そこに画像ファイルを抽出している

こちらは抽出した画像ファイルの一覧。今回使用したPDFでは1000を超える画像ファイルが作成された

阿久津良和(Cactus)