Рисование точек рукописного штриха с помощью DrawEllipse (GDI +)

Я работаю над приложением, которое рисует рукописные штрихи. Штрихи внутренне хранятся как векторы точек, и они могут быть преобразованы в 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 используя 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);
}

И новый сток у меня выглядел так:
задачи2

Когда я использую Graphics.DrawRectangle вместо DrawEllipse при рисовании этого нового красного штриха никогда не бывает, чтобы этот штрих (нарисованный прямоугольниками) имел разную ширину или отверстия в нем:

прямоугольники

Я не могу придумать ни одной возможной причины, почему рисование кругов привело бы к такому странному поведению. Почему этот удар всегда постоянен и никогда не деформируется, когда я использую Graphics.DrawRectangle?
Кто-нибудь может объяснить, что здесь происходит? Я что-то пропустил?

Кстати, я использую Windows XP (например, если это известная ошибка). Любая помощь будет оценена.

3

Решение

Я сделал неверное предположение, что если я использую 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);

который дает следующий результат:

правильный ход

Поэтому, если кто-то столкнется с той же проблемой, что и я, решение будет таким:

введите описание изображения здесь

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]