Calibre中epub、mobi或pdf间转换格式图片变形的问题

背景

前段时间因为想学英语,偶然发现 Calibre 可以订阅纽约时报、经济学人等周刊杂志看,便开始使用 Calibre 中 fetch news 功能定期下载订阅。因想在阅读英文杂志过程中使用划词翻译并添加生词到 Anki,所以将原 mobi 格式的文件转换成 pdf 格式在 Chrome 上使用 pdf.js 观看。

正常来说,事情到这里便已经结束了。可尝到 Calibre 订阅的乐趣后,更确切地说是认为看杂志比看新闻效益高之后,觉得不如少看些 rss 新闻多订阅些杂志,于是今天在 Calibre 下载了国家地理杂志。然而,当面对大量图片的杂志时,之前可以略过的小瑕疵现在却不能视而不见。就现象上来说,无论是 epub、mobi 还是转换后的 pdf 文件,杂志的图片均发生了长宽比例不协调的情况,也就是图片发生了形变。

探究问题

  1. 排除源文件中图片的问题。

将下载的 mobi 转换为 zip 格式,解压后可得到 html 源文件。查看解压后的 image 文件夹后发现原本的图片并没有任何问题。

最初也怀疑过是否是源文件的问题,使用英文搜索问题,得到这个解答问题的方法,并且回答者给出可能是 css 导致的问题。

  1. 原来是自带阅读器的锅,事实上大部分 mobi 或 epub 阅读器都会针对窗口大小进行缩放。

再稍加搜索,在 mobileread 网站上有位叫 pbw 的用户抓取 The Australian ,针对同样图片变形的问题提问。在回复中作者提及到了本质的问题

Would it work to set max-height to a ratio-preserving value? Or is max-height a second-class citizen in the viewers? Incidentally, iBooks.app does seem to scale in both dimensions. Obviously, the app environment gives them a lot more flexibility. Even so, iBooks has very restricted MathML support."

接下来的回复中有人也验证了他的观点:

A max-anything is only an upper limit. The viewer is free to resize the other dimension however it likes. Now as long as you dont set the width or height explicitly on the image, most viewers will resize them preserving aspect ratio. If you do set the width or height explicitly, then aspect ratio will be lost. So in your html, simply remove the explicit width/height setting and you will be fine.

至此我才明白,原来多数阅读器在阅读 mobi 或 epub 电子书时,都会发生形变。我使用 iBook 打开原本使用 Calibre 默认阅读器会出现问题的 epub 文件,果然 iBook 能显示电子书中图片的正常比例。

  1. iBook 能正常看 epub,但如何使转换后的点子书不发生图片形变呢?

同样在 mobileread 论坛,Calibre 的作者 kovidgoyal 曾经回答过一个类似的问题。不过,显然提问的人不太清楚问题缘由,故而作者可能没意思到时阅读器所导致的。

好在另一个提问帖子中有人给出了答案,提到修改 css 或者 html 样式的办法。

Calibre only resizes the image file, it doesn't change the CSS or HTML styles for the images. This means that the image will only be displayed at the resized size if there are no CSS or HTML styles affecting the size. If the size is being set in CSS or HTML then all that happens is that the downsized image gets scaled up again resulting in a poor quality rendering on screen.

First of all don't set the output type to "Kobo", because this refers to the original ancient Kobo devices that had extremely low resolution screens. Instead use "Tablet" so that the image file doesn't get resized.

Second, you will usually need to edit the CSS or HTML styles so that the image displays at the size you want. E.g. if you want a map to fill the avaliable screen (i.e. changing the aspect ratio to match the available screen) then use height:100%; width:100%; for the img object. Or if you want to display the image as large as will fit on the screen but retaining the original aspect ratio then use height:100%; width:auto; max-width:100%; for images with a taller aspect ratio than the screen, or height:auto; max-height:100%; width:100%; for images with a wider aspect ratio than the screen. Alternatively you can use <svg> styles to resize the image which gives more control than <img>.

(If you don't care about the aspect ratio and the only problem is that the images are too big for the screen then you might get away with just adding img {max-height:100%; max-width:100%;} to the book's stylesheet.)

具体操作下来,我发现上述中第一步也没有必要,默认 Kindle PaperWhite 3 输出设置也可以。事实上,之前搜索相关问题,有人提及将转换的页面设置为 Tablet 就好了,可是现在我们得知问题其实出在阅读器上。

针对具体问题,回帖中有人更进一步,在帖子 8 楼给出了一套替换的代码。

我的解决方法

可惜我看不太懂代码,只知道是 Calibre 中的一个 class 的问题,可是怕修改后影响到之后其它文件的样式,不敢做太多的改动。目前我的需求只为转换后的 pdf 文件中图片不要变形。

于是最简单的方法,在转换 pdf 格式中的转换>界面外观>样式中的附加样式css添加:

img {
    height: auto;
    max-height: 100%;
    width: 100%
    }

这样 PDF 电子书中的图片保持了原本的大小,自然不会有形变。

当然这样也不完美,如果图片的像素尺寸大于输出页面设置的尺寸,应该会发生裁剪掉一部分图片的现象吧。不过好在我仅仅是在电脑上看 PDF,页面设置默认选项 Kindle PaperWhite 3 的 1072*1430 像素尺寸已经足够大了。

评论

此博客中的热门博文

1206 - 荣耀手环4连接到 Google Fit 的问题

用户体验设计面试中的 7 个问题(如何为此准备)