chainlpのepubを以前チェックしたときこれはepub2じゃんとか思った。余白除去やpdfやjpgからkoboやkindleで読めるように編集していくれる。画像からEPUBを作るには他に方法があるので、別にいらないという気もするが。余白除去や白抜きなどの機能があれば便利かなと色々いじってみた。
You:
最小限の機能から実装したい PDFや画像ZIPを画像として取り出す 画像の余白除去、白抜き 画像を固定レイアウトEPUBとして出力
ChatGPT:
いい切り分けです。
その3点なら ChainLPの“核の一部”を、かなり小さく・確実に作れます。
以下は **「最小構成・失敗しにくい実装順」**で整理します。
(Electron+Node.js前提、Windows想定)
🎯 目標(最小構成)
PDF / 画像ZIP → 画像抽出
画像の余白除去・白抜き
画像を固定レイアウトEPUB(Kindle対応)として出力
👉 縦書き・テキスト解析・ルビなし
👉 完全に「画像本」特化
1️⃣ 全体アーキテクチャ(最小)
Electron UI
├─ ファイル選択
├─ プレビュー(前後ページ)
└─ 実行ボタン
↓
Node.js 変換エンジン
├─ PDF / ZIP 解析
├─ 画像正規化
├─ 余白除去
└─ 固定レイアウトEPUB生成
UIは最低限でOK
→ ほぼCLIでも成立する構成
2️⃣ PDF / 画像ZIP → 画像抽出
■ 画像ZIPの場合(最優先・超簡単)
条件
zip内に
jpg/png/webp並び順=ページ順
使用ライブラリ
JSZipsharp
import JSZip from "jszip"
import fs from "fs"
const zip = await JSZip.loadAsync(fs.readFileSync("input.zip"))
for (const name of Object.keys(zip.files)) {
if (name.match(/\.(png|jpg|jpeg)$/i)) {
const buf = await zip.file(name).async("nodebuffer")
fs.writeFileSync(`tmp/${name}`, buf)
}
}
👉 まずはここから始めるのが正解
■ PDFの場合(最小構成)
ライブラリ
pdfjs-distcanvas(Node)
npm i pdfjs-dist canvas
PDF → ページ画像
const page = await pdf.getPage(i)
const viewport = page.getViewport({ scale: 2 })
const canvas = createCanvas(viewport.width, viewport.height)
await page.render({ canvasContext: canvas.getContext("2d"), viewport }).promise
👉 ChainLPでも同様のアプローチ
3️⃣ 画像の余白除去・白抜き(最重要)
■ 使用ライブラリ(確定)
✅ sharp
高速
Node標準
Electronと相性◎
npm i sharp
■ 最小の余白除去アルゴリズム
手法(安全)
グレースケール化
閾値で白判定
bounding box検出
crop
const image = sharp(input)
const { data, info } = await image
.grayscale()
.raw()
.toBuffer({ resolveWithObject: true })
白判定例:
pixel > 245 → 白
bounding box計算後:
image.extract({
left,
top,
width,
height
})
👉 まずは「四辺トリム」だけでOK
■ 白抜き(Kindle向け)
sharp(input)
.flatten({ background: "#ffffff" })
.toFile(output)
PNGの透明対策
Kindle表示崩れ防止
4️⃣ 固定レイアウトEPUB生成(核心)
■ 固定レイアウトEPUBの正体
.epub = ZIP ├─ mimetype ├─ META-INF/container.xml ├─ OEBPS/ │ ├─ content.opf │ ├─ nav.xhtml │ ├─ css/style.css │ ├─ text/page001.xhtml │ └─ images/page001.jpg
■ 画像1枚 = 1ページ(鉄板)
XHTML(最小)
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <link rel="stylesheet" href="../css/style.css"/> </head> <body> <img src="../images/page001.jpg" /> </body> </html>
■ 固定レイアウトOPF(超重要)
<meta property="rendition:layout">pre-paginated</meta> <meta property="rendition:orientation">portrait</meta> <meta property="rendition:spread">none</meta>
<item id="p1" href="text/page001.xhtml" media-type="application/xhtml+xml" properties="rendition:layout-pre-paginated"/>
👉 これがないとKindleで崩れる
■ CSS(最低限)
html, body { margin: 0; padding: 0; } img { width: 100%; height: 100%; object-fit: contain; }
■ EPUB書き出し
import JSZip from "jszip"
zip.file("mimetype", "application/epub+zip", { compression: "STORE" })
zip.file("META-INF/container.xml", containerXml)
zip.file("OEBPS/content.opf", opf)
5️⃣ 実装順(失敗しない)
✅ STEP 1
画像ZIP → 画像抽出
EPUB固定レイアウト出力
✅ STEP 2
余白除去
白抜き
✅ STEP 3
PDF対応
プレビューUI
6️⃣ この構成でできること
✔ スキャン漫画
✔ 同人誌PDF
✔ 古書PDF
✔ ChainLPの「画像系機能」再現
✔ AozoraEpub3と共存可能
次に進めるとしたら
🔜 余白検出アルゴリズムの精度向上
🔜 左右ページ分割
🔜 Kindle向け左右余白最適化
🔜 GUI最小構成(ドラッグ&ドロップ)
次は
👉 STEP1のコード雛形を全部まとめて出す
👉 EPUBテンプレを完全に書く
どちら行きますか?