Create e-book from scans

Reading a manga or, generally, a book in paper may be cumbersome because of its weight. To solve it, you can scan your book and make it an e-book („scanbook“) to use it in your e-book reader. Here’s how to compile the scans into a usable e-book.


  • ImageMagick‚s convert,
  • cwebp tool to efficiently compress the scans into a reasonable data size, and
  • Calibre to compile them into an e-book format of your choice.

This article is an extension of the Crop and split book scan in 3 commands article I wrote a few years ago.

Scan the book

When scanning, try to use the same dimensions for all the scans. Be it double pages or single pages, this makes it easier when splitting and cropping the scans later on.

Use consecutive numbering for the scans so that you don’t get lost in how the scans follow each other. I recommend using Xsane for scanning as it has the numbering functionality included.

In the example here, I have files named page-01.png, page-02.png, etc.

Split the double pages into series of single pages

Use ImageMagick’s convert to split the pages automatically. The command is:

convert `ls page-*.png` -rotate 90 -crop 3704x1852+160+20 +repage -crop 50%x100% page-split.png
  • The -rotate 90 rotates the scans because my scans were in portrait layout, while I needed them to be in landscape. If you don’t need to rotate the images, leave it out.
  • The -crop option takes the argument in this format: `OUTPUTWIDTHxOUTPUTHEIGHT+OFFSETX+OFFSETY.
    • Offsets (X and Y) are where you want to set the 0,0 coordinates – this is useful if your scans have borders you want to get rid of. The height and width are dimensions of the resulting single page. This isn’t for resizing, it’s just for convert to know which section of the input image to use.
  • The +repage option resets the coordinates after crop. If you don’t need to use the first -crop, you can leave +repage out.
  • The second -crop with percents splits double pages to single pages. Its argument is XxY and the values are in percents of the whole input (already cropped and resized at the point).
    • The Y size remains 100% if you don’t need to split pages vertically.
    • The 50% value for X means the page will be split exactly in half. You need to adjust this according to where the spine of your book is in the images (ie., where the two pages of the double page meet).

To get these values, open your scan in GIMP and use the Rectangle select tool that shows its position in the image when you hover over the image. To calculate the percent value where your book spine is (ie., where to split the double page), you probably need to use the rule of three. With a double page of 4000px and the splitting line on 2500px:

  • the whole double page width is 4000, that is 100 %;
  • the split is 2500px, that is X %;
  • that means 2500 ÷ 4000 × 100 = 62.5 is the percentage of the whole double page width where you want to split it.

ImageMagick’s convert outputs files named page-split-01.png , ...-02.png, and so on.

See the Troubleshooting section if you get convert-im6.q16: cache resources exhausted file @ error/cache.c/OpenPixelCache/4095 or something similar when trying to process dozens of pages.

Convert the PNGs to WEBPs

If your book is in color and has many pages, the PNGs take too much data space. Sure, at this point, you can use

convert `ls pages-split*` -page 100%x100% result.pdf

to convert them to JPGs and put them into PDF, but JPG is a very unsuitable (read: bad) format for images with text and it’s going to look ugly while still pretty big (datasize-wise).

Use WEBP. With quality setting on 50, you’ll get from a PNG of 4.5 MB a WEBP of 250 kB with almost impercievable quality loss.

To convert to WEBP, you need the appropriate library for it:

sudo apt install webp

For other than Debian-based systems and details, see How to Convert Images to WebP Format in Linux.

To convert all the PNGs to WEBP, use a one-liner:

for f in `ls *png`; do cwebp -q 50 $f -o $f.webp; done;

Compile the e-book

You can’t simply stack the WEBPs into a PDF because the nearest format to WEBP that PDF supports it JPG, and, as I said above, you really don’t want that for images that contain text.

Fortunately, EPUB supports WEBP well, MOBI apparently does somewhat, too.

Use Calibre to compile the images into an e-book.

Prepare the input for Calibre

Create an HTML document that links all the images (pages) you want in your e-book:

<!DOCTYPE html>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>The name of the book</title>
		<img src="cover-start.webp" />
		<img src="page-split-00.png.webp" />
		<img src="page-split-01.png.webp" />
		<img src="cover-end.png.webp" />

Save that into the same directory as where the WEBP scans are and open it in a browser to check the images load fine.

Compile the e-book in Calibre

  1. Open Calibre
  2. Click Add books
  3. Select the HTML file you’ve created above
  4. Enter the metadata (more is better, you’ll thank yourself in the future)
  5. Click Save

Export the e-book into a desired format

  1. Click Convert books
  2. Select the output format
  3. Click OK.
  4. Click Save to disk and select location for the files.
  5. Click OK

There are many formats to choose from, I tried only EPUB, AZW3 and MOBI. EPUB is the best in terms of size. However, Kindle Paperwhite doesn’t support EPUB. The Amazon proprietary AZW3 is unusable, because where the EPUB was 15 MB large, the AZW3 was 400 MB. MOBI was a fair compromise, it had about 40 MB in size and Kindle supports it well.


When coverting larger number of files with ImageMagick’s convert, it may happen that you’ll end up with this (or similar) error:

convert-im6.q16: cache resources exhausted file @ error/cache.c/OpenPixelCache/4095
convert-im6.q16: attempt to perform an operation not allowed by the security policy `PDF' @ error/constitute.c/IsCoderAuthorized/421.

To fix this, you need to allow ImageMagick to use more memory. Go to /etc/ImageMagic/policy.xml and edit the line <policy domain="resource" name="memory" value="256MiB"/>

Raise the value from 256MiB to something bigger, e.g., 4GiB.

Then, you also need to allow encoding (writing) PDFs so if you get an error about writing PDFs being forbidden, allow it (the same file as above):

<policy domain="coder" rights="read|write" pattern="PDF" />

(The line is towards the end with right="none" by default, at least on my machine.)

Sources (attribution)

I thank (among others) these guides and posts for help: