使用MoveTo和LineTo来画曲线,出现锯齿,如何才能消除锯齿,来使曲线平滑?

时间:2023-01-28 20:33:29
使用MoveTo和LineTo来画曲线,出现锯齿,如何才能消除锯齿,来使曲线平滑?

11 个解决方案

#1


这两个函数无法实现抗锯齿,简单的方式就是用GDI+的Drawline函数。

#2


使用GDI+的Drawline画的话,就可以实现没有锯齿了?我还没用过GDI+我试一下

#3


好像不是Drawline函数,是Graphics::SetSmoothingMode 

#4


GDI没办法实现么? 非要用GDI+?

#5


GDI有办法实现,但需要算法的,轻易比较难实现,效果也不是很理想。
你可以把平滑的直线放大看看,他是如何处理像素的。记得CODEPROJECT上有一个GDI平滑的例子,直线,曲线都有,你可以参考下。

#6


抗锯齿这游戏选项, 的确在10年前就已经出来了, 但我想能够达到这水平的平民..还是少之又少的

#7


就用GDI+吧,其实挺方便的,何必自己折腾

#8



void CAADraw::DrawLine(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;

// Set start pixel
::SetPixel(hDC, x1, y1, color);

// 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;

// Set middle pixels
int xs;
float yt = (float)y1 + k;
float distance;
UCHAR red, green, blue;
for (xs=x1+1; xs<x2; xs++)
{
distance = (float)(yt - (int)(yt));

bgColor = ::GetPixel(hDC, xs, (int)yt);
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, RGB(red,green,blue));

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;

// Set middle pixels
int ys;
float xt = (float)x1 + k;
float distance;
UCHAR red, green, blue;
for (ys=y1+1; ys<y2; ys++)
{
distance = (float)(xt - (int)(xt));

bgColor = ::GetPixel(hDC, (int)xt, 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, ys, RGB(red,green,blue));

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;
}
}

// Set end pixel
::SetPixel(hDC, x2, y2, color);
}

这是AADraw类,网上有源代码,可Google之.
用了一堆SetPixel, 要高效,就不建议使用.

#9


使用混合,最方便还是GDI+

#10


有需要的时候使用GDI+ 可以用 gdi实现的就用gdi....这样也不错吧

#11


关注~~~

#1


这两个函数无法实现抗锯齿,简单的方式就是用GDI+的Drawline函数。

#2


使用GDI+的Drawline画的话,就可以实现没有锯齿了?我还没用过GDI+我试一下

#3


好像不是Drawline函数,是Graphics::SetSmoothingMode 

#4


GDI没办法实现么? 非要用GDI+?

#5


GDI有办法实现,但需要算法的,轻易比较难实现,效果也不是很理想。
你可以把平滑的直线放大看看,他是如何处理像素的。记得CODEPROJECT上有一个GDI平滑的例子,直线,曲线都有,你可以参考下。

#6


抗锯齿这游戏选项, 的确在10年前就已经出来了, 但我想能够达到这水平的平民..还是少之又少的

#7


就用GDI+吧,其实挺方便的,何必自己折腾

#8



void CAADraw::DrawLine(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;

// Set start pixel
::SetPixel(hDC, x1, y1, color);

// 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;

// Set middle pixels
int xs;
float yt = (float)y1 + k;
float distance;
UCHAR red, green, blue;
for (xs=x1+1; xs<x2; xs++)
{
distance = (float)(yt - (int)(yt));

bgColor = ::GetPixel(hDC, xs, (int)yt);
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, RGB(red,green,blue));

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;

// Set middle pixels
int ys;
float xt = (float)x1 + k;
float distance;
UCHAR red, green, blue;
for (ys=y1+1; ys<y2; ys++)
{
distance = (float)(xt - (int)(xt));

bgColor = ::GetPixel(hDC, (int)xt, 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, ys, RGB(red,green,blue));

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;
}
}

// Set end pixel
::SetPixel(hDC, x2, y2, color);
}

这是AADraw类,网上有源代码,可Google之.
用了一堆SetPixel, 要高效,就不建议使用.

#9


使用混合,最方便还是GDI+

#10


有需要的时候使用GDI+ 可以用 gdi实现的就用gdi....这样也不错吧

#11


关注~~~