PDF2Images

PDF2Images

TypeScript, JavaScript, Obsidian API, PDF.jsHobby Project|October 2024 - now

Summary

PDF2Images is a plugin for Obsidian that converts PDF pages into images and inserts them into notes. This is primarily developed for students, to quickly and easily extract PDF lecture slides into their notes.

Motivation for development

Back in 2024, I switched from using OneNote to using Obsidian to have more control over my own notes. I've always liked to be able to throw in the lecture slides in OneNote and extend with my own notes below each slide.
However Obsidian did not have built-in support for this, and I found manually extracting images from PDFs to be slow and cumbersome. I then stumbled upon the Obsidian Developer Documentation, that would allow users to develop their own plugins for Obsidian. Hence I decided to build a plugin that would allow me to quickly extract images from PDFs directly into my Obsidian vault.

Development Process

From idea to MVP - the first steps
The direction of development was fairly easy, since the plugin's purpose was to solve my own problem - to extract images from PDFs quickly and efficiently. A lot of things were new to me. I had only scratched the surface of JavaScript and only heard about TypeScript. I had no clue about how I would convert PDF pages to images and if it was even possible without an internet connection. Before I got too overwhelmed, I decided to break all my thoughts and ideas into issues on my project board that would be required to make a minimum viable product.

I began to research about parsing PDF files, and found the PDF.js library from Mozilla, to be a great fit. I later discovered that Obsidian's plugin API had built-in support for that library. To start developing the plugin itself, I followed the official Obsidian tutorial to set up my development environment and get a basic plugin running. Throughout the initial development, I had been using Claude Sonnet 3.5 as a sparring partner, together with the GitHub Copilot plugin for VS Code to help me with the TypeScript syntax. After a few days of work and a lot of trial and error, I had a basic MVP that could extract images from an uploaded PDF and insert the pages into the current note as images - even with a small progress indicator.

Beyond the MVP - what's next?
Great - now I had a working MVP that solved my initial problem. However, I still had a lot of ideas for future improvements and features that could be made. Once again, I turned to my project board and started prioritizing the issues that would bring the most value to me.

In Obsidian, there is a side-view to show the headers in a note. Since the lecture slides are just images, the view doesn't recognize any headers. Therefore I prioritized adding support for finding and inserting headers based on the content of each slide. Headers are detected using the pdf.js library's text extraction and are assessed based on font-size and a sensitivity filter. For each page, all text is extracted and compared, which increases the time it takes to process larger PDFs. Hence I made this setting optional for the user.

As of today, a lot of new features have been added, such as choosing image quality, image insertion method, image separator, header size and more.

Joining Obsidian’s Official Plugin List
After a few weeks of development and testing, I decided to submit the plugin to Obsidian's official plugin list. This would allow my friends and other users to automatically receive updates instead of having to manually download and install new versions. However, making this plugin 'public' would also mean taking responsibility for maintaining it and ensuring it kept working with future Obsidian updates. So far everything has been going well, and knowing that the Obsidian team is doing their work to keep their API secure, I feel comfortable having my plugin listed officially.

The use of AI tools
By having LLMs available, I was aware of the temptation to rely on them to write large parts of the code for me. However, I wanted to make sure that I was the one in control of the development and that I would understand every single line of code. To address this, I have primarily used AI tools for syntax help, brainstorming ideas and general faster development with the autocomplete functionality. This way, I ensured that I learned a lot throughout the process and that I could maintain and extend the plugin in the future without relying on AI tools.