Les ePubs ont déjà pas mal d’historique et d’implémentations divergentes. Je fouillais ces jours ci les différentes méthodes pour trouver l’image de couverture. J’ai probablement du louper des choses, mais ça servira probablement à d’autres.
Avant toute chose, il faut ouvrir l’ePub à l’aide de unzip
unzip exemple.epub
Puis repérer l’adresse de l’OPF dans le fichier META-INF/container.xml
. Attention à ne pas rechercher manuellement un fichier content.opf
à la racine de l’ePub. Si c’est souvent là qu’il se trouve, ce n’est pas toujours le cas.
L’adresse de l’OPF est dans l’attribut @full-path
de la balise <rootfile>
avec le media-type
« application/oebps-package+xml ». S’il existe plusieurs correspondances, c’est la première qui doit être utilisée.
<?xml version="1.0"?> <container version="1.0" xmlns="urn:oasis:names:tc:opendocument:xmlns:container"> <rootfiles> <rootfile full-path="Ops/content.opf" media-type="application/oebps-package+xml"/> </rootfiles> </container>
C’est dans ce fichier OPF que tout va se passer. Voici mes quatre méthodes pour trouver les couvertures, à essayer par ordre de priorité :
1– Rechercher une balise <meta>
avec pour nom « cover ». Si elle existe, son contenu référence la balise <item>
qui contient la couverture.
En XPath, le chemin de la couverture donnerait quelque chose comme //item[id=//meta[name='cover']/@content]/@href
<?xml version="1.0" encoding="UTF-8"?> <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="BookId"> <metadata xmlns:opf="http://www.idpf.org/2007/opf"> <meta name="cover" content="img1"/> </metadata> <manifest> <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml"/> <item id="style" href="style.css" media-type="text/css"/> <item id="id1" href="1.html" media-type="application/xhtml+xml"/> <item id="id2" href="2.html" media-type="application/xhtml+xml"/> <!-- ... --> <item id="id13" href="13.html" media-type="application/xhtml+xml"/> <item id="img1" href="images/img1.jpg" media-type="image/jpeg"/> <item id="img2" href="images/img2.jpg" media-type="image/jpeg"/> </manifest> </package>
2– Rechercher, dans la liste des <item>
celui qui a « cover-image » dans son attribut @properties
. Il faut regarder l’ensemble de l’attribut. Ce dernier peut contenir plusieurs valeurs séparées par des espaces.
En XPath ce serait quelque chose de proche de //item[@properties and contains(@properties,'cover-image')]/@href
<?xml version="1.0" encoding="UTF-8"?> <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="BookId"> <metadata xmlns:opf="http://www.idpf.org/2007/opf"></metadata> <manifest> <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml"/> <item id="style" href="style.css" media-type="text/css"/> <item id="id1" href="1.html" media-type="application/xhtml+xml"/> <item id="id2" href="2.html" media-type="application/xhtml+xml"/> <!-- ... --> <item id="id13" href="13.html" media-type="application/xhtml+xml"/> <item properties="cover-image" id="img1" href="images/img1.jpg" media-type="image/jpeg"/> </manifest> </package>
3– Rechercher, dans la liste des <reference>
du <guide>
, la première avec « cover » comme attribut @type
. Le fichier référencé pourra être un fichier XHTML. Dans ce cas je considère comme couverture la première <img>
de taille égale ou supérieure à 200×200 pixels (oui, c’est moche, mais je n’ai pas trouvé mieux).
En XPath ce serait quelque chose de proche de //reference[@type='cover']/@href
en n’oubliant pas ensuite qu’on obtient un fichier XHTML et non une image.
<?xml version="1.0" encoding="UTF-8"?> <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="BookId"> <metadata xmlns:opf="http://www.idpf.org/2007/opf"></metadata> <manifest> <item id="ncx" href="toc.ncx" media-type="application/x-dtbncx+xml"/> <item id="style" href="style.css" media-type="text/css"/> <item id="id1" href="1.html" media-type="application/xhtml+xml"/> <!-- ... --> <item id="id13" href="13.html" media-type="application/xhtml+xml"/> </manifest> <guide> <reference type="cover" title="Cover image" href="1.html"/> </guide> </package>
4– Enfin, à défaut de mieux, je descend les trois premiers <item>
du <manifest>
jusqu’à trouver une <img>
de taille égale ou supérieure à 200×200 pixels (oui, c’est encore plus moche que précédemment, je sais)
<?xml version="1.0" encoding="UTF-8"?> <package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="BookId"> <metadata xmlns:opf="http://www.idpf.org/2007/opf"></metadata> <manifest> <item media-type="application/x-dtbncx+xml"id="ncx" href="toc.ncx" /> <item media-type="text/css" id="style" href="style.css" /> <item media-type="application/xhtml+xml" id="id1" href="1.html" /> <item media-type="application/xhtml+xml" id="id2" href="2.html" /> <item media-type="application/xhtml+xml" id="id3" href="3.html" /> <item media-type="application/xhtml+xml" id="id4" href="4.html" /> <!-- ... --> <item id="id13" href="13.html" media-type="application/xhtml+xml"/> </manifest> </package>
Malgré cela, certains livres n’ont pas de couverture, et d’autres auront une couverture SVG qui ne sera pas récupérable, même si c’est rare. Si vous voulez compléter ou préciser, n’hésitez pas.
Laisser un commentaire