Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

CTGraphics - Anti-Alias C++ Drawing

0.00/5 (No votes)
13 Dec 2006 1  
An article on anti-aliased C++ drawing.

Demo-Project Screenshot image

Introduction

This article is about the anti-alias drawing support under GDI using C++. It refers to MFC or non-MFC applications. Here, a small class called CTGraphics is presented. It has anti-alias support for drawing basic primitives: lines, arcs, ellipses (circles), round rectangles, polylines, and pies. You can define other interesting shapes using this basic primitives.

Background

What is the "aliasing" effect? It is the effect of jagged-edges (or stairs in other words) that appear when you draw some graphic shapes using the basic Windows GDI. See the image below:

Aliased Line image

So what is the problem with this? Well, if you want your computer generated graphics (or images) to look nice, this is not a good way to do it. How does this happen then? It is because of the limited screen resolution, that is a limited number of pixels, horizontal or vertical, that can be drawn on the screen. Their size is so small that you can't see them, so that is why this will happen when you want to draw a line using the MoveToEx() and LineTo() methods of the Windows GDI.

What to do then? Now, this is a place where a technique called "anti-aliasing" is coming at the scene. It must do something to blur those edges so different approaches were taken for this action. One is called a super-sampling of the original image. It renders an image at high frequency (scaled original image 2x or more), and then it performs low-pass filtering of that super-sampled image so the edges will become less sharp, and when you scale this image down again (to the original size), you will have an anti-aliasing effect in action. This is a very memory consuming method but it will work.

Another method (implemented here) is the so called pre-filtering of the original image. It averages the amount of pixels that is covered with the primitive equation. The ideal line will not cover the whole pixel but a part of it, so this method sets the intensity of that pixel to some value other than the maximum for the line that you are drawing. So while you draw your line, you set the line pixels to some value. This method is less memory consuming than the previous one but it takes a lot of math to implement it to work correctly, so you can see where the compromise is.

Whichever way you do anti-aliasing, you will get an output similar to the following:

AntiAliased Line image

So, you have modified the original line pixels so that now line edges are a bit smoothed. The CTGraphics class does its work in a similar manner. It supports anti-aliasing for the following:

  • Lines
  • Polylines
  • Polygons
  • Ellipses
  • Arcs
  • Pies
  • Chords
  • Round Rectangles
  • Bezier Splines

However, you are free to extend its functionality on other shapes and graphic primitives. You can combine basic shapes and get more complex shapes (this is how the Round Rectangle is done: by combining Lines and Arcs).

Using the code

To use the source provided, just include the TGraphics.h and TGraphics.cpp files in your MS Visual C++ Project. Using the described class is very simple, see below:

CTGraphics tGraphics;

// hDC is obtained somewhere else

// Variables x1, y1, x2 and y2 are defined somewhere else

COLORREF color = RGB(255, 0, 0); // Pick some nice line color


// You have everything, now draw anti-aliased line

tGraphics.DrawLine(hDC, x1, y1, x2, y2, color);

It is very simple, isn't it? Other methods of the CTGraphics class work very similar so I will not explain each of them.

Important note

Here is presented a small C++ class which performs anti-aliased drawing using Windows GDI and C++. However, no speed records were a goal here, so don't expect the demo to run the fastest it can. This is just the demo of the functionality that was required to have smooth edges while drawing lines and arcs, at the first place. Also, just 1px width of the "drawing pen" is supported. This may sound not perfect, but this was only done in order to finish the job, not to make it harder than it already is.

Points of interest

I was looking for this subject all over the Internet and CodeProject and found different solutions, more or less similar. I wanted to extend the basic line anti-aliasing algorithms (like Wu's algorithm present on the CodeProject) to arcs and other shapes. I don't say this is the best result you can achieve, but it finished the job for me very quickly. You also may find that, due to float numbers involved in the calculations, the output is not perfect, but I leave this as an exercise for you. As an example of different approaches, you may find in the source of the CTGraphics class that ellipse is not done using an arc of 360 degrees, although it could be. Instead I used a similar and a bit modified math equation.

History

CTGraphics class version 1.01.

In this release, the support for the following were added:

  • Polygons
  • Chords
  • Bezier Splines

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here