ラベル 電子書籍 の投稿を表示しています。 すべての投稿を表示
ラベル 電子書籍 の投稿を表示しています。 すべての投稿を表示

2023/05/04

【Python】画像ファイルのPDF変換を並列処理で高速化する

これまでに何度も画像ファイルのPDF変換の記事を書いてきたのですが、これまでの変換プログラムの中で最も高速かつ簡単に動作していたのは、「img2pdf」でした。
img2pdfの使い方や速度比較などは、下記の過去記事にて紹介していますのでご参照ください。


これまで記事を作成する中で得られた経験から、concurrent.futuresで並列処理を実装すると、(動かすマシン次第ですが、)処理速度が結構早くなる可能性が見えてきました。
本記事では、並列処理を実装することでimg2pdfの処理速度を超えることを目指した結果をご紹介します。

本記事では、下記の三通りの比較を行います。
  • Method1: img2pdfを使用する
  • Method2: pikepdfとPillowを使用する
  • Method3: Method2をconcurrent.futuresで並列処理
前回までの記事と同様に、書籍をスキャンしたpngファイル(連番ファイル名)群を、pdfに変換することを想定しています。

実行環境は、以下の通りです。
MacBook Air(8コアCPU、10コアGPU、16コアNeural Engine搭載Apple M2チップ, 16GBメモリ)
------
Python 3.10.10
img2pdf 0.4.4
pikepdf 7.1.1
Pillow 9.3.0

Method1 : img2pdfを使う


Method2: pikepdfとPillowを使用する


Method3: Method2をconcurrent.futuresで並列処理

ライブラリとして、下記のようにpic2pdfという名前で整理しました。
一部の関数はimg2pdfのように動かせます。

10個の異なるpng画像ファイル群での出力ファイルサイズと実行時間の比較は、以下の通りです。


まとめ

今回作成したMethod2やMethod3による出力は、img2pdfで作成したPDFと完全に同じサイズのPDFにはなりませんでした。 img2pdfはロスレスらしいので、今回作成したものとは異なる処理でロスレスを実現しているみたいです。
なので、Method2やMethod3による出力はロスレスではなく、注意が必要です。

Method2は、img2pdfのソースコード(4000行超)と比較すればかなりシンプルに書くことができましたが、変換処理に2~3倍時間がかかっています。
それをconcurrent.futuresで並列処理を実装して、力技で高速化したのがMethod3です。あくまで、私の環境での計測結果になりますが、Method2よりも5倍以上早くなっています。
結果的に、img2pdfと比較して、半分程度で処理されるようになりました。また、プログレスバーを実装したので、処理時間が長い場合でも処理が動いていることが分かるようになりました。

今後も改良を重ねて、行こうと考えているので気になる方はGithubの方をチェックして下さい。

下記のようなPDF変換用のプログラムも作成していますので、今回の成果は、こちらで使用しようと考えています。

2023/03/17

【Python】自作のPythonパッケージをPyPIに登録しました!

今回は、自作のPythonパッケージをPyPIに登録することができたので報告したいと思います。

作成したパッケージは、以前の記事などで、作ってきたものを拡張したもので、自炊した漫画の画像ファイルをpdfに変換するためのプログラムです。別の記事で作ったePubからpdfに変換するプログラムも組み込んでいます。

PyPIへの登録手順は、他のサイトでも紹介されているため、ここでは割愛します。詳しい手順は、参考記事などをご確認ください。

参考記事:
setup.pyファイルの書き方も初めてだったので、ドキュメントを読みながら苦労しました。結局、setup.pyファイルでミスをしてしまい、PyPIにファイルをあげて直ぐに更新版をリリースすることになってしまいました。
似たような名前のパッケージがすでに登録されていることもあるので、パッケージ名を考えるところが難しいかもしれません。

今回、私が登録したPythonパッケージのソースコードは以下のGitHubリポジトリで閲覧することができます。また、改良のアイデアやバグ報告などがあれば、Github上でIssueを立てていただければ幸いです。

2023/01/07

【Python】複数枚のPNG画像をJPEGに圧縮してPDFに変換する

過去に何度もimg2pdfを利用した複数画像からPDFへの変換を記事にしていますが、本記事ではPNG画像をJPEG画像に圧縮してからPDFに変換する方法を試します。
PNG画像とJPEG画像の特性については解説しませんが、PDFにした時のファイルサイズの削減が目的です。 変換処理を挟むので、処理時間が増加しますがファイルサイズ低減のメリットが大きければ採用する価値があると思います。
以前の記事に倣って、またいくつかの手法を比較しました。

