首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用DrawEllipse (GDI+)绘制手写笔画点

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

Stack Overflow用户
提问于 2013-02-07 12:12:49
回答 1查看 2.1K关注 0票数 3

我正在开发一个绘制手写笔画的应用程序。笔画作为点的向量在内部存储,它们可以转换为std::vector<Gdiplus::Point>。各点如此接近,每个点的简单绘图应形成连续笔画的图像。

我使用Graphics.DrawEllipse (GDI+)方法来绘制这些点。下面是代码:

代码语言:javascript
复制
// 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);
}

最后,我只是将这个bitmap保存为PNG映像,有时会出现以下问题:

当我在笔画中看到这个“洞”时,我决定再次画出我的点,但这一次,通过将宽度和高度设置为1的椭圆使用redPen,将宽度设置为0.1f。因此,在上面的代码之后,我添加了以下代码:

代码语言:javascript
复制
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);
}

我得到的新斯托克是这样的:

当我在绘制这个新的红色笔画时使用Graphics.DrawRectangle而不是DrawEllipse时,这种笔画(由绘制矩形绘制)不会有不同的宽度或洞:

我想不出任何可能的原因,为什么画圈会导致这种奇怪的行为。为什么当我使用Graphics.DrawRectangle时,笔划总是连续的,而且从来没有变形过?有人能解释一下这是怎么回事吗?我是不是遗漏了什么?

顺便说一下,我正在使用Windows (例如,万一它是一个已知的bug)。任何帮助都将不胜感激。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-02-07 16:17:27

我做了一个错误的假设,如果我用Graphics.DrawEllipse画一个半径等于2px的圆,用宽度约为2px的笔画一个直径约为4-5Px的填充圆。

但我发现这样画圆圈时,实际上不能依赖笔的宽度。这种方法只适用于绘制这种形状的边框,因此,对于绘制填充椭圆,最好使用Graphics.FillEllipse

另一个非常重要的事实是,上述两个函数都以指定“矩形左上角的参数坐标,指定椭圆”的边界,因此我应该从两个坐标中减去一半半径,以确保原始坐标指定这个圆圈的中间位置。

以下是新代码:

代码语言:javascript
复制
// 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);

其结果如下:

因此,如果有人会遇到和我一样的问题,解决办法是:

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14750832

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档