AJ

25May/100

Convert any e-book to PDF for iPad

Most of the e-books are tied to their publishing house, and their propriety reading software. It is quite troublesome to use them in different environment, for example ubuntu or iPad that supports only PDF.

Below is a three step process that converts the e-books that can be opened in any computer into image-only pdf. The post is written with developer in mind, specially some one who can set path, compile and run a simple java program.

Before starting, we need to make sure whether the e-book reader allows contentious navigation or not. Most of the e-book reader does with the use of arrow or space key for a page at a time. The code below is tested with the software that allowed page scrolling with space.

Actual conversion process would be like.

  1. Scroll a page.
  2. Take a snapshot of the screen and work on the snapshot now to extract only the required portion / or save and use Photo shop automation to do this.
  3. Stitch the processed images to a single pdf using Acrobat pro or java iText library.

The code below is divided into three parts, if you feel comfortable looking at the entire code please scroll to bottom.

Scrolling the page.

private void pressSpace() throws Exception {
Robot r = new Robot();
r.keyPress(KeyEvent.VK_SPACE);
}
private void click(int x, int y, int times) throws Exception {
Robot r = new Robot();
r.mouseMove(x, y);
for (int i = 0; i < times; i++) {

r.mousePress(InputEvent.BUTTON1_MASK);
r.mouseRelease(InputEvent.BUTTON1_MASK);
Thread.sleep(100);
}
}

..
click(500, 500, 2); // Adjust to somewhere near center.
pressSpace();
click(500, 500, 2);
..

Getting the snapshot and extracting the required portion out of it.

    private BufferedImage getImage(int sX, int sY, int eX, int eY) throws Exception {
        Robot r = new Robot();
        BufferedImage img = r.createScreenCapture(new Rectangle(sX, sY, (eX - sX), (eY - sY)));
        return img;
    }

    private void save(BufferedImage img, String fileName) throws Exception {
        JPEGImageWriter writer = (JPEGImageWriter) ImageIO.getImageWritersByFormatName("jpeg").next();
        ImageWriteParam iwp = writer.getDefaultWriteParam();
        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        iwp.setCompressionQuality(1);

        FileImageOutputStream output = new FileImageOutputStream(new File(fileName));
        writer.setOutput(output);
        IIOImage iimage = new IIOImage(img, null, null);

        writer.write(null, iimage, iwp);
        writer.reset();
    }

..
        save(getImage(527, 55, 1389, 1067), pageNumber); // With some dummy coordinates for start and end.
..

Stitching the final image. Can be done using Adobe pro or using code below

        Document document = new Document(new com.itextpdf.text.Rectangle(862,1012));
        document.setMargins(0, 0, 0, 0);
        PdfWriter.getInstance(document, new FileOutputStream("book.pdf"));
        document.open();

        JPEGProducer p = new JPEGProducer();

        for (int i = 0; i < (550 ) ; i++) {
            Image image = p.getImage(527, 55, 1389, 1067);

            document.add(com.itextpdf.text.Image.getInstance(image, null));
            p.click(500, 500, 2);
            p.pressSpace();
            p.click(100, 100, 2);

        }
        document.close();

Below is the complete source code. Make sure you put iText library in path for this code to compile and run.


import java.awt.Image;
import java.awt.Rectangle;
import java.awt.Robot;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;

import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.stream.FileImageOutputStream;

import com.itextpdf.text.Document;
import com.itextpdf.text.pdf.PdfWriter;
import com.sun.imageio.plugins.jpeg.JPEGImageWriter;

public class JPEGProducer {

    private void click(int x, int y, int times) throws Exception {
        Robot r = new Robot();
        r.mouseMove(x, y);
        for (int i = 0; i < times; i++) {

            r.mousePress(InputEvent.BUTTON1_MASK);
            r.mouseRelease(InputEvent.BUTTON1_MASK);
            Thread.sleep(100);
        }

    }

    private BufferedImage getImage(int sX, int sY, int eX, int eY) throws Exception {
        Robot r = new Robot();
        BufferedImage img = r.createScreenCapture(new Rectangle(sX, sY, (eX - sX), (eY - sY)));
        return img;
    }

    private void pressSpace() throws Exception {
        Robot r = new Robot();
        r.keyPress(KeyEvent.VK_SPACE);
    }

    private void save(BufferedImage img, String fileName) throws Exception {
        JPEGImageWriter writer = (JPEGImageWriter) ImageIO.getImageWritersByFormatName("jpeg").next();
        ImageWriteParam iwp = writer.getDefaultWriteParam();
        iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
        iwp.setCompressionQuality(1);

        FileImageOutputStream output = new FileImageOutputStream(new File(fileName));
        writer.setOutput(output);
        IIOImage iimage = new IIOImage(img, null, null);

        writer.write(null, iimage, iwp);
        writer.reset();
    }

    public static void main(String[] args) throws Exception {

        Thread.sleep(8000);//Enough to activate the reader in screen.

        Document document = new Document(new com.itextpdf.text.Rectangle(862, 1012));
        document.setMargins(0, 0, 0, 0);
        PdfWriter.getInstance(document, new FileOutputStream("book.pdf"));
        document.open();

        JPEGProducer p = new JPEGProducer();

        for (int i = 0; i < (45 + 581 + 8 + 6 + 15 + 67 + 2 + 11 + 16); i++) {
            Image image = p.getImage(527, 55, 1389, 1067);

            document.add(com.itextpdf.text.Image.getInstance(image, null));
            p.click(500, 500, 2);
            p.pressSpace();
            p.click(100, 100, 2);

        }
        document.close();

    }

}
Filed under: java Leave a comment
Comments (0) Trackbacks (0)

No comments yet.


Leave a comment


No trackbacks yet.