我正在开发一个绘制手写笔画的应用程序。笔划在内部存储为点向量,并且可以转换为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);
}
最后,我将此bitmap
保存为PNG图像,有时会出现以下问题:
当我在笔画 中看到 “洞”时,我决定再次绘制我的点,但这一次,使用宽度和高度设置为{的椭圆{1}}使用宽度设置为1
的{{1}}。所以在上面的代码之后我添加了以下代码:
redPen
我看起来像是这样的:
当我在绘制这个新的红色笔划时使用Graphics.DrawRectangle
而不是0.1f
时,这个笔划(由绘图矩形绘制)在其中会有不同的宽度或空洞:
我想不出任何可能的原因,为什么画圈会导致这种奇怪的行为。当我使用Graphics.DrawRectangle
时,为什么中风始终是连续的并且不会以任何方式变形?
谁能解释一下,这里发生了什么?我错过了什么吗?
顺便说一句,我正在使用Windows XP(例如,如果它是一个已知的bug)。任何帮助将不胜感激。
答案 0 :(得分:2)
我做了错误的假设,如果我使用Graphics.DrawEllipse
用宽度约为2px的笔绘制半径等于2px的圆,则会产生直径约为4-5 px的实心圆绘制。
但是我发现在用这种方式绘制圆形时我实际上不能依赖笔的宽度。此方法仅用于绘制此形状的边框,因此,对于绘制填充的椭圆,使用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);
产生以下结果:
因此,如果有人将面临与我相同的问题,解决方案是: