Click here to Skip to main content
15,867,453 members
Articles / Multimedia / GDI
Article

CTGraphics - Anti-Alias C++ Drawing

Rate me:
Please Sign up or sign in to vote.
4.77/5 (51 votes)
13 Dec 2006CPOL4 min read 172K   9K   103   33
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Elektromehanika d.o.o. Nis
Serbia Serbia
He has a master degree in Computer Science at Faculty of Electronics in Nis (Serbia), and works as a C++/C# application developer for Windows platforms since 2001. He likes traveling, reading and meeting new people and cultures.

Comments and Discussions

 
QuestionHigh efficiency. Pin
feirench19-Feb-14 20:21
feirench19-Feb-14 20:21 
Very good,thank you,that's what i want.
GeneralMy vote of 5 Pin
JJMatthews27-Sep-12 4:01
JJMatthews27-Sep-12 4:01 
GeneralMy vote of 5 Pin
hugh lo24-May-12 20:47
hugh lo24-May-12 20:47 
GeneralMy vote of 5 Pin
futurejo18-Nov-11 1:58
futurejo18-Nov-11 1:58 
Questionhow about just expand the resolution of the canvas ? Pin
William.Zhang1-Sep-10 18:47
William.Zhang1-Sep-10 18:47 
Generalit`s cool Pin
lovefly_mhl16-Jun-09 5:58
lovefly_mhl16-Jun-09 5:58 
Generalerror on compile Pin
Member 337533414-Feb-09 14:10
Member 337533414-Feb-09 14:10 
GeneralRe: error on compile Pin
Dontcryme4-Mar-09 0:00
Dontcryme4-Mar-09 0:00 
Generalnot working Pin
Member 33753348-Feb-09 17:17
Member 33753348-Feb-09 17:17 
QuestionHow to Fill? Pin
aChih7-Apr-08 7:31
aChih7-Apr-08 7:31 
AnswerRe: How to Fill? Pin
Geoff Bolton28-Apr-08 15:51
Geoff Bolton28-Apr-08 15:51 
GeneralRe: How to Fill? Pin
Mukit, Ataul24-Sep-10 20:45
Mukit, Ataul24-Sep-10 20:45 
GeneralRe: How to Fill? Pin
Pavel672-Jun-20 20:55
Pavel672-Jun-20 20:55 
QuestionHow to set thickness of line? Pin
xumingxian20-Aug-07 16:04
xumingxian20-Aug-07 16:04 
Questionis this a bug ? Pin
cbeaudet19-Jul-07 7:45
cbeaudet19-Jul-07 7:45 
QuestionThickness of Line? Pin
AVEbrahimi31-Dec-06 20:08
AVEbrahimi31-Dec-06 20:08 
AnswerRe: Thickness of Line? Pin
darkoman2-Jan-07 23:08
darkoman2-Jan-07 23:08 
GeneralRe: Thickness of Line? Pin
mound3-Jan-12 5:33
mound3-Jan-12 5:33 
GeneralPocket PC Pin
AVEbrahimi31-Dec-06 19:18
AVEbrahimi31-Dec-06 19:18 
GeneralA good, practical article... Pin
Jun Du16-Dec-06 14:46
Jun Du16-Dec-06 14:46 
GeneralThanks... Pin
Paul Selormey13-Dec-06 13:45
Paul Selormey13-Dec-06 13:45 
GeneralPretty damn cool :) Pin
Kochise30-Nov-06 21:12
Kochise30-Nov-06 21:12 
GeneralRe: Pretty damn cool :) Pin
Paul Selormey13-Dec-06 13:44
Paul Selormey13-Dec-06 13:44 
GeneralRe: Pretty damn cool :) Pin
matakk29-Jan-07 19:45
matakk29-Jan-07 19:45 
GeneralCool Pin
Leafdown30-Nov-06 15:41
Leafdown30-Nov-06 15:41 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.