Colaboratory環境で画像ファイルをPDFファイルに変換する(img2pdf)
本記事では、主にGoogle Colaboratory環境で、JPEGなどの画像ファイルをimg2pdfを利用して、画質の劣化なくPDFファイルに変換する方法について考えてみました。
【目次】
[1]img2pdfについて
img2pdfは、JPEGなどの画像ファイルを、劣化なく(可逆に)PDFファイルに変換してくれるツールです。
img2pdfの特徴
- 劣化がない(可逆変換)
- PDFに埋め込まれた画像は、すべてのピクセルが入力と同じカラー情報を持ちます。
- サイズが小さい
- 可能であれば、入力画像と出力PDFとのファイルサイズの違いは、PDFコンテナー自体のオーバーヘッドのみになります。
- 変換が高速
- 可能であれば、入力画像はピクセルデータの再エンコードを行わずにそのままPDFドキュメントに貼り付けられます。
このため、画像ファイルを画質を落とさず機械的にPDFファイルに変換したい場合には、とても有用なツールです。
img2pdfは、シェルコマンドあるいはPythonライブラリとして利用することができます。
本記事では、『Colaboratory+GoogleドライブでVision APIの実験環境を作る』の流れから、Colaboratoryの環境内でimg2pdfを使って画像ファイルをPDFに変換する方法を考えてみました。
(参考)
本記事とは逆に、PDFファイルを画像化する記事『Ubuntu/Colab環境でPDFファイルのページを画像化する(pdf2image、pdftoppm、pdftocairo)』も書いてみました。参考にしてください。
[2]インストール方法
以下のコマンドを実行するだけで、Colaboratory環境にimg2pdfをンストールできます。
!pip install img2pdf
インストールすると、img2pdfコマンドが利用できるようになます。また、Pythonからもimg2pdfをインポートすれば利用できます。
(補足)
img2pdfのホームページには、DebianあるいはUbuntu環境におけるapt経由でのインストールする方法が書かれています。しかしながら、Colaboratory環境ではPython環境との関係から、pipでインストールする必要があります。
[3]シェルコマンドとして利用する
(1)基本的な使い方
img2pdfはシェルコマンドとして利用できます。超基本的な利用法は以下の通りです。
!img2pdf [-o 出力PDFファイル名] 入力画像ファイル(複数指定可能)
-oオプションで作成するPDFファイル名を指定します。もし-oオプションを指定しない場合は、標準出力に出力されます。
入力画像ファイルは複数指定できます。もし入力画像ファイルを指定しないか、または入力画像ファイルとして、ハイフン(-)を指定すると標準入力から画像ファイルを読み込みます。
例1)sample1.jpgをout1.pdfに変換する
!img2pdf -o out1.pdf sample1.jpg
例2)sample1.jpgとsample2.jpgの2つの画像から2ページのout2.pdfに変換する
!img2pdf -o out2.pdf sample1.jpg sample2.jpg
(2)高度な使い方
img2pdfは多くの機能を持っています。
以下のコマンドを実行すると、利用方法と詳細な機能説明を表示することができます。
!img2pdf --help
これは以下のページでも見ることが出来ます。
- Ubuntsu Manpage(http://manpages.ubuntu.com/manpages/xenial/man1/img2pdf.1.html)
全ての機能を説明することはできませんが、例を書きます。
例)ページサイズを指定して、sample1.jpgとsample2.jpgの2つの画像を2ページのout2a4.pdfに変換する
!img2pdf -o out2a4.pdf --pagesize A4 sample1.jpg sample2.jpg
(3)PNGファイルを変換する場合の注意事項
PNGファイルをPDF変換する時、以下のエラーが発生する場合があります。
WARNING:root:Image contains transparency which cannot be retained in PDF.
WARNING:root:img2pdf will not perform a lossy operation.
WARNING:root:You can remove the alpha channel using imagemagick:
WARNING:root: $ convert input.png -background white -alpha remove -alpha off output.png
ERROR:root:error: Refusing to work on images with alpha channel
この内容は、img2pdfのホームページのBugsの項目に以下のように説明されています。
- Input images with alpha channels are not allowed. PDF only supports transparency using binary masks but is unable to store 8-bit transparency information as part of the image itself. But img2pdf will always be lossless and thus, input images must not carry transparency information.
ざっくり言えば、(アルファチャネルによる)透明度情報もつ画像(PNG-32など)は、img2pdfが目的とする劣化がない(可逆)変換でPDF化することはできないので、img2pdfでは扱わないということのようです。
ならば何らかの方法で透明度情報を持たないJPEGなどに変換してからimg2pdfを利用してもよいのですが、ここでは上記のメッセージで例示されている、ImageMagickを利用してアルファチャネルの情報を取り除く方法を試してみます。
ところで、ImageMagickは、とても高機能な画像加工ツールです。本記事ではImageMagickについての説明は割愛します。
ImageMagickのインストール
以下のコマンドでColaboratory環境にImageMagickをインストールできます。
!apt install imagemagick
インストールが完了すると、img2pdfのメッセージに例示されているconvertコマンドが利用できるようになります。
convertはとても多機能なコマンドですが、ファイル変換するだけならとても簡単に利用できます。例えば、sample3.pngをsample3.jpgに単純に変換するだけなら、以下のように利用できます。
!convert sample3.png sample3.jpg
convertコマンドと組み合わせてPNGをPDFに変換する
例えば、sample3.pngをout3.pdfに変換するため、
!img2pdf -o out3.pdf sample3.png
を実行すると、透明度情報に関するエラーが表示されたとします。
エラーメッセージにあるように、convertコマンドでアルファチャネルの情報を取り除いたPNGファイルを作成して、img2pdfを実行すると、確かに変換できます。
!convert sample3.png -background white -alpha remove -alpha off output.png
!img2pdf -o out3.pdf output.png
なお、中間ファイルを作らず、パイプで繋いで実行することもできます。
!convert sample3.png -background white -alpha remove -alpha off - | img2pdf - -o out3.pdf
[4]Pythonプログラムから利用する
(1)基本的な使い方
例)sample1.jpgをout1.pdfに変換する
import img2pdf
with open("out1.pdf","wb") as f:
f.write(img2pdf.convert('sample1.jpg'))
これ以外にも、img2pdfのサイトのLibraryの項に、Pythonから利用する場合のサンプルコードがありますので必要に応じて参照してください。
(2)コマンドライン的な利用方法
Pythonライブラリとしてのimg2pdfのリファレンスを見つけることが出来ませんでしたので、ソースコードを見てみました。
- img2pdf GibLab(https://gitlab.mister-muffin.de/josch/img2pdf/tree/master)
これによると、img2pdfコマンドはPythonで実装されていることが分かります。
そして、コマンドラインに与える内容を、文字列のリストで表現し、それを引数としてPythonライブラリのmain関数を呼び出せば同じ動作を実行できます。
高度な使い方については、まずは、上記のManPageのコマンドリファレンスを参考にして、必要なオプションをシェルコマンドで試してみます。うまく動作すれば、そのコマンド文字列を引数としてmain関数を呼び出せばよいことになります。
例)sample1.jpgをout1.pdfに変換する
import img2pdf
argv = ['','-o','out1.pdf','sample1.jpg']
img2pdf.main(argv)
コメント
コメントを投稿