実行環境は、以下の通りです。
------
MacBook Air (M2, 2022, メモリ:16 GB)
Python 3.10.9
img2pdf 0.4.4
Pillow 9.3.0


Method1 : 画像変換によって圧縮してからPDFにする(PNG画像→JPEG画像→PDF):本記事のタイトルの手法

Method2 : img2pdfをだけ使う(PNG画像→PDF, ロスレス):以前の記事の中で書いたもの

Method3 : Pillowだけを使う(PNG画像→PDF, 圧縮):以前の記事の中で書いたもの

Method4 : Pillowだけを使う(PNG画像→PDF, 圧縮):Method3をconcurrent.futuresで並列化(Method1でもconcurrent.futuresを使用して並列化による高速化を試したため比較)

10個の異なるpng画像ファイル群での出力ファイルサイズと実行時間の比較は、以下の通りです。

Method1とMethod2の比較から分かりますが、JPEGに一度変換することでファイルサイズが小さくなり、処理速度も上がっています。
Method3とMethod4では、ファイル変換処理は同じなので当然出力ファイルサイズは同じですが、Method3とMethod4の比較から並列化の効果が分かります。今回使用した環境では、だいたい半分の時間で処理できています。


img2pdfで扱えないアルファチャンネルのある透過PNG画像も、Method1を使えば取り扱えそうです。

2022/12/16

【Python】画像のみの固定レイアウトのePubをPDFに変換する

だいぶ前から漫画などの固定レイアウトEpubを目次付きPDFに変換するプログラムをPythonで作りたい、ということで色々と検討してきました。 前回前々回の記事で紹介した内容になりますが、PythonのライブラリのEbookLibimg2pdfが使い勝手が良さそうだということがわかりました。

そこで本記事では、流行りの「ChatGPT」に、プログラムを作成してもらいました。
「画像のみの固定レイアウトepubを、PDFに変換するプログラムをPythonのebooklibとimg2pdfを使って作成してください」とチャットに送信した結果、以下の動画のようになりました。実際には、複数回実行して、ある程度欲しい結果になるまで繰り返し実行しています。



ChatGPTに何回か出力させたプログラムを組み合わせて、さらに足りてない部分などを加えて、修正したものが以下になります。


かなり実行速度が速く、体感的には一瞬で変換してくれました。まだ、目次の移植や右綴じへの変換などは出来ていないので、追々検討しようと思います。

ChatGPTが、吐き出したプログラムが実際には動かないプログラムというケースもありますが、今回の事例では良い精度で実行したい内容を動くプログラムにしてくれたので驚いています。 今後は、知りたいことを検索エンジンで似たようなことをやっている記事を探すのではなく、チャットで正解例を教わるような時代になるのでしょうか?
今後の進展が気になります。

追記:2022/12/18
pikepdfで右綴じにする部分を追加しました。

追記:2023/01/09
ePubからの目次を移植する部分を追加しました。
追追記:2023/02/24
Ebooklibを使わずに、BeautifulSoupを使うバージョンを作成しました。
コマンドライン実行を想定していて、綴じ方なども指定できるように変更しました。


今後は、逆に画像のみのPDFから固定レイアウトのePubへの変換プログラム作成に取り組みたいと思います。

2022/06/19

calibreで出力したepubをKindleGenで処理できるように再変換する

以前の記事でKindleGenなどの使い方を紹介しましたが、Kindleもepub対応するとニュースになっていました。メール転送でepubが使えるようになるだけみたいなので、個人的にはもうしばらくはKindleGenも使って行きたいと思っています。

電子書籍管理ソフトウェアの「Calibre」で変換したepubが、KindleGenで変換できないケースがあります。Calibreでmobiなりazw3なりに変換すれば良いのでしょうが、設定が正しくないためか、レイアウトが崩れ表示が壊れるケースに見舞われたので、Pythonで変換スクリプトを書きました。

と言っても、画像中の左のファイル構成になっているものを、右のファイル構成に変換するのが主な処理です。万能なコードではなく、KindleGenが上手く処理できない一部のケースのみに対応しているので、ご留意ください。

日本語の縦書き書籍(漫画などではない)を想定しており、スタイルシートは、「電書協 EPUB 3 制作ガイド ver.1.1.3 2015年1月1日版」から一部のファイルをコピーして使用しています。事前にダウンロードして解凍して同一階層に必要なファイルを置いてください。


バグ等もあるかと思いますので、参考程度にご利用いただけると幸いです。

関連記事

2021/08/06

