Over the last couple weeks I’ve been playing about with the concept of creating a central page that would be my starting point for reading through various ebooks, notably PDFs. I have collected quite a few PDFs along the way and as they’re not physical, and not piling up on my desk or bookshelf, it can be easy to forget about them. So a page of thumbnails will give a visual reminder of what you’ve not read yet or of a library to access in the future.
The concept is pretty simple, scan through a directory and create a thumbnail of the first page of every PDF and provide a link to the actual file from a static page. Ideally the script would be run periodically to update the static page to collect any changes in the files.
One further thing that is important is the ability to filter out files that you want but perhaps don’t want to have included in the static page as you’ve already read them maybe, so there’s an ability to exclude specific directories.
Dependencies
The only direct dependency needed for creating an image from a PDF is the Apache PDF Box library, but that is dynamically loaded with Groovy Grape (thanks to mvnrepository.com).
@Grapes(
@Grab(group='org.apache.pdfbox', module='pdfbox', version='1.7.1')
)
Creating Thumbnails
By utilising the Apache PDFBox library there really isn’t all that much work to do for generating images.
The PDDocument.load(pdfFile)
reference loads a PDF file and then utilising a PDFImageWriter
class with it’s writeImage
method it will save a full size image to the desired location.
That gets us half way there, the other thing we need to do is resize the images to a sane size, I’ve gone with 150 x 210. The resizing is also pretty simple using the javax.imageio.ImageIO
class to read and write the image and the java.awt.Graphics2D
class to render a resized image (which then gets written to file).
All this is done in about 100 lines of Groovy in com.thecuriousdev.ebookwall.PdfImageCreator
.
The Static Page
There’s not much to the static page, just creating a series of table cells from the collection of PDFs with the thumbnail linking to the actual files.
At this stage, it’s just hard-coded to output at most ten thumbnails per row, which seems about right for a wide-screen monitor of at least a 1600x900 resolution.
If there aren’t exactly the right amount of images, it will pad it out to ensure we’ve got a nice ‘n clean HTML table.
Using DIVs and actual CSS might be a better option going forward, but for a first cut, this will work good enough.
Configuration
The core of the project relies upon it being told where your PDFs are, this is done in the config.properties
file, which looks a little like this:
images_dir=C:/Users/Scott/Dropbox/EbookWall/images/
out_file=C:/Users/Scott/Dropbox/EbookWall/ebookwall.htm
include_dirs=C:/Users/Scott/Dropbox/current_reading_ebooks|C:/Users/Scott/Dropbox/RegularReading/
exclude_dirs=C:/Users/Scott/Dropbox/RegularReading/_archive/|C:/Users/Scott/Dropbox/current_reading_ebooks/_archive/
The configuration points are pretty self explainatory. You just need to say where the generated images and the static page should go, where to include the PDFs from and an optional list of exclude directories. These latter two are pipe |
separated.
Running
There’s really not much to running the class, it is just a matter of calling it with either one or no arguments.
With no arguments it will look for a config.properties
file in the root of the project.
#> groovy com\thecuriousdev\ebookwall\EBookWall.groovy
Optionally you can provide the file name / path to a different file, perhaps with different references to the directory, such as your Dropbox folder.
#> groovy com\thecuriousdev\ebookwall\EBookWall.groovy work-pc-config.properties
So this will allow you to have multiple configurations and static pages for the same DropBox directory even though it might be located in a totally different path.
The Result
Here’s a sample of my EBookWall, pretty basic for now but I’ve got a few ideas to implement yet.
The Code
For this project, I figured it might be useful for someone else as a standalone repository, so it’s available here: EBookWall.
There are only two classes, so it shouldn’t take long to find your way around.
Have a play and let me know if you’ve got any enhancement ideas.