Subpixel rendering is the technique your computer uses to make text on the screen as readable as possible even at small font sizes.
In a typical LCD monitor, each pixel is represented by a combination of three separate light-emitting elements, which are coloured red, green and blue. When they are all switched on, the pixel appears white, and when they are all switched off, the pixel appears black. Other colours can be displayed by varying the red, green and blue components individually, and for shades of grey, these components are always equal.
To display smooth lines and curves, a technique called antialiasing is used to eliminate the jagged edges that appear where dark and light pixels are placed adjacent to each other. This is illustrated in the middle of the image on the right, where the pixels forming the letter “e” have been changed to smoothly varying grey levels to avoid the jagged appearance of the non-antialiased letter at the top of the image.
Subpixel antialiasing goes one step further by working on the transitions between individual light-emitting elements instead of at the pixel level. This is done by applying a reddish or bluish hue to pixels to adjust the brightness at the edges of each RGB pixel.
After reading a recent question at Stack Overflow, I got to wondering how easy it would be to reverse this subpixel rendering process on antialiased text. This might, for example, be useful if you’re trying to use OCR software to read text from a screenshot image.
Here’s an example of text grabbed from my computer monitor (scaled up 300%):
If you look closely, you can see that the letters are coloured red on the left and blue on the right due to the effects of subpixel antialiasing:
OCR software often uses thresholding to separate text from background details. Applying a simple 50% threshold filter to this antialiased text gives illegible results:
Although this can be improved by choosing the threshold value more carefully, I got much better results by writing some software to scale up the original image while taking subpixel antialiasing effects into consideration. This is what I got:
If you think it might be useful, you can download the software here: subpix.c. It uses the GD graphics library, but it shouldn’t be too hard to make it work with other libraries.
Nice, thanks for the idea !
Using the following convert command is probably easier :
convert input.png -resize 300% -black-threshold 50% -white-threshold 50% output.png
A hint for those we want to compile subpix.c :
sudo apt-get install libgd2-xpm-dev (or equivalent on your distro)
gcc /tmp/subpix.c -lgd -o subpix