A color theme generator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

4.6 KiB

Auto Color

This is a library which automatically generates color themes based on the user's background image.

I made this project as a part of the Wheel Reinvention Jam, using the jam as an excuse to work on a project which feels frivolous, but should come in handy for prettifying future projects.

The project is a C library with an optional command-line interface. The library looks at the user's current desktop background and picks some number of unique colors from that background. It then outputs the color values selected.

Rationale

If you are going to be staring at something all day, you might as well make it nice to look at. To me, this means a dark theme for less eye strain, and a pleasing color set.

Similar to musical notes, colors look best in context. Auto Color ensures the application's theme always harmonizes with the user's desktop. Additionally, Auto Color guarantees a set text to background contrast ratio so that any theme is still readable.

Applications

When included in a C/C++ project, the color values can be used to theme the application to match the user's background automatically.

In this example, an application I wrote using ImGui uses Auto Color to theme to the user's wallpaper:

/code/macoy/auto-color/src/branch/master/images/ImGuiExample1.jpg

/code/macoy/auto-color/src/branch/master/images/ImGuiExample3.jpg

/code/macoy/auto-color/src/branch/master/images/ImGuiExample4.jpg

In edge cases where there are very few colors to select from, Auto Color will still guarantee appropriate text contrast ratios:

/code/macoy/auto-color/src/branch/master/images/ImGuiExample2.jpg

Editors

By using base16, a guideline for color theme formats, any editor which supports Base16 color sets will work with Auto Color.

Here is a screenshot of Emacs after being themed with Auto Color:

/code/macoy/auto-color/src/branch/master/images/FirstTheme.jpg

You can see with some added transparency, the editor looks really nice.

Using it

Auto Color is a single header file. It also comes with a command-line interface.

Here's a simple usage example:

  #include <stdio.h>

  #include "AutoColor.h"

  int main()
  {
      AutoColor base16Colors[16] = {0};
      if (!autoColorPickFromCurrentBackground(base16Colors))
          return 1;
      fprintf(stderr, "The first color is RGB %d, %d, %d\n",
              base16Colors[0][0], base16Colors[0][1], base16Colors[0][2]);
      return 0;
  }

See the test/ directory for a buildable example.

Note that loading the wallpaper can take a relatively long time, depending on its resolution (long being around 200ms). If you are writing a real-time application, you should run autoColorPickFromCurrentBackground() on a separate thread than the render thread.

Windows

The desktop background is retrieved by checking the registry.

Include advapi32.lib in your linker command in order for this to work.

Linux

There are many different desktop window managers on Linux. Each manager does different things for desktop backgrounds, so they must have custom support. Luckily, only one function needs to be implemented in order to support a new desktop window manager. (So, please contribute if you want yours supported).

Auto Color currently supports the following managers:

GNOME 2.0

This should work on any newer Ubuntu distribution.

Before compilation:

sudo apt install libglib2.0-dev

On compilation:

  -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include

On linking:

  -lglib-2.0 -lgio-2.0 -lgobject-2.0

Comparison with past work

My inspiration for this project was from one of my previous projects, which creates color schemes for Emacs:

https://macoy.me/code/macoy/auto-base16-theme/media/branch/master/images/Example4.jpg

This project is a reinvention of that past project. This new version solves several problems:

  • Low dependencies. My previous implementation relied on schemer2, which is written in Go, and my color processor was written in Python. These two languages require pulling in a lot more dependencies than a tiny C library, and cannot be embedded in C/C++ applications

  • Automatic. I've found I enjoy themes which match my desktop most, but previous tools require manual steps to make this happen. This project will be easily embeddable and automatically scrape colors off the user's background

  • First-class Windows support. I'm committed to making this tool work on Windows, which tends to get less love from the FOSS community (in part because it's objectively less theme-able)

It has more robust color selection code and generally picks more colors. It also does not allocate memory.