Bob H
April 19th, 1999, 10:06 AM
What is the software method for anti-aliasing a graphic relative to its background?
|
Click to See Complete Forum and Search --> : Anti-aliased graphics Bob H April 19th, 1999, 10:06 AM What is the software method for anti-aliasing a graphic relative to its background? April 19th, 1999, 10:55 AM Basically, for each pixel along an edge to be antialiased, you need to know (i) the background color, (ii) the foreground color and (iii) the fraction of the pixel that would have been covered by the foreground color based had "aliasing" (the replacement of a color of a pixel with the color of a foreground object that only partially covers the pixel) not taken place. The color of the pixel should be the weighted average of the two colors, weighted based upon the relative fractions of the idealized pixel that would have been covered by each. For instance, if the background was white (0,0,0), the foreground black (255, 255, 255) and the foreground would cover 0.60 of the background (for instance, if the foreground was the set of all points below the line y=1.2x and we were considering the pixel having (0,0) as its lower-left corner and (1,1) as its upper-right corner), the pixel should be colored (153,153,153). To do antialiasing properly, you need to know how your system/mapping mode/etc. defines pixels (for instance, which corner of a pixel do its coordinates correspond to), as well as how it defines the boarders of objects you may want to put in the foreground (polygons, lines, bitmaps). Also, you need to know how you are defining mathematically idealized lines, etc. Good luck. David Patrick April 19th, 1999, 02:25 PM The following code snippet does not match the more academically correct definition as stated by a previous reply however it may be a bit more useful. Essentially the routine applies a 3x3 convultion matrix which is used to adjust a pixel's color using the color of the pixel's neighbors. Given a matrix a b c d e f g h i then the values in the matrix indicate how much the color of the surrounding pixels should affect the target pixel. 'e' represents the target pixel at (x,y), therefore 'a' represents the pixel at (x-1,y-1), b = (x,y-1), c=(x+1,y-1), d=(x-1,y), f=(x+1,y),g=(x-1,y+1),h=(x,y+1),i=(x+1,y+1). the new value for the pixel at (x,y) after applying the matrix is the sum of ( a * color(x-1,y-1) ) + ( b * color(x,y-1) ) + .. etc .. + (i * color(x+1,y+1) ) divided by the sum of a + b + c + d + e + f + g + h + i. The cool thing about this is that you can use this technique for other things other than anti-aliasing ... it is used for a lot of effects such as sharpening or bluring a picture .. also embossing a picture uses this technique .. all it takes is different values in the matrix for a..i In the case of the routine below the matrix is 1 1 1 1 n 1 1 1 1 this means for a pixel located at (x,y) its new color will be color(x-1,y-1) + color(x,y-1) + color(x+1,y-1) // thus ends first row in matrix + color(x-1,y) + color(x,y) * n // ( here n is a weight factor ) + color(x+1,y) // thus ends second row in matrix + color(x-1,y+1) + color(x,y+1) + color(x+1,y+1) // thus ends third row in matrix The result of the color summation is then divided by (8+n) to get the new pixel(x,y) color. Obviously the higher the value for 'n' the less the surrounding pixels will affect the value of the pixel(x,y). A more common matrix used for anti-aliasing is 0 1 0 1 1 1 0 1 0 which could be implemented as above without taking into consideration the value of pixels at (x-1,y-1),(x+1,y-1),(x-1,y+1)(x+1,y+1). Personally I dont like this matrix because it will not provide any anti-aliasing to horizontal or vertical lines .. which may be appropriate depending up situtation. If you want the whole class email me and I will send it to you .. the class basically converts a HBITMAP to DIBSection so that you can have fast access to the bits of the bitmap. void CLMDIB::AntiAlias(int weight) { //------------------------------------------------------------------------- // Before do anything with the dib-section make sure any batched gdi actions // are completed //------------------------------------------------------------------------- GdiFlush(); //------------------------------------------------------------------------- // Make a backup copy of the data bits //------------------------------------------------------------------------- int PixelCount = (m_Info.bmiHeader.biHeight*m_Info.bmiHeader.biWidth); COLORREF *src_bits = new COLORREF[PixelCount]; CopyMemory(src_bits,m_Bits,(PixelCount*4)); //------------------------------------------------------------------------- // Declaration(s) //------------------------------------------------------------------------- int offset; int Red; int Green; int Blue; int y_minus_one; int y_plus_one; int factor = 8 + weight; //------------------------------------------------------------------------- // Process each pixel //------------------------------------------------------------------------- for ( int y = 1; y < m_Info.bmiHeader.biHeight - 1; y++ ) { for ( int x = 1; x < m_Info.bmiHeader.biWidth - 1; x++ ) { //----------------------------------------------------------------- // Determine location of target pixel //----------------------------------------------------------------- offset = PixelOffset(x,y); //----------------------------------------------------------------- // Determine offsets of surrounding pixels //----------------------------------------------------------------- y_minus_one = offset - m_Info.bmiHeader.biWidth; y_plus_one = offset + m_Info.bmiHeader.biWidth; //----------------------------------------------------------------- // Accumulate Color information from surrounding pixels //----------------------------------------------------------------- // From row above pixel Red = GetRValue(src_bits[y_minus_one-1]); // x-1,y-1 Green = GetGValue(src_bits[y_minus_one-1]); // x-1,y-1 Blue = GetBValue(src_bits[y_minus_one-1]); // x-1,y-1 Red += GetRValue(src_bits[y_minus_one]); // x,y-1 Green += GetGValue(src_bits[y_minus_one]); // x,y-1 Blue += GetBValue(src_bits[y_minus_one]); // x,y-1 Red += GetRValue(src_bits[y_minus_one+1]); // x+1,y-1 Green += GetGValue(src_bits[y_minus_one+1]); // x+1,y-1 Blue += GetBValue(src_bits[y_minus_one+1]); // x+1,y-1 // From same row as pixel Red += GetRValue(src_bits[offset-1]); // x-1,y Green += GetGValue(src_bits[offset-1]); // x-1,y Blue += GetBValue(src_bits[offset-1]); // x-1,y Red += (GetRValue(src_bits[offset])*weight); // x,y Green += (GetGValue(src_bits[offset])*weight); // x,y Blue += (GetBValue(src_bits[offset])*weight); // x,y Red += GetRValue(src_bits[offset+1]); // x+1,y Green += GetGValue(src_bits[offset+1]); // x+1,y Blue += GetBValue(src_bits[offset+1]); // x+1,y // From row below pixel Red += GetRValue(src_bits[y_plus_one-1]); // x-1,y+1 Green += GetGValue(src_bits[y_plus_one-1]); // x-1,y+1 Blue += GetBValue(src_bits[y_plus_one-1]); // x-1,y+1 Red += GetRValue(src_bits[y_plus_one]); // x,y+1 Green += GetGValue(src_bits[y_plus_one]); // x,y+1 Blue += GetBValue(src_bits[y_plus_one]); // x,y+1 Red += GetRValue(src_bits[y_plus_one+1]); // x+1,y+1 Green += GetGValue(src_bits[y_plus_one+1]); // x+1,y+1 Blue += GetBValue(src_bits[y_plus_one+1]); // x+1,y+1 //----------------------------------------------------------------- // Average the colors //----------------------------------------------------------------- Red = Red / factor; Green = Green / factor; Blue = Blue / factor; //----------------------------------------------------------------- // Store result //----------------------------------------------------------------- m_Bits[offset] = RGB(Red,Green,Blue); } } //------------------------------------------------------------------------- // Free dynamically allocated memory //------------------------------------------------------------------------- delete[] src_bits; } codeguru.com
Copyright Internet.com Inc., All Rights Reserved. |