整理日: 2015年2月16日算法
這幾天一直在研究win32 SDk下畫線去鋸齒,以前一直用的QT的畫線接口函數,裏面有去鋸齒的效果,但是忽然項目要求不能用QT的只能用win32 SDK下的GDI畫線接口函數,但是顯示的效果有鋸齒,怎麼辦?只能研究下怎麼去鋸齒影響,由於GDI下沒有去鋸齒的處理,因此只能本身找算法處理。dom
在網上找了一下
http://www.codeproject.com/KB/GDI/CTGraphics.aspx
http://www.codeproject.com/KB/GDI/AntiAliasing.aspx
http://www.codeproject.com/KB/GDI-plus/AntiAliasingIssues.aspx
反走樣技術之一 Wu像素
http://dev.gameres.com/Program/Visual/3D/Antialiasing.htm
http://dev.gameres.com/Program/Visual/Effects/WuLine.htm函數
什麼是防鋸齒技術?什麼是亞像素? - Apple4.uscode
但是這些方法的畫線處理不能設置線寬,個人畫線處理須要線寬,按照網上找到的去鋸齒的代碼,我改了下代碼(見後),修改的代碼並不能靈活設置的線寬,兩個端點處理也須要完善,最主要的是我不知道怎麼去處理兩個端點。搞了好幾天,仍是沒有找到端點處理的合適方式。htm
void RVS_drawLine_width(HDC hDC, int x1, int y1, int x2, int y2, COLORREF color) { // Calculate line params int dx = (x2 - x1); int dy = (y2 - y1); COLORREF bgColor; int temp; float k; // X-dominant line if (abs(dx) > abs(dy)) { // Ex-change line end points if (dx < 0) { temp = x1; x1 = x2; x2 = temp; temp = y1; y1 = y2; y2 = temp; } k = (float)dy / (float)dx; int xs; float yt = (float)y1; float distance; UCHAR red, green, blue; for (xs = x1; xs <= x2; xs++) { distance = (float)(yt - (int)(yt)); bgColor = ::GetPixel(hDC, xs, (int)yt - 1); red = (UCHAR)(distance * GetRValue(bgColor)) + (UCHAR)((1.0f - distance) * GetRValue(color)); green = (UCHAR)(distance * GetGValue(bgColor)) + (UCHAR)((1.0f - distance) * GetGValue(color)); blue = (UCHAR)(distance * GetBValue(bgColor)) + (UCHAR)((1.0f - distance) * GetBValue(color)); ::SetPixel(hDC, xs, (int)yt - 1, RGB(red, green, blue)); // ::SetPixel(hDC, xs, (int)yt-1, color); ::SetPixel(hDC, xs, (int)yt, color); bgColor = ::GetPixel(hDC, xs, (int)yt + 1); red = (UCHAR)((1.0f - distance) * GetRValue(bgColor)) + (UCHAR)(distance * GetRValue(color)); green = (UCHAR)((1.0f - distance) * GetGValue(bgColor)) + (UCHAR)(distance * GetGValue(color)); blue = (UCHAR)((1.0f - distance) * GetBValue(bgColor)) + (UCHAR)(distance * GetBValue(color)); ::SetPixel(hDC, xs, (int)yt + 1, RGB(red, green, blue)); yt += k; } } // Y-dominant line else { // Ex-change line end points if (dy < 0) { temp = x1; x1 = x2; x2 = temp; temp = y1; y1 = y2; y2 = temp; } k = (float)dx / (float)dy; int ys; float xt = (float)x1; float distance; UCHAR red, green, blue; for (ys = y1; ys <= y2; ys++) { distance = (float)(xt - (int)(xt)); bgColor = ::GetPixel(hDC, (int)xt - 1, ys); red = (UCHAR)(distance * GetRValue(bgColor)) + (UCHAR)((1.0f - distance) * GetRValue(color)); green = (UCHAR)(distance * GetGValue(bgColor)) + (UCHAR)((1.0f - distance) * GetGValue(color)); blue = (UCHAR)(distance * GetBValue(bgColor)) + (UCHAR)((1.0f - distance) * GetBValue(color)); ::SetPixel(hDC, (int)xt - 1, ys, RGB(red, green, blue)); // ::SetPixel(hDC, (int)xt-1, ys, color); ::SetPixel(hDC, (int)xt, ys, color); bgColor = ::GetPixel(hDC, (int)xt + 1, ys); red = (UCHAR)((1.0f - distance) * GetRValue(bgColor)) + (UCHAR)(distance * GetRValue(color)); green = (UCHAR)((1.0f - distance) * GetGValue(bgColor)) + (UCHAR)(distance * GetGValue(color)); blue = (UCHAR)((1.0f - distance) * GetBValue(bgColor)) + (UCHAR)(distance * GetBValue(color)); ::SetPixel(hDC, (int)xt + 1, ys, RGB(red, green, blue)); xt += k; } } }