zoukankan      html  css  js  c++  java
  • epub、ocf等常用电子书格式浅析----附JAVA示例程序

    一、 电子书介绍

    转载请注明http://www.cnblogs.com/xckk/p/6020324.html 

    Epub(Electronic Publication)是一个完全开放和免费的电子书标准。是一个自由的开放标

    准,属于一种可以“自动重新编排”的内容。

    “自动重新编排”的原因是内部使用XHTML来展现文件的内容,用一系列CSS来定义格式和版面设计,达到了内容和编排的分离。

    现在EpubEpub包括三项主要规格:

    开放出版结构(Open Publication Structure,OPS)2.0,以定义内容的版面;

    开放包裹格式(Open Packaging Format,OPF)2.0,定义以XML为基础的.epub档案结构;

    开放容器格式(OEBPS Container Format,OCF)3.0,将所有相关文件收集至ZIP压缩档案之中。

    OPS规范的目的是为内容提供者(例如出版商、作者等)和出版工具提供者提供一个最小的通用指导,以保证电子内容能够在各种阅读系统中保持一致性。

    OPS用XHTML来构筑书的内容,用CSS来定义书的格式和版面设计等

    OPF规范则定义了将各种OPS出版组件连接在一起的机制,并为其提供附加的结构和语言。OPF规范与OPS规范是分开的,目的是将内容描述技术和包装描述技术模块化。

    OCF定义了将所有电子出版组件包装成一个单一档案进行传播、递送和存档的标准机制。是一种打包机制。

    相关规范文档:

    OPS2.0规范:http://www.idpf.org/epub/20/spec/OPS_2.0.1_draft.htm

    OPF2.0规范:http://www.idpf.org/epub/20/spec/OPF_2.0.1_draft.htm

    OCF规范:http://www.idpf.org/epub/301/spec/epub-ocf.html

    二、 EPUB基础知识介绍

    打开方式

    epub可以用stanza的PC版打开,也可以用FirefoxChrome上的相应的插件。

    Firefox EpubReader 扩充组件:EPUBReader是一个可以阅读ePub格式文件的Firefox扩充程序。你无须安装额外的软件,在Firefox浏览器中便可阅读ePub格式文件,推荐这个。

    文件解析

    一个 EPUB 就是一个简单 ZIP 格式文件(使用 .epub 扩展名),其中包括按照预先定义的方式排列的文件。除此以外,EPUB 非常简单。只需将后缀改为.zip或.rar,解压即可看到里面的文件内容。如下图

    0

    一个epub电子书的zip大致包含以下东西:

    1、mimetype 文件,必须是压缩包的第一个文件。注意,mimetype必须是非压缩格式。

    2、META-INF目录,里面至少包含一个container.xml 文件。

    3、OEBPS目录(可以是别的名字,但建议用这个名字),包含了:

    a) image子目录(不一定总有)存放了所有的图片文件

    b) content.opf 文件名可以是其它的,扩展名一定是opf,就是一个xml格式的包内的文件列表

    c)  toc.ncx 目录文件,一个“逻辑目录”, 浏览控制文件.

    d) 一些xhtml或html文件。就是书的内容。

    简单 EPUB 档案的目录和文件结构:

    mimetype

    META-INF/

       container.xml

    OEBPS/

      content.opf

      title.html

      content.html

      stylesheet.css

      toc.ncx

      images/

         cover.png

    一个完整的epub格式电子书,OPF文件一般包括OEBPS目录下的 .opf和 .ncx文件。

    1、.opf文件

    包括四个元素:metadata, manifest, spine, guide

    (1)metadata: epub的元数据,如title、language、identifier、cover等。其中,title 和 identifier这两个数据是必须的。按照EPUB规范,identifier由数字图书的创建者定义,必须唯一。对于图书出版商来说,这个字段一般包括ISBN或者Library of Congress编号;也可以使用URL或者随机生成的唯一用户ID。注意:unique-identifier 的值必须和 dc:identifier 元素的 ID 属性匹配。

    1

    (2)manifest:列出了目录中所包含的所有文件(xhtml、css、png、ncx等)。EPUB 鼓励使用 CSS 设定图书内容的样式,因此 manifest标签下也包含 CSS文件。注意:进入数字图书的所有文件都必须在 manifest 中列出,manifest只列出文件,未列出文件之间的结构顺序。

    2

    3

    3)spine:所有xhtml文档的线性阅读顺序。其中,spine标签的toc属性必须包含在manifest列出来的.ncx的id。可以将 OPF spine 理解为是书中 “页面” 的顺序,解析的时候按照文档顺序从上到下依次读取 spine。

    在spine中的每个 itemref 元素都需要有一个 idref 属性,这个属性和 manifest 中的某个 ID 匹配。

    4

    2、.ncx文件

    ncx 定义了数字图书的目录表。复杂的图书中,目录表通常采用层次结构,包括嵌套的内容、章和节。包含了toc(tablet of content,提供了分段的一些信息)。ncx的 <head> 标记中包含四个 meta 元素:

    uid:数字图书的惟一ID。该元素和 OPF 文件中的 dc:identifier 对应。

    depth:反映目录表中层次的深度。

    totalPageCount 和 maxPageNumber:仅用于纸质图书,保留 0 即可。

    docTitle/text 的内容是图书的标题,和 OPF 中的 dc:title 匹配。后面的示例程序是对该标题进行更改。

    navMap定义了图书的目录,是 ncx 文件中最重要的部分。navMap 包含一个或多个 navPoint 元素,每个 navPoint 都要包含下列元素:

    playOrder:说明文档的阅读顺序。和 OPF spine 中 itemref 元素的顺序相同。

    navLabel/text :给出该章节的标题。通常是章的标题或者数字。

    content :它的 src 属性指向包含这些内容的物理资源。就是 OPF manifest 中声明的文件。

    还可以有一个或多个 navPoint 元素。ncx 使用嵌套的导航点表示层次结构的文档

    5

    3、.opf的spine和.ncx文件有什么不同?

    Spine标签描述文档顺序,.ncx文件描述目录。

    两者很容易混淆,因为两个文件都描述了文档的顺序和内容。要说明两者的区别,最简单的办法就是拿印刷书来打比方:.opf文件的spine标签描述了书中的各个章节是如何实际连接起来的,比方说翻过第一章的最后一页就看到第二章的第一页。.ncx在图书的一开始描述了目录,目录肯定会包含书中主要的章节,但是还可能包含没有单独分页的小节。

    一条法则是ncx包含的 navPoint 元素通常比 opf spine中的itemref 元素多。实际上,spine 中的所有项都会出现在 .ncx 中,但.ncx可能更详细。

    三、ocf格式电子书介绍

    咪咕阅读制作的电子书是.ocf格式,与EPUB所规定的大部分格式与展现标准相同,并且对其进行扩展,重点解决了版面丰富性、格式开放性和文档安全性、可交换性、可扩展性、可裁剪性。适用于手机、手持阅读终端等设备。

    ocf格式的图书经过内部的图书入库、章节拆分与压缩、加密以及MEB打包后,形成.meb作为扩展名的电子书,就可以上架供客户端解析阅读了。

    OCF包的目录结构:

    OCF
    
    │ mimetype
    
    ├─META-INF
    
    │ │ book.ncx
    
    │ │ book.opf
    
    │ │ container.xml
    
    │ │ cover.xml
    
    │ │ right.xml
    
    │ └─ext
    
    │ cover180240.jpg
    
    │ cover5168.png
    
    │ cover600800.jpg
    
    │ cover6080.jpg
    
    │ cover75100.jpg
    
    │ cover81108.png
    
    │ cover90120.jpg 
    
    └─oebps
    
    ├─chapter01
    
    │ │ chapter01.html 
    
    │ ├─css
    
    │ │ style.css 
    
    │ └─images
    
    │ ├─128
    
    │ │ Image0.jpg 
    
    │ ├─176
    
    │ │ Image0.jpg 
    
    │ ├─240
    
    │ │ Image0.jpg 
    
    │ ├─320
    
    │ │ Image0.jpg 
    
    │ ├─360
    
    │ │ Image0.jpg 
    
    │ ├─480
    
    │ │ Image0.jpg 
    
    │ └─orig
    
    │ Image0.jpg 
    
    ├─chapter02
    
    │ │ chapter02.html 
    
    │ ├─css
    
    │ │ style.css 
    
    │ └─images
    
    │ ├─128
    
    │ │ Image0.jpg 
    
    │ │ Image1.jpg 
    
    │ ├─176
    
    │ │ Image0.jpg
    
    │ │ Image1.jpg
    
    │ ├─240
    
    │ │ Image0.jpg
    
    │ │ Image1.jpg
    
    │ ├─320
    
    │ │ Image0.jpg
    
    │ ├─360
    
    │ │ Image0.jpg
    
    │ ├─480
    
    │ │ Image0.jpg 
    
    │ └─orig
    
    │ Image0.jpg
    
    │ Image1.jpg

    文件名与目录名的描述如下:

    文件名/目录名

    描述

    类型

    限定

    mimetype

    Mime类型描述文件

    Ascii文件

    必选

    META-INF/

    Meta信息目录

    目录

    必选

    container.xml

    容器描述文件

    Xml文件

    必选

    book.opf

    图书元数据描述文件,如书名、作者信息

    Xml文件

    必选

    book.ncx

    描述图书的目录结构信息

    Xml文件

    必选

    cover.xml

    封面内容文件

    Xml文件

    必选

    right.xml

    权利描述文件

    Xml文件

    可选

    ext/

    MEB文件扩展目录

    目录

    可选

    coverWH.jpg

    coverWH.png

    封面图片

    jpg/png文件

    可选

    oebps/

    MEB内容信息目录

    目录

    必选

    chapterXX/

    章节目录

    目录

    必选

    chapterXX.html

    页内容页面

    xHtml文件

    /

    images/

    图片目录

    目录

    可选

    orig

    原图存放目录

    目录

    可选

    128

    特定分辨率图片存放目录

    目前分辨率有128、176、240、320、360、480、600(600没有单独的目录,因为600及600以上宽度的图片,只需要在orig中存在)

    目录

    可选

    Image0.jpg

    图片文件

    Orig存放的是原图,如果章节引用了图片,则该目录肯定有图片;128-480目录,如果原图宽度大于目录名称值的,才会有文件,如图片宽度为300,则在orig、128、176、240中会有对应压缩后的图片文件。

    jpg/png

    可选

     

    四、 JAVA解析epub格式电子书示例

    文章最后提供一下解析epub电子书的示例程序。程序的主要功能是读取修改.epub格式文件的

    相关材料和源码均在链接中可以下载:http://pan.baidu.com/s/1bnm8YXT

    包括

    1、JAVA项目工程test_epub,里面包括了jar包和一本epub电子书myBook.epub

    2、epub相关jar包(epublib-codr-lastest.jar、以及slf4j-*.jar)

    3、电子书myBook.epub

    JAVA解析.epub格式电子书,具体实现代码如下。写了一个简单helloWorld程序,加入了相应的jar包。

    程序说明:

    1、读取epub/myBook.epub文件。

    2、修改metaData中的title

    3、输出新的.epub文件到工程目录下。文件名mynewbook.epub

    通过解压mynewbook.epub文件,可以看到toc.ncx文件中的<docTitle>和content.opf中的<dc:title>标签内容都进行了修改。


    package com.hk;
    
    import java.io.FileInputStream;
    
    import java.io.FileNotFoundException;
    
    import java.io.FileOutputStream;
    
    import java.io.IOException;
    
    import java.io.InputStream;
    
    import java.io.OutputStream;
    
    import java.util.ArrayList;
    
    import java.util.List;
    
    import nl.siegmann.epublib.domain.Book;
    
    import nl.siegmann.epublib.epub.EpubReader;
    
    import nl.siegmann.epublib.epub.EpubWriter;
    
    /**
    
    * 
    
    * epub格式文件读和写示例程序
    
    * @author hk
    
    * @version [版本号, 2015年11月26日]
    
    * @see [相关类/方法]
    
    * @since [产品/模块版本]
    
    */
    
    public class TestEpub
    
    {
    
    public static void main(String[] args)
    
    {
    
    System.out.println("hello world");
    
    // 获得电子书路径
    
    String epubPath = getEbookPath();
    
    // 读epub文件
    
    Book book = readBook(epubPath);
    
    // 修改电子书
    
    modifyBook(book);
    
    String outputFileName = "mynewbook.epub";
    
    writeBook(book, outputFileName);
    
    }
    
    /**
    
    * 获得电子书路径
    
    * 
    
    * @return
    
    * @see [类、类#方法、类#成员]
    
    */
    
    private static String getEbookPath()
    
    {
    
    // 得到的currentPath = file:/E:/study/epub/test_epub/bin/,其中E:/study/epub/test_epub是工程路径
    
    String currentPath = Thread.currentThread().getClass().getResource("/").toString();
    
    String epubPath = currentPath + "epub/myBook.epub";
    
    // 去年路径中的前缀//file:/
    
    epubPath = epubPath.substring(6, epubPath.length());
    
    epubPath = epubPath.replace("/", "//");
    
    System.out.println(epubPath);
    
    return epubPath;
    
    }
    
    /**
    
    * 读epub文件
    
    * 
    
    * @return
    
    * @see [类、类#方法、类#成员]
    
    */
    
    private static Book readBook(String epubPath)
    
    {
    
    EpubReader epubReader = new EpubReader();
    
    Book book = null;
    
    try
    
    {
    
    InputStream inputStr = new FileInputStream(epubPath);
    
    book = epubReader.readEpub(inputStr);
    
    }
    
    catch (FileNotFoundException e)
    
    {
    
    e.printStackTrace();
    
    }
    
    catch (IOException e)
    
    {
    
    e.printStackTrace();
    
    }
    
    return book;
    
    }
    
    /**
    
    * 修改电子书 本处修改了toc.ncx文件中的<docTitle>和content.opf中的<dc:title>标签内容.
    
    * 
    
    * @param book
    
    * @see [类、类#方法、类#成员]
    
    */
    
    private static void modifyBook(Book book)
    
    {
    
    // 设置epub文件内title.
    
    List<String> titlesList = new ArrayList<String>();
    
    titlesList.add("test book");
    
    book.getMetadata().setTitles(titlesList);
    
    }
    
    /**
    
    * 输出电子书
    
    * 
    
    * @param book
    
    * @param fileName
    
    * @see [类、类#方法、类#成员]
    
    */
    
    private static void writeBook(Book book, String fileName)
    
    {
    
    // write epub
    
    EpubWriter epubWriter = new EpubWriter();
    
    try
    
    {
    
    OutputStream ouput = new FileOutputStream(fileName);
    
    epubWriter.write(book, ouput);
    
    }
    
    catch (FileNotFoundException e)
    
    {
    
    e.printStackTrace();
    
    }
    
    catch (IOException e)
    
    {
    
    e.printStackTrace();
    
    }
    
    }
    
    }

    文章参考了work hard work smart的技术博客

    http://www.cnblogs.com/linlf03/archive/2011/12/13/2286218.html

    程序实现博客http://www.cnblogs.com/xckk/p/4598196.html

    秀才坤坤出品

  • 相关阅读:
    C#设计模式之订阅发布模式
    ASP.NET Core依赖注入(DI)
    ASP.NET 开源导入导出库Magicodes.IE 完成Csv导入导出
    .NET IoC模式依赖反转(DIP)、控制反转(Ioc)、依赖注入(DI)
    曾经优秀的人,怎么就突然不优秀了?
    IDEA中文注释难看的简单解决办法
    JasperReport报表中输出Excel时,部分列不显示的问题
    为什么Spring Security看不见登录失败或者注销的提示
    JQuery文件上传插件JQuery.upload.js的用法简介
    一个很酷炫也挺实用的JS库leader-line
  • 原文地址:https://www.cnblogs.com/xckk/p/6020324.html
Copyright © 2011-2022 走看看