Reverse Antialiasing for Image Scaling

When enlarging screen images, for example using screen magnifier utilities such as KDE’s KMag, the antialiasing used for rendering text becomes very visible (see left image). To limit the effect, simple pixel replication is not suited, but a different scaling algorithm needs to be used. The simplest of those algorithms is the bilinear filtering method, which is quite fast, but has the disadvantage of blurring the result.

More advanced methods, such as the Mitchell filter, obtain better results, but are slower to compute and introduce new kinds of artifacts, called ringing. For more information about the kind of artifacts linear scaling methods introduce, please refer to this interpolation introduction.

Image Scaling Comparison

Several methods for non-linear image scaling were proposed, some of them especially fast, some of them optimized for pixel art, others using several megabytes of trained neuronal networks etc. There is always a trade off you have to make between the image quality, and the speed you get.

While the source code for the neuronal network-based scaler is available (as well as the trained data), it was out of scope for a simple screen magnifier, such as KMag. The algorithm should be fast (maybe the speed of a bicubic scaler), and work without additional data, so that it can be used for KMag.

Again, I was not satisfied with the methods that were previously freely available, so I developed my own version of a scaling algorithm. This time it is optimized for scaling antialiased text or rasterized vector graphics, because it effectively reverses the antialiasing process. The quality is certainly not perfect, especially when faced with thin diagonal lines, but I consider it good and fast enough to be useful in KMag. It should also be quite useful as a resolution doubler for high-resolution (“Retina”) displays, and GPU implementations should be simple.

On the right image, you can see my result, using some text and some graphics from the Oxygen team (unscaled image here). To get an impression how it looks as a screen magnifier, here is a screenshot of a Dolphin window (made by Peter Penz), and its resolution doubled version.

A description of the algorithm will follow later. Just be a bit patient, I am still learning TeX :)

About these ads


  1. ben said

    Wow, the scaled up dolphin screenshot is quite impressive.

    How well does it play together with the various subpixel hinting types?

  2. Christoph said

    @ben, what do you mean? The algorithm does not handle subpixel antialiasing differently, so it can, for example, not convert between different subpixel layouts. If the original image is using a wrong layout, the scaled version will also be wrong.

  3. VS said

    Have you tried LyX? Since I discover it, I gladly forgot years of TeX pain..

  4. Christoph said

    Yes, using LyX here, but it does not really help with TikZ graphics; you have to use inline raw TeX for that, or I did not see the obvious…

  5. For making TikZ graphics I suggest using ktikz (preferably the svn version at svn:// because it is much better than version 0.10). You still have to learn the TeX commands, but the program allows you to create the figures faster because it recompiles the code automatically each time you change something.

  6. Luis said

    Hey, it looks awesome. I’m looking forward to taking a look at your algorithm. Congratulations!

  7. ben said


    I meant, if the original image uses subpixel rendering (with color pixels) for black text, will the scaled-up version of the text look like it has colorful edges?
    (Like it does with linear scaling:

    Or will it still appear smooth and black

  8. Christoph said

    ben, the Dolphin screenshot does use (colorful) subpixel rendering, so does the doubled version.

  9. Sgdb said

    Very good quality!

    Any comments about the algorithm?

  10. kdepepo said

    Here is a simple standalone version of the scaling algorithm, for those who want to play with it.

  11. Sgdb said

    Thanks, it works. I’m amazed by some results. I intend to understand the logic behind it and try to make a gpu shader some day…

  12. Sgdb said

    Hi! I ported your sources to Cg shader language and made a post about your amazing filter in this forum:

    I´m interested in understanding the theory behind it.

  13. kdepepo said

    Nice work! Doesn’t look good as a pixel art scaler, though :)

    Sorry, I didn’t yet have time to improve my TikZ skills, and I feel that without some graphics, it is not easy understand. I wish there was a program that converts handwritten notes/graphics to a nice document :P

  14. Sgdb said

    No need for tex. Just write some txt with these ideas! :P

    I’m coming here every day to see any update. :(

  15. Sgdb said

    Any news about the algorithm explanation? :(

  16. Sgdb said

    Oh my! More than a year since it was released!

    Please, provide us an explanation about this algorithm. How did you got the formula (7*(b+c) – 3*(a+d)+8)/16?

    I’ve already tried to reach that formula, but couldnt.

  17. kdepepo said

    The way sharpening is done using these coefficients is not much different compared to other higher-order interpolation algorithms. I tried varying the coefficients, and to me these values looked best to get a relatively sharp picture. In other words, the coefficients are arbitrary, as long as they sum to 0.5, as stated in the source.

    The actual “magic” (reverse antialiasing) is accomplished by the “min(abs(2b), abs(2c))” limiting, but yes, this really ought to be explained via some graphs and linear arithmetic formulas. Sorry for lacking the time :/

RSS feed for comments on this post · TrackBack URI

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


Get every new post delivered to your Inbox.

Join 140 other followers

%d bloggers like this: