そこで本記事では、流行りの「ChatGPT」に、プログラムを作成してもらいました。
「画像のみの固定レイアウトepubを、PDFに変換するプログラムをPythonのebooklibとimg2pdfを使って作成してください」とチャットに送信した結果、以下の動画のようになりました。実際には、複数回実行して、ある程度欲しい結果になるまで繰り返し実行しています。
ChatGPTに何回か出力させたプログラムを組み合わせて、さらに足りてない部分などを加えて、修正したものが以下になります。
import img2pdf | |
import ebooklib | |
from ebooklib import epub | |
# 1. EPUBを読み込む | |
book = epub.read_epub('input.epub') | |
# 2. EPUBの各ページを画像として取得する | |
items = [] | |
for item in book.get_items(): | |
if item.get_type() == ebooklib.ITEM_COVER: | |
items.append(item.get_content()) | |
elif item.get_type() == ebooklib.ITEM_IMAGE: | |
items.append(item.get_content()) | |
# 3. 画像をPDFに変換する | |
with open('output.pdf', 'wb') as f: | |
f.write(img2pdf.convert(items)) |
かなり実行速度が速く、体感的には一瞬で変換してくれました。まだ、目次の移植や右綴じへの変換などは出来ていないので、追々検討しようと思います。
ChatGPTが、吐き出したプログラムが実際には動かないプログラムというケースもありますが、今回の事例では良い精度で実行したい内容を動くプログラムにしてくれたので驚いています。 今後は、知りたいことを検索エンジンで似たようなことをやっている記事を探すのではなく、チャットで正解例を教わるような時代になるのでしょうか?
今後の進展が気になります。
追記:2022/12/18
pikepdfで右綴じにする部分を追加しました。
import io | |
import pikepdf | |
import img2pdf | |
import ebooklib | |
from ebooklib import epub | |
# 1. EPUBを読み込む | |
book = epub.read_epub('input.epub') | |
# 2. EPUBの各ページを画像として取得する | |
items = [] | |
for item in book.get_items(): | |
if item.get_type() == ebooklib.ITEM_COVER: | |
items.append(item.get_content()) | |
elif item.get_type() == ebooklib.ITEM_IMAGE: | |
items.append(item.get_content()) | |
# 3. 画像をPDF形式に変換する | |
file_obj = io.BytesIO(img2pdf.convert(items)) | |
# 4. PDFを右綴じ(R2L)にする | |
with pikepdf.Pdf.open(file_obj) as pdf: | |
pdf.Root.PageLayout = pikepdf.Name.TwoPageRight | |
pdf.Root.ViewerPreferences = pikepdf.Dictionary() | |
pdf.Root.ViewerPreferences.Direction = pikepdf.Name.R2L | |
pdf.save('output_R2L.pdf') |
追記:2023/01/09
ePubからの目次を移植する部分を追加しました。
import io | |
import pikepdf | |
import img2pdf | |
import ebooklib | |
from ebooklib import epub, utils | |
from pikepdf import Pdf, OutlineItem | |
# 1. ePubを読み込む | |
book = epub.read_epub('input.epub') | |
# 2. ePubの各ページのファイル名と画像を取得する | |
page_names = [] | |
page_items = [] | |
for item in book.get_items(): | |
if item.get_type() == ebooklib.ITEM_COVER: | |
page_names.append(item.get_name()) | |
page_items.append(item.get_content()) | |
elif item.get_type() == ebooklib.ITEM_IMAGE: | |
page_names.append(item.get_name()) | |
page_items.append(item.get_content()) | |
# 3. ePub内の画像をPDF形式に変換する | |
file_obj = io.BytesIO(img2pdf.convert(page_items)) | |
# 4. ePubの目次情報を取得し、画像リストと照らし合わせる | |
index_numbers = [] | |
for item in book.get_items_of_type(ebooklib.ITEM_DOCUMENT): | |
body = utils.parse_html_string(item.get_body_content()) | |
for elem in body.iter(): | |
if 'xlink:href' in elem.attrib: | |
for chapter in book.toc: | |
if item.get_name() == chapter.href: | |
image_href = elem.attrib.get('xlink:href')[3:] | |
index_number = page_names.index(image_href) | |
index_numbers.append(index_number) | |
elif 'src' in elem.attrib: | |
for chapter in book.toc: | |
if item.get_name() == chapter.href: | |
image_href = elem.attrib.get('src')[3:] | |
index_number = page_names.index(image_href) | |
index_numbers.append(index_number) | |
# 5. PDFに目次情報を書き込み、右綴じ(R2L)にする | |
with pikepdf.Pdf.open(file_obj) as pdf: | |
outitem = [] | |
for chapter, index_number in zip(book.toc, index_numbers): | |
outitem.append(OutlineItem(chapter.title, index_number)) | |
with pdf.open_outline() as outline: | |
outline.root.extend(outitem) | |
pdf.Root.PageLayout = pikepdf.Name.TwoPageRight | |
pdf.Root.ViewerPreferences = pikepdf.Dictionary() | |
pdf.Root.ViewerPreferences.Direction = pikepdf.Name.R2L | |
pdf.save('output_outline_R2L.pdf') |
Ebooklibを使わずに、BeautifulSoupを使うバージョンを作成しました。
コマンドライン実行を想定していて、綴じ方なども指定できるように変更しました。
mashu3/epub2pdf
今後は、逆に画像のみのPDFから固定レイアウトのePubへの変換プログラム作成に取り組みたいと思います。