The road to ImageGlass 9

Phap Duong
5 min readJust now

--

Here I am, returning after 4 years, and so much has happened. Today, I will share how ImageGlass 9 came to be.

As you may know, ImageGlass 9 has been built from the ground up. In any photo-viewing app, the viewer component is the heart of the experience. The design might not be perfect, and button sizes may vary, but the main viewer — where users view and interact with their photos — needs to be smooth, responsive, and fast. I began developing version 9 by experimenting with various approaches to find the one that best matched my needs and skills.

From the experiments…

In Dec 2017, I started the “ImageGlass-Photos” project, hoping to create a cross-platform version of ImageGlass. It featured a sleek UI inspired by the Windows 10 Fluent Design language, but the project didn’t get far due to poor performance and high memory usage.

The “ImageGlass-Photos” project
The “ImageGlass-Photos” project

In mid-2020, the “ImageGlass Preview” project was born, trying the latest technology of Windows: UWP. Eventually, it ended up being abandoned due to the limitations and restrictions of UWP framework. A simple task such as opening a file picker dialog also required way more effort than with WinForms. I was lost — what happened to Windows native app development? Should I stick with the outdated WinForms or WPF, or struggle through the limitations of UWP?

The “ImageGlass Preview” project
The “ImageGlass Preview” project

Around the same time in mid-2020, I decided to experiment with the WPF framework for the “ImageGlass α” project, using Ashley Davis’s “ZoomAndPanControl” code as a foundation. The app looked smooth and beautiful, but the control lacked UI virtualization, making it sluggish when opening large photos. Additionally, the WPF app was slow to launch and consumed a lot of memory. Once again, the experiment ended in disappointment.

The “ImageGlass α” project
The “ImageGlass α” project

In July 2021, with .NET 5 supporting WinForms and WebView2 gaining popularity, I kicked off a new project called “HapplaBox” — a hybrid application combining C# WinForms with web technology. This app utilized C# libraries from the “ImageGlass α” project, the Thumbnail component from “ImageGlass-Photos”, and a new JavaScript viewer component. It worked well initially until a communication issue arose between WebView2 and the C# backend code, leading to yet another abandonment of the project.

The “HapplaBox” project
The “HapplaBox” project

Not giving up, I continued researching zoom and pan algorithms for the viewer component, determined to develop my own native solution. I came across Mohammed Abd Alla’s article, “A Picture Viewer Class that can Scroll and Zoom using API”, which offered a basic implementation of zoom and pan that worked surprisingly well. I successfully created a quick native GDI-based viewer component. However, when I tried to add support for transparency and animation, I ran into significant challenges due to the outdated GDI APIs. As a result, the viewer component remained just a proof of concept.

… to the release of ImageGlass 9 Beta 1

While exploring the DirectX domain, I discovered that Direct2D offered the native hardware acceleration I needed but using it with C# wasn’t straightforward. I found the “d2dlib” project, a .NET library for Direct2D rendering, and quickly ported my GDI code to work with it. I then developed more advanced features, including smooth zoom and pan, text rendering, and custom controls. I incorporated the image backend library from the “HapplaBox” project and created a new toolbar and menu component. It all worked wonderfully — until I started adding more image features: the limitations of the Direct2D APIs provided through “d2dlib” meant that I couldn’t implement transparency and animation effectively. Despite these setbacks, I remained optimistic about this approach and decided to publish it, leading to the birth of ImageGlass 9 Beta 1 in May 2022.

ImageGlass 9 Beta 1
ImageGlass 9 Beta 1

… and the stable foundation of ImageGlass 9 — ImageGlass 9 Beta 2!

Unhappy with the limitations of the “d2dlib” library, I delved into its C++ source code to try to expose more features from Direct2D. However, my limited knowledge of C++ made it challenging. I continued searching for alternatives and came across the “WicNet” and “DirectN” projects. These were exactly what I needed! They provided direct interop APIs for Direct2D without the need to create new ones. This meant I could seamlessly port the Direct2D C++ APIs to C#. Additionally, they supported the latest features of Direct2D, allowing me to easily develop and take ownership of the technology.

I created the “D2Phap.DXControl” library — a WinForms hybrid control that supports both Direct2D and GDI+ drawing, serving as the foundation for the Direct2D component used in ImageGlass. I replaced the viewer component based on “d2dlib” with a new one built on “D2Phap.DXControl”, successfully resolving all outstanding issues.

In Sep 2022 — 4 months after the Beta 1, ImageGlass 9 Beta 2 was released!

ImageGlass 9 Beta 2
ImageGlass 9 Beta 2

… to the final ImageGlass 9

Building on the success of the viewer component, more features were added.

  • Beta 3 was a significant release, introducing a new Crop tool and focusing on modernizing the app’s appearance. Implementing support for Windows 10 and 11 backdrop styles, such as Acrylic, Mica, and Mica Alt within the WinForms framework proved to be quite a challenge. I plan to write another blog post to share more details about this process.
  • Beta 4 brought more features from ImageGlass 8, including support for layout customization and external tools. This release introduced the “ImageGlass.Tools” library for developers looking to integrate their applications with ImageGlass, which led to the creation of the “ExifGlass” app — an EXIF metadata viewing tool.
  • Beta 5 marked a significant milestone with the integration of the web viewer component from the “HapplaBox” project, enabling seamless SVG viewing. Its core JavaScript library was split off into a separate project called “happlajs”.
  • RC (Release Candidate) helped bridge the gap between ImageGlass 8 and the new features introduced in ImageGlass 9.

From the initial experiment to the GA release of ImageGlass, it took five years — a long journey for any indie open-source developer. Without the encouragement and support from ImageGlass users, especially those who donated, I might not have completed the revamp. ImageGlass 9 opens up a new path for its future development.

Stay tuned for more posts to come!

--

--