使用DrawEllipse(GDI +)绘制手写笔画的点

3
我正在开发一个绘制手写笔画的应用程序。笔画被内部存储为点向量,可以转换为std::vector<Gdiplus::Point>。这些点非常接近,简单地绘制每个点应该得到一条连续的笔画图像。
我使用Graphics.DrawEllipse(GDI+)方法来绘制这些点。以下是代码:
// prepare bitmap:
Bitmap *bitmap = new Gdiplus::Bitmap(w, h, PixelFormat32bppRGB);
Graphics graphics(bitmap);

// draw the white background:
SolidBrush myBrush(Color::White);
graphics.FillRectangle(&myBrush, 0, 0, w, h);

Pen blackPen(Color::Black);
blackPen.SetWidth(1.4f);

// draw stroke:
std::vector<Gdiplus::Point> stroke = getStroke();
for (UINT i = 0; i < stroke.size(); ++i)
{
    // draw point:
    graphics.DrawEllipse(&blackPen, stroke[i].X, stroke[i].Y, 2, 2);
}

在最后,我将这个位图保存为PNG图像,有时会出现以下问题:

problem

当我看到我笔画中的这个“空洞”时,我决定再次绘制我的点,但这次使用椭圆形并将宽度和高度设置为1,使用redPen并将宽度设置为0.1f。因此,在上面的代码之后,我添加了以下代码:
Pen redPen(Color::Red);
redPen.SetWidth(0.1f);

for (UINT i = 0; i < stroke.size(); ++i)
{
    // draw point:
    graphics.DrawEllipse(&redPen, stroke[i].X, stroke[i].Y, 1, 1);
}

我得到的新笔画如下所示: problem2

当我使用 Graphics.DrawRectangle 代替 DrawEllipse 来绘制这个新的红色笔划时,它从未出现过这样的情况:这个笔划(通过绘制矩形来绘制)会有不同的宽度或孔。

rectangles

我想不出任何可能的原因,为什么画圆会导致这种奇怪的行为。当我使用 Graphics.DrawRectangle 时,为什么描边总是连续的,从未以任何方式变形? 有人能解释一下正在发生什么吗?我有什么遗漏吗?
顺便说一下,我正在使用 Windows XP(例如,如果这是已知的错误)。任何帮助将不胜感激。
1个回答

2
我曾经错误地认为,如果我使用Graphics.DrawEllipse来画一个半径为2px的圆,用宽度大约为2px的笔,结果会画出直径约4-5像素的实心圆。
但我发现,我不能依靠笔的宽度来绘制这种圆。这种方法仅适用于绘制形状的边框,因此要绘制填充椭圆,最好使用Graphics.FillEllipse
另一个需要考虑的相当重要的事实是,这两个提到的函数都以指定椭圆边界矩形的左上角坐标作为参数。因此,我应该从两个坐标中减去半径的一半,以确保原始坐标指定了这个圆的中心。
这是新代码:
// draw the white background:
SolidBrush whiteBrush(Color::White);
graphics.FillRectangle(&whiteBrush, 0, 0, w, h);

// draw stroke:
Pen blackBrush(Color::Black);
std::vector<Gdiplus::Point> stroke = getStroke();
for (UINT i = 0; i < stroke.size(); ++i)
    graphics.FillEllipse(&blackBrush, stroke[i].X - 2, stroke[i].Y - 2, 4, 4);

// draw original points:
Pen redBrush(Color::Red);
std::vector<Gdiplus::Point> origStroke = getOriginalStroke();
for (UINT i = 0; i < origStroke.size(); ++i)
    graphics.FillRectangle(&redBrush, origStroke[i].X, origStroke[i].Y, 1, 1);

这将产生以下结果:

正确的笔画

因此,如果有人遇到与我相同的问题,解决方案是:

输入图像描述


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接