EPUB: 固定レイアウト(漫画)の作り方
コミックなどのEPUBは固定レイアウト形式となる。リフロー型を作成する時より、いくつか追加作業が発生するので手間がかかります。
例えば、パッケージドキュメントのmeta情報に固定レイアウト宣言や<manifest>に各画像パス/本文ファイルパスを登録するほか、1枚につき1ファイル(.xhtml)を用意する必要がある。
ただ、エディタ等で用意されているEmmet機能やファイル連番量産はPowerShellやbashを使えば比較的に簡単に作成できるのでそれについても併せて解説したいと思います。
本記事では、固定レイアウトEPUBの基本的な仕組みを解説するとともに、Emmetを活用してXHTMLファイルを効率よく作成する方法を紹介します。altにテキスト情報を入れる方法については解説していないのでご了承ください。
固定レイアウトについて
その名の通り、画像形式のEPUB(Fixed layout)のことを意味する。固定レイアウトを適用したい場合まずパッケージドキュメントのmetaに下記のように固定ページ宣言を記述する必要がある。
<?xml version="1.0" encoding="UTF-8"?>
<package version="3.0" unique-identifier="uid" xmlns="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata>
<dc:identifier id="uid">urn:uuid:763f8928-79bf-4bd8-82b6-488f5392d4e3</dc:identifier>
<dc:title>マンガ</dc:title>
<dc:language>ja</dc:language>
<dc:creator>漫画太郎</dc:creator>
<meta property="dcterms:modified">2026-10-17T06:45:25Z</meta>
<meta property="rendition:layout">pre-paginated</meta>
<meta property="rendition:orientation">auto</meta>
<meta property="rendition:spread">auto</meta>
<meta name="fixed-layout" content="true"/>
<meta name="book-type" content="comic"/>
<meta name="primary-writing-mode" content="horizontal-rl"/>
</metadata>
.....
pre-paginatedとは固定ページである宣言みたいなもの。これが必要になる。
また、rendition:orientationは端末の向きを指定する設定になります。portrait(縦向き)/landscape(横向き)/auto(端末に合わせる)3つの値を決めることができます。スマホやPCなどのマルチデバイスに対応するにはautoを使用するのが無難です。例えばlandscapeを使用してしまうと、PCでは表示は問題なくてもスマホだと強制的に横方向の表示になるので注意が必要です。ユーザーに自由を与えるためにautoでいいかと思います。
rendition:spreadは見開きの設定になります。両開きか単一のページにするかの設定です。これもいくつかオプションがありますがautoのほうがリーディングシステムで調整ができるのでautoでいいかと思います。例えばスマホの場合縦方向では単一のページですが横画面で表示することで見開きの設定が可能になるためです。
kindle対応させるには
通常コミックなどは右から左へと移動することが多いです。kindleに対応させるには上記のメタ情報だけでは不十分で下記の記述が必須になります。
fixed-layout…固定ページであるかの宣言primary-writing-mode…右から左へと設定したい場合はhorizontal-rl
<meta name="fixed-layout" content="true"/>
<meta name="primary-writing-mode" content="horizontal-rl"/>
詳細は公式の【テキスト ポップアップ付きの固定レイアウトの本を作成する】をご覧ください。
ファイル構造
固定レイアウトのEPUBを作る際の注意点があり、画像ファイルとxhtmlファイルの2つのフォルダーで管理することをお勧めします。何故かというと、修正数のが楽になるからです。例えば章ごとにBOOK-IMGのフォルダー内に複数のフォルダーがあると連番作成する際に複雑な処理を書かなくてはいけなくなるためです。
EPUB
│ mimetype
│
├─BOOK
│ │ package.opf
│ │ style.css
│ │
│ ├─cover
│ │ 1.jpg
│ │ cover.xhtml
│ │
│ ├─BOOK-IMG
│ │ 1.jpeg
│ │ ....
│ │ 300.jpeg
│ │
│ └─xhtml
│ nav.xhtml
│ page1.xhtml
│ ...
│ page300.xhtml
│
└─META-INF
container.xml
package.opf
下記のパッケージドキュメントは省略していますが、作るとわかりますが膨大な行になります。manifestにはページパスと画像のパスを登録する必要があるのでどちらも記述する必要があります。
spineにはページの読む順番の登録を行います。今回は右から左へ流れるコンテンツのためpage-progression-direction="rtl"と記述します。
表紙にはrendition:page-spread-centerと記述する。
また、固定レイアウトの場合見開きにも対応した記述をする必要がありpropertiesにrendition:page-spread-right / rendition:page-spread-leftを記述する必要があります。右から左へ移動するページの場合はじめをpage-spread-rightに設定し、次をpage-spread-leftと設定します。左から右のページを作成する場合はその逆になります(その場合page-progression-directionは不要)。
<?xml version="1.0" encoding="UTF-8"?>
<package version="3.0" unique-identifier="uid" xmlns="http://www.idpf.org/2007/opf" xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata>
<dc:identifier id="uid">urn:uuid:xxxxx</dc:identifier>
<dc:title>マンガ</dc:title>
<dc:language>ja</dc:language>
<dc:creator>漫画太郎</dc:creator>
<meta property="dcterms:modified">2026-10-17T06:45:25Z</meta>
<meta property="rendition:layout">pre-paginated</meta>
<meta property="rendition:orientation">auto</meta>
<meta property="rendition:spread">auto</meta>
<meta name="fixed-layout" content="true"/>
<meta name="primary-writing-mode" content="horizontal-rl"/>
</metadata>
<manifest>
<item href="cover/cover.xhtml" media-type="application/xhtml+xml" id="cover"/>
<item href="cover/1.jpg" media-type="image/jpeg" id="cover-image" properties="cover-image"/>
<item href="style.css" media-type="text/css" id="css"/>
<item href="xhtml/nav.xhtml" media-type="application/xhtml+xml" id="nav" properties="nav"/>
<item href="xhtml/page1.xhtml" media-type="application/xhtml+xml" id="page1"/>
<item href="xhtml/page2.xhtml" media-type="application/xhtml+xml" id="page2"/>
....
<item href="xhtml/page332.xhtml" media-type="application/xhtml+xml" id="page332"/>
<!-- BOOK-IMG -->
<item href="BOOK-IMG/1.jpeg" media-type="image/jpeg" id="img1"/>
<item href="BOOk-IMG/2.jpeg" media-type="image/jpeg" id="img2"/>
<item href="BOOk-IMG/3.jpeg" media-type="image/jpeg" id="img3"/>
<item href="BOOk-IMG/4.jpeg" media-type="image/jpeg" id="img4"/>
<item href="BOOk-IMG/5.jpeg" media-type="image/jpeg" id="img5"/>
....
<item href="BOOk-IMG/332.jpeg" media-type="image/jpeg" id="img332"/>
</manifest>
<spine page-progression-direction="rtl">
<itemref idref="cover" properties="rendition:page-spread-center"/>
<itemref idref="page1" properties="page-spread-right"/>
<itemref idref="page2" properties="page-spread-left"/>
<itemref idref="page3" properties="page-spread-right"/>
<itemref idref="page4" properties="page-spread-left"/>
<itemref idref="page5" properties="page-spread-right"/>
<itemref idref="page6" properties="page-spread-left"/>
.....
<itemref idref="page332" properties="page-spread-left"/>
</spine>
</package>
rendition:page-spread-rightとrendition:page-spread-leftと記述しないのはKindleだと左右分割ができないので消しています。
page.xhtml
続いてxhtmlフォルダに格納する連番ページのテンプレートになります。ここではテンプレートの作成を行い、後述で解説します。
本文ページはalt情報を抜く場合かなりシンプルに作成できます。リフロー型と違うのはmetaにviewportの設定が必要なところです。
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
<title>マンガ</title>
<meta name="viewport" content="width=800, height=1200"/>
<link rel="stylesheet" href="../style.css" type="text/css"/>
</head>
<body>
<img src="../BOOK-IMG/NUM.jpeg" alt=""/>
</body>
</html>
style.css
もし画像をリーディングシステムに合わせたサイズにしたい場合下記のようにCSSを記述します。
html, body{
margin: 0;
padding: 0;
width: 800px;
height: 1200px;
}
img{
width: 800px;
height: 1200px;
}
Emmet/シェルスクリプトを使用した連番作成
VSCodeの場合Emmet機能を使うにはsetting.jsonに下記を追記する必要がります。
// Emmet
"files.associations": {
"*.opf": "xml"
},
"emmet.triggerExpansionOnTab": true,
"emmet.includeLanguages": {
"xml": "html",
"opf": "html"
},
パッケージドキュメントファイルを開き下記に記載したコードを入力した後にTabを押すと300行のitem属性が作成されます。もし></item>は/>と置換しておいてください。
item[href="BOOK-IMG/$.jpeg" media-type="image/jpeg" id="img$"]*300
続いてspineに見開きを設定したファイルの読み込み順をEmmetを使い作成します。いったん、右だけのページを生成します。
itemref[idref=page$ properties=page-spread-right]*300
続いて余分な></itemref>を/>へ置換します。
偶数をleftへ変換したいので下記の正規表現を使い置換します。
# 検索
(idref="page\d*[02468]") properties="page-spread-right"
# 置換
$1 properties="page-spread-left"
PowerShellを使った連番ファイル作成
先ほど作成した下記のファイルを300ページ分作成していきます。シェルスクリプトを使えばこのような量産はたやすいです。例がpowershellで申し訳ないが。
<?xml version="1.0" encoding="UTF-8"?>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops">
<head>
<title>マンガ</title>
<meta name="viewport" content="width=800, height=1200"/>
<link rel="stylesheet" href="../style.css" type="text/css"/>
</head>
<body>
<img src="../BOOK-IMG/NUM.jpeg" alt=""/>
</body>
</html>
PowerShellを起動して下記のコードを実行することでxhtmlフォルダー内に320件のpage.xhtmlファイルが作成されます。一行目の"page.xhtml"がテンプレート用のファイルのパスになります。なのでルートディレクトリからアクセスするにはEPUB/BOOK/XHTML/page.xhtmlと指定する必要があります。
また、Set-Content -Path "BOOK/xhtml/page$n.xhtml"は作成するディレクトリ先を指定します。
$template = Get-Content -Path "page.xhtml" -Raw
$imageNumber = 1
1..332 | ForEach-Object {
$n = $_
$content = $template.Replace("NUM", "$imageNumber")
Set-Content -Path "BOOK/xhtml/page$n.xhtml" -Value $content -Encoding utf8
$imageNumber++
}
画像圧縮ソフト
大量の画像になると膨大なデータになります。リーディングシステムによっては制限があるので可能な限り圧縮をしましょう。おすすめなのがCaesium Image Compressorというソフトになります。すべてのOSに対応しているので便利です。