Results 1 to 7 of 7

Thread: Tutorial - Anti-Alias Pixels

  1. #1

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755

    Tutorial - Anti-Alias Pixels

    Introduction:

    This tutorial will teach you how to draw anti-aliased (AA) pixels.

    For those who don't know what an anti-aliased pixel is, here's an explenation:
    When drawing pixels you are limited to the resolution of the monitor, but with
    AA-pixels you can simulate that you draw pixels inbetween the actual monitor pixels.
    This will result in a really smooth look of anything you draw in your program.

    I will keep this tutorial as simple as i can, and i will not use any API because
    that might be hard to follow for anyone that is not that experienced with Visual Basic.
    I will however attach a fast exaple using API in the last part.

    Here's an image that shows what AA looks like.

    Attached Images Attached Images  
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  2. #2

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    Some theory:

    Here are some illustrations that shows the pixel we want to draw.
    The grid shows the pixels that the monitor has, also our boundary - We can't draw
    between those pixels.



    Lest say we want to draw a red pixel on X position 2.6 and Y position 2.8 - Right between
    two monitor pixels. Without AA the pixels position would be rounded off and it would
    be painted on X 3 and Y 3 and we can't do anything about that, that's why we simulate
    that the pixel is drawn inbetween. We do this by drawing 4 pixels (because our pixel
    touches 4 of the monitors pixels) with different colors depending on how much our pixel
    touches the surrounding pixels.

    As you can see in the illustration, our pixel only touches the (2,2) pixel a little bit,
    so we draw the (2,2) pixel just a little bit read.
    The illustration also shows that our pixel touches the (3,3) pixel very much, so we will
    draw that one almost red.
    We do like this for all the pixels we touch. (In this case there are 4 pixels, but sometimes
    there are only 2 pixels ore maybe even just 1)
    Attached Images Attached Images  
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  3. #3

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    Rounding functions:

    We will start off by calculating the distance to the pixel up left. ((2,2) in this case)
    To to that we need to 'remove' the decimals from our X and Y, and we'll get (2,2) instead of (2.6,2.8)
    There is no built in function in Visual Basic that does that so we'll have to make our own.

    First we have to correct Visual Basic's Round function that will not always return the correct value,
    so here's Round2

    VB Code:
    1. Private Function Round2(Number As Double, Optional NumDigitsAfterDecimal As Long = 0) As Double
    2.     If Number - Round(Number, NumDigitsAfterDecimal) >= 0.5 / (10 ^ NumDigitsAfterDecimal) Then Round2 = Round(Number, NumDigitsAfterDecimal) + 0.1 / (10 ^ NumDigitsAfterDecimal)
    3.     If Number - Round(Number, NumDigitsAfterDecimal) < 0.5 / (10 ^ NumDigitsAfterDecimal) Then Round2 = Round(Number, NumDigitsAfterDecimal)
    4. End Function

    Now what this function do is it takes your number and checks if the decimal value is equal,
    higher or lower than 0.5 and then rounds it off in the correct direction.


    Now we head on to the type of round function we were after - A function that 'removes' the decimals
    so we can get the upper left pixel.

    VB Code:
    1. Private Function RoundClose(Number As Double) As Integer
    2.     If Number = Round2(Number) Then
    3.         RoundClose = Number
    4.     Else
    5.         If Number - Round2(Number) > 0 Then
    6.             RoundClose = Round2(Number)
    7.         Else
    8.             RoundClose = Round2(Number) - 1
    9.         End If
    10.     End If
    11. End Function

    This function uses the Round2 function we made earlier to round off the decimals and if the number
    gets rounded up to the next integer we simply subtract one from it.
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  4. #4

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    Calculations:


    Now it's time to create the function that will do the actual AA calculation.
    We call the upper left pixel's coordinates cX and cY (c stands for Close)

    VB Code:
    1. Private Sub DrawAntiAliasPixel(PicBox As PictureBox, ByVal X As Double, ByVal Y As Double, ByVal R As Integer, ByVal G As Integer, ByVal B As Integer)
    2.     Dim cX As Integer
    3.     Dim cY As Integer
    4.  
    5.     cX = RoundClose(X)
    6.     cY = RoundClose(Y)
    7. End Sub

    The function takes 6 parameters which are X and Y for position and R, G and B for color values. PicBox is the PictureBox we want to draw on.


    Now let's find out how to calculate the new colors of the surrounding pixels.
    To do that we need to calculate how many percent of our pixel that is touching each of the surrounding
    pixels.
    For this we need to know how far our pixel are from each of the other pixels.
    We calculate this by subtracting cX from X and cY from Y, then we get delta X and delta Y (dX,dY).
    But this will only tell us the distance from one side. The dX and dY from the other side (dX2,dY2) is 1 - dX and 1 - dY.



    For the upper left corner on our pixel we do dX2 * dY2, and that will give us how many percent we touch the
    upper left pixel.

    For the other pixels do:
    Upright Pixel = dX * dY2
    Downleft Pixel = dX2 * dY
    Downright Pixel = dX * dY

    If this is confusing take a close look at the image attached (dX2 * dY2 will give us the area of the corner
    and also the percent because 100% of the area of a square with 1 lenght units on all sides is 1)

    By multiplying these value with the color values, we will get how much of our pixel's color we need for each pixel.
    We also need to know how much of the original color from the pixels we need, and that is the inverted value:
    Upleft Pixel = 1 - dX2 * dY2
    Upright Pixel = 1 - dX * dY2
    Downleft Pixel = 1 - dX2 * dY
    Downright Pixel = 1 - dX * dY

    Now we need to extract the original colors from the background to mix with the new color. We do this by using the
    Point function. But we also need to extract the red, green and blue values from that color.
    To do this, we need some new functions:

    VB Code:
    1. Private Function GetRed(ByVal Color As Long) As Byte
    2.     GetRed = Color And 255
    3. End Function
    4.  
    5. Private Function GetGreen(ByVal Color As Long) As Byte
    6.     GetGreen = (Color And 65280) \ 256
    7. End Function
    8.  
    9. Private Function GetBlue(ByVal Color As Long) As Byte
    10.     GetBlue = (Color And 16711680) \ 65535
    11. End Function

    Now all that's left is to create variables to hold all different values and put it all down into the function
    and draw the pixels using PSet.

    Here's the finished function:

    VB Code:
    1. Private Sub DrawAntiAliasPixel(PicBox As PictureBox, ByVal X As Double, ByVal Y As Double, ByVal R As Integer, ByVal G As Integer, ByVal B As Integer)
    2.     Dim cX As Integer
    3.     Dim cY As Integer
    4.     Dim dX As Double
    5.     Dim dY As Double
    6.     Dim dX2 As Double
    7.     Dim dY2 As Double
    8.     Dim BGColor As Long
    9.     Dim BGRed As Integer
    10.     Dim BGGreen As Integer
    11.     Dim BGBlue As Integer
    12.     Dim NewRed As Integer
    13.     Dim NewGreen As Integer
    14.     Dim NewBlue As Integer
    15.     Dim Percent As Double
    16.     Dim InvPercent As Double
    17.    
    18.     cX = RoundClose(X)
    19.     cY = RoundClose(Y)
    20.  
    21.     dX = X - cX
    22.     dY = Y - cY
    23.     dX2 = 1 - dX
    24.     dY2 = 1 - dY
    25.    
    26.     'upleft pixel
    27.     BGColor = PicBox.Point(cX, cY)
    28.     BGRed = GetRed(BGColor)
    29.     BGGreen = GetGreen(BGColor)
    30.     BGBlue = GetBlue(BGColor)
    31.    
    32.     Percent = dX2 * dY2
    33.     InvPercent = 1 - Percent
    34.    
    35.     NewRed = Percent * R + InvPercent * BGRed
    36.     NewGreen = Percent * G + InvPercent * BGGreen
    37.     NewBlue = Percent * B + InvPercent * BGBlue
    38.    
    39.     PicBox.PSet (cX, cY), RGB(NewRed, NewGreen, NewBlue)
    40.    
    41.     'upright pixel
    42.     BGColor = PicBox.Point(cX + 1, cY)
    43.     BGRed = GetRed(BGColor)
    44.     BGGreen = GetGreen(BGColor)
    45.     BGBlue = GetBlue(BGColor)
    46.    
    47.     Percent = dX * dY2
    48.     InvPercent = 1 - Percent
    49.    
    50.     NewRed = Percent * R + InvPercent * BGRed
    51.     NewGreen = Percent * G + InvPercent * BGGreen
    52.     NewBlue = Percent * B + InvPercent * BGBlue
    53.    
    54.     PicBox.PSet (cX + 1, cY), RGB(NewRed, NewGreen, NewBlue)
    55.    
    56.     'downleft pixel
    57.     BGColor = PicBox.Point(cX, cY + 1)
    58.     BGRed = GetRed(BGColor)
    59.     BGGreen = GetGreen(BGColor)
    60.     BGBlue = GetBlue(BGColor)
    61.    
    62.     Percent = dX2 * dY
    63.     InvPercent = 1 - Percent
    64.    
    65.     NewRed = Percent * R + InvPercent * BGRed
    66.     NewGreen = Percent * G + InvPercent * BGGreen
    67.     NewBlue = Percent * B + InvPercent * BGBlue
    68.    
    69.     PicBox.PSet (cX, cY + 1), RGB(NewRed, NewGreen, NewBlue)
    70.    
    71.     'downright pixel
    72.     BGColor = PicBox.Point(cX + 1, cY + 1)
    73.     BGRed = GetRed(BGColor)
    74.     BGGreen = GetGreen(BGColor)
    75.     BGBlue = GetBlue(BGColor)
    76.    
    77.     Percent = dX * dY
    78.     InvPercent = 1 - Percent
    79.    
    80.     NewRed = Percent * R + InvPercent * BGRed
    81.     NewGreen = Percent * G + InvPercent * BGGreen
    82.     NewBlue = Percent * B + InvPercent * BGBlue
    83.    
    84.     PicBox.PSet (cX + 1, cY + 1), RGB(NewRed, NewGreen, NewBlue)
    85. End Sub
    Attached Images Attached Images  
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  5. #5

    Thread Starter
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    Here's the fast version using some API:

    (Edit: Fixed a bug in the code.)
    Attached Files Attached Files
    Last edited by cyborg; Apr 5th, 2004 at 05:10 PM.
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  6. #6
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,927
    The code/files within this thread (submitted: 04-05-2004) have been checked for malware by a moderator.

    Disclaimer: This does not necessarily mean that any compiled files (DLL/EXE/OCX etc) are completely safe, but any supplied code does not contain any obvious malware. It also does not imply that code is error free, or that it performs exactly as described.

    It is recommended that you manually check any code before running it, and/or use an automated tool such as Source Search by Minnow (available here or here).
    If you find any serious issues (ie: the code causes damage or some sort), please contact a moderator of this forum.

    Usage of any code/software posted on this forum is at your own risk.

  7. #7
    Lively Member
    Join Date
    Mar 2015
    Posts
    104

    Re: Tutorial - Anti-Alias Pixels

    Thanks for the tute on antialiasing pixels. I have been playing around with different antialiasing modules, but have not properly understood how these work. I had a rough idea, but hopefully your tute will help with the understanding of the underlying code. I have a module created by another programmer on Planet Vb, which antialiases lines of various thicknesses and opacities. I will attach it for you to have a browse. Thanks once again for your informative tutorial.
    Attached Files Attached Files

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width