【Python】複数画像をPDFに変換する方法の比較

以前も、複数画像をPDFに変換する方法に関して、img2pdfの紹介記事を書いたのですが、img2pdfやそれ以外の手法での実行時間やファイルサイズなどを比較してみました。

本記事では、img2pdfを用いてpdfにする方法と、reportlabとPillowを組み合わせる方法、Pillowのみを使う方法の三種類を比較した結果を紹介します。

実行時間は、実行環境などで変わるため、あくまで目安です。計測に関しても、Jupyter Lab上で、実行した結果であり、複数回測って平均をとるというような厳密なことはしておりません。

実行環境は、以下の通りです。

MacBook Pro 13-inch (2017)
------
Python 3.8.11
img2pdf 0.4.1
reportlab 3.3.0
Pillow 8.1.0

下記のスクリプトは、いずれも書籍をスキャンしたpngファイル(連番ファイル名)を、pdfに変換することを想定しています。

Method1 : img2pdfを使う

Method2 : reportlabとPillowを組み合わせる

Method3 : Pillowだけを使う


10個の異なるpng画像ファイル群での実行時間と出力ファイルサイズの比較は、以下の通りです。


img2pdfを用いた方法は、実行時間(変換にかかる時間)が特に短いです。 出力されたpdfファイルサイズは、pngファイルの合計サイズよりとほぼ同じサイズになっており、pngファイルを複雑に処理していないことが伺われます。 img2pdfに関して、残念なのはアルファチャンネルのある透過pngに対応していない点です。事前に処理しておいてね、という仕様となっています。


reportlabとPillowを組み合わせる方法ですが、実行時間が特に長く、画像のみのpdfを作るのであれば、reportlabを組み合わせる必要はないかなと感じました。


Pillowだけを用いる方法は、入力ファイルによって結果がばらついていますが、基本的にはファイルサイズが圧縮されています。リサンプリングしているため実行時間が伸びますが、この方法では、qualityの値を調整することでファイルサイズをさらに圧縮することも可能なので、ファイルサイズを調整したい時には良い方法だと思います。
ただし、img2pdfのように、見開きの設定など複雑なことはできないようなので、割り切って使うか他のツールと組み合わせる必要があります。


追記:2022/12/09
PyMuPDFを使って、変換する方法が分かったので追加しました。実行速度などは測っていません。

Method4 : PyMuPDFを使う

参考:

Method5 : borbを使う

borbを使って変換することも出来ましたが、v2.1.7では画像をPDFにする際に自動でOCR処理をするようで変換処理が遅いです。OCR処理をスキップ指定できる方法が分かれば更新します。基本的には余白が自動で入る設計で、このような変換は想定していないと思われます。
続き

2020/08/26

【Python】img2pdfを使って複数画像をPDFに変換する

前回からだいぶ時間が経ちましたが、目標である「漫画などの固定レイアウトEpubを目次付きPDFに変換するプログラムを作る」を達成するため、今回は前段階として、Pythonで連番を付けた複数画像ファイルをPDFに変換する方法を検討しました。

PythonのPDF関連のライブラリは、多い様で、PyPDF2ReportLabなどを使用した例の記事が多数ヒットしますが、これらのライブラリの更新はしばらく行われていない様です。

img2pdf

最近、img2pdfというライブラリが手軽かつ画像の再変換無しに使えるということで、日本語の紹介記事が多数書かれています。img2pdfでは、pdfの処理にpikepdfpdfrwが用いられている様です。またpikepdfは、Python3.8にも対応するなど積極的に更新されています。

参考リンク


ただ、簡単に変換するという目的以外の細かい設定を解説しているサイトが見つからなかったので、少し細かい設定を試してみました。
画像ファイルは、左からゼロ埋めしたファイル名になったもの(001.png, 002.png, ...)を使用しました。
img2pdfを用いてタイトル、作成者、およびキーワードなどのプロパティを設定したPDFが作成可能です。

また、見開きや表示倍率、フルスクリーン表示などの設定もできます。

img2pdfをコマンドラインから使う際は、見開きなどの設定ができますが、img2pdf(version 0.4.0)のconvert関数を使うと上手くいかず手こずりました。

上記の通り、parse_layout関数を通すなどすると動きました。
恐らくバグだと思いますが誰もこの機能を使っていない為、指摘されていないのかも知れません。

問題点:TwoPageRight、TwoPageLeftに対応していない

ページレイアウトは、現在(img2pdf version 0.4.0)では
single:「単一ページ」に相当
onecolumn:「連続ページ」に相当
twocolumnright:「連続見開きページ(表紙)」に相当
twocolumnleft:「連続見開きページ」に相当
にしか対応していません。

img2pdf.py(「PageLayout」に関する部分)を少し書き換えれば、
TwoPageRight: 「見開きページ(表紙)」に相当
TwoPageLeft: 「見開きページ」に相当
にも対応されることができます。

問題点:R2L (右綴じ)に対応していない


pdfrwは対応している様なので、こちらとの併用が必要になるかと思います。

追記:2022/12/09
pikepdfで右綴じ変換のプログラムを作成されている方がいらっしゃったので、リンクを貼ります。

続き

2019/10/01

【Python】EPUBからデータを抽出する

漫画などの固定レイアウトEpubを目次付きPDFに変換するプログラムを作りたい、ということで
手始めに、ePubからメタデータや目次データ、画像データのパスなどを表示するプログラムをサンプルコードなどを参考に書いてみました。
EbookLibというPythonのライブラリを使っています。https://github.com/aerkalov/ebooklib
EbookLibの使い方の参考になれば幸いです。


出力例:

2016/08/08

ePubをKindleで読めるように変換する方法


Kindleでは、PDFならそのままKindleの「documents」フォルダに入れて読むことができます。
しかし、ePub形式の電子書籍ファイルは「documents」フォルダに入れても読むことができません。

JailbreakすることでePubファイルのまま読めるようにすることも出来るようですが、JailbreakするとKindleがサポート対象外になり故障時などに困ります。

Calibreで変換する方法を紹介しているサイトも多いようですが、本記事では、Calibreは使わず、Kindle PreviewerやKindleUnpackなどを使って、ePubをKindleで開くことができるファイル形式に変換して読む方法を紹介します。
今回の内容を簡単に示すと以下のようになります。

.epubファイル(Kindleで読めない)
 ↓ 「KindleGen」または「Kindle Previewer」で変換
.mobiファイル(Kindleで読める)
 ↓ 「KindleUnpack」で変換
.azw3ファイル(Kindleで読める)
 ↓
Kindleへ転送

1.「KindleGen」あるいは「Kindle Previewer」をダウンロード&インストールする。

Amazonの公式ツールがここからダウンロードできます。

Windows版のツールのファイルサイズは「KindleGen」が3MB弱、「Kindle Previewer」は200MB弱です。
「KindleGen」だけでもePubから.mobiファイルに変換できます。ただ「KindleGen」はコマンドラインツールなので、使い方がよく分からない人は「Kindle Previewer」が良いかもしれません。

2.「KindleGen」あるいは「Kindle Previewer」でePubを変換する。


「KindleGen」のReadmeにはお勧めできないと書いてあるものの、解凍した「KindleGen」の実行ファイルのアイコン上に、ePubをドラッグ&ドロップすると、ePubと同じディレクトリ(フォルダ)内に.mobiファイルが出力されます。



出力された.mobiファイルをそのままKindleの「documents」フォルダに入れても読むことが出来ます。
しかし、出力された.mobiファイルは、ファイルサイズが元のePubよりもかなり大きくなります。

という訳で、もうひと手間かけて.mobiファイルを軽量化します。

3.「KindleUnpack」で圧縮する。

「KindleUnpack」というツールを使い、.mobiファイルを圧縮します。
「KindleUnpack」はここからダウンロードできます。
Pythonスクリプトなので、Pythonをインストールする必要があります。
スクリプトがPython 3.Xに対応していないので、Python 2.7.X系統をインストールします。
【2018/08/01追記】
アップデートでPython 3.4以降に対応したようです。

Pythonをインストールした後、KindleUnpack.pywをダブルクリックで起動します。


上から「入力ファイル」、「出力フォルダ」、「オプション」です。

「Browse」をクッリクし、「入力ファイル」と「出力フォルダ」を設定します。
[Split Combination Kindlegen eBooks]にチェックを入れ、[Start]で処理を開始します。

設定した「出力フォルダ」に「mobi8-(元のePubファイル名).azw3」が出力されます。
これで.mobiファイルよりも軽量化された.azw3ファイルが出来ます。


* KindleUnpackを用いることで、.azw3ファイルからePubファイルへの変換も行えますが、DRMのない.azw3ファイルしか扱えないようです。もし変換したい場合には何らかの方法で事前に.azw3ファイルからDRMを解除しておく必要があります。

4.Kindleに.azw3ファイルを転送する。


後は、KindleをPCにUSBケーブルで接続して、Kindleの「documents」フォルダに.azw3ファイルを入れれば、読むことができます。

関連記事