Гид по технологиям

Рисование графики в Windows Forms: линии, фигуры и изображения

6 min read Разработка Обновлено 05 Dec 2025
Рисование в Windows Forms: линии, фигуры, изображения
Рисование в Windows Forms: линии, фигуры, изображения

Важно: примеры собраны для Visual Studio 2019 Community Edition и ориентированы на GDI+ (System.Drawing).

Компьютер с открытым графическим редактором в среде разработки

Введение

Windows Forms — это фреймворк для создания настольных приложений на .NET с визуальным конструктором форм. Для рисования в окне формы используются классы GDI+ (в пространстве имён System.Drawing и System.Drawing.Drawing2D). В основной схеме вы обычно:

  • подписываетесь на событие Paint формы или переопределяете OnPaint;
  • используете объект PaintEventArgs.E.Graphics для рисования;
  • создаёте объекты Pen и Brush для линий и заливок;
  • заботитесь об освобождении GDI+ ресурсов.

Дальше — подробные инструкции и рабочие примеры.

Встроенные классы для рисования графики

Ниже — обзор основных классов, которые вы будете использовать.

КлассОписание
GraphicsОбъект холста, предоставляемый PaintEventArgs. Содержит методы DrawLine, DrawRectangle, DrawPolygon, DrawEllipse, DrawString, FillRectangle и др.
PenОпределяет свойства пера: цвет, толщина, стиль штриховки, украшения (LineCap). Пен используется для методoв Draw*.
ColorПредставляет цвет в формате ARGB (A — прозрачность, R/G/B — каналы). Используется при создании Pen и Brush.
SolidBrush, HatchBrush, TextureBrushКлассы кистей для заполнения областей: сплошной цвет, узор (Hatch), текстура (Bitmap).
Rectangle, Point/PointF, SizeСтруктуры геометрии: прямоугольники, точки и размеры. Многие методы принимают эти объекты вместо отдельных координат.

Примечание: GDI+ не потокобезопасен — все вызовы к Graphics должны выполняться в UI-потоке или через Invoke/BeginInvoke.

Как добавить обработчик Paint при загрузке формы

Лучший способ — подписаться на событие Paint. В дизайнере Visual Studio это делается через вкладку “Свойства” → значок молнии → Paint.

Пример обработчика OnPaint:

private void Form1_Paint(object sender, PaintEventArgs e)
{
    // Здесь выполняется весь код рисования
}

Советы:

  • Используйте e.Graphics, не создавайте новый Graphics из формы без необходимости.
  • Для сложных сцен рассмотрите двойную буферизацию, чтобы избежать мерцания.

Показано, как добавить обработчик Paint в WinForms

Как рисовать линии на форме

Для простых линий используйте Color, Pen и метод DrawLine.

Пример создания цвета и пера:

Color black = Color.FromArgb(255, 0, 0, 0);
using (Pen blackPen = new Pen(black))
{
    e.Graphics.DrawLine(blackPen, 300, 200, 800, 200);
}

Изменение свойств пера:

using (Pen blackPen = new Pen(Color.Black))
{
    blackPen.Width = 20;
    blackPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dash;
    blackPen.StartCap = System.Drawing.Drawing2D.LineCap.ArrowAnchor;
    blackPen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
    e.Graphics.DrawLine(blackPen, 300, 200, 800, 200);
}

Ключевые моменты:

  • Используйте using или вручную Dispose для Pen и Brush, чтобы не допустить утечек GDI-ресурсов.
  • DashStyle и LineCap позволяют получить разнообразные визуальные эффекты.

Приложение Visual Studio с отрисованной линией

Как рисовать прямоугольники и окружности

Вы можете передавать координаты (x, y, width, height) или использовать структуры Rectangle/RectangleF.

Рисование прямоугольника по координатам:

Color red = Color.FromArgb(255, 255, 0, 0);
using (Pen redPen = new Pen(red))
{
    redPen.Width = 5;
    e.Graphics.DrawRectangle(redPen, 100, 100, 500, 200);
}

Рисование прямоугольника из объекта Rectangle:

Rectangle rectangle = new Rectangle(100, 350, 500, 200);
using (Pen redPen = new Pen(Color.Red, 5))
{
    e.Graphics.DrawRectangle(redPen, rectangle);
}

Рисование окружности/эллипса:

using (Pen greenPen = new Pen(Color.Lime, 5))
{
    e.Graphics.DrawEllipse(greenPen, 400, 150, 400, 400);
}

Важно: параметры x и y для DrawEllipse указывают верхний левый угол ограничивающего прямоугольника, а не центр окружности.

Рисование полигона (треугольник, шестиугольник и т.д.):

using (Pen bluePen = new Pen(Color.Blue, 5))
{
    PointF[] triangle = new PointF[]
    {
        new PointF(400, 150),
        new PointF(300, 300),
        new PointF(500, 300)
    };
    e.Graphics.DrawPolygon(bluePen, triangle);
}

Треугольник на холсте в приложении Visual Studio

Как использовать Brush для заливки фигур

Для заливки используйте методы FillRectangle, FillEllipse, FillPolygon и соответствующие кисти.

Пример создания SolidBrush:

Color purple = Color.FromArgb(255, 128, 0, 0);
using (SolidBrush solidBrush = new SolidBrush(purple))
{
    e.Graphics.FillRectangle(solidBrush, 50, 50, 200, 250);
    e.Graphics.FillEllipse(solidBrush, 300, 50, 200, 200);
    e.Graphics.FillPolygon(solidBrush, new PointF[] {
        new PointF(700, 150), new PointF(600, 300), new PointF(800, 300)
    });
}

HatchBrush и TextureBrush:

using (HatchBrush hatchBrush = new HatchBrush(System.Drawing.Drawing2D.HatchStyle.Horizontal, Color.Green, Color.Blue))
{
    e.Graphics.FillRectangle(hatchBrush, 50, 50, 200, 250);
}

Bitmap image = (Bitmap)Image.FromFile(@"C:\Users\Sharl\Desktop\flag.bmp", true);
using (TextureBrush textureBrush = new TextureBrush(image))
{
    e.Graphics.FillRectangle(textureBrush, 100, 100, 500, 400);
}

Приложение Visual Studio с залитыми фигурами

Прямоугольник с горизонтальным узором

Фигура, заполненная изображением

Как рендерить изображения на форме

Для отображения растрового изображения проще использовать PictureBox, особенно если вы хотите встроить элемент управления, который умеет изменять размер и позиционирование.

Пример создания PictureBox и добавления в форму:

PictureBox picture = new PictureBox();
picture.ImageLocation = @"C:\Users\Sharl\Desktop\flagLarge.bmp";
picture.SizeMode = PictureBoxSizeMode.AutoSize; // или Zoom, StretchImage и т.д.
this.Controls.Add(picture);

Если требуется сложная обработка изображений (масштабирование с контролем интерполяции), используйте Graphics.DrawImage с параметрами SourceRectangle/DestinationRectangle и настройкой InterpolationMode.

Приложение WinForms с изображением на форме

Практические советы и надёжные шаблоны

  1. Освобождение ресурсов

Всегда освобождайте Pen, Brush, Bitmap и другие GDI+ объекты. Используйте конструкцию using:

using (Pen p = new Pen(Color.Black))
{
    e.Graphics.DrawLine(p, 0, 0, 100, 100);
}
  1. Двойная буферизация для устранения мерцания

Включите двойную буферизацию для формы:

this.DoubleBuffered = true;

Или установите стиль:

this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.OptimizedDoubleBuffer, true);
  1. Антиалиасинг

Для более гладких линий включите сглаживание:

e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
  1. Масштабирование и DPI

Учитывайте DPI: размеры и координаты в пикселях зависят от масштабирования экрана. Для масштабируемых интерфейсов используйте логические единицы или масштабируйте координаты по коэффициенту DPI.

  1. Потокобезопасность

Вызовы рисования должны выполняться в UI-потоке. Если данные для отрисовки приходят из фонового потока, обновляйте состояние модели и вызывайте Invalidate/BeginInvoke для перерисовки в UI-потоке.

  1. Обработка ошибок и отказоустойчивость

GDI+ бросает ObjectDisposedException, если вы используете уже освобождённый ресурс. Логируйте и корректно обрабатывайте такие ситуации.

Когда этот подход не подходит (контрпример)

  • Если вам нужна аппаратная акселерация и сложная графика (анимация, 3D, плавный масштаб) — лучше выбрать WPF, DirectX, SkiaSharp или Unity.
  • Для кроссплатформенной 2D-графики с высокой производительностью рассмотрите SkiaSharp.
  • Для сложной векторной графики и масштабирования с векторной точностью — WPF или SVG-движки.

Альтернативные подходы

  • WPF (Windows Presentation Foundation): аппаратно-ускоренная, декларативная, лучше работает с векторной графикой и привязками данных.
  • SkiaSharp: кроссплатформенная библиотека на базе Skia от Google, хороша для высокопроизводительной 2D-графики.
  • Direct2D/DirectX: для низкоуровневой оптимизации и аппаратного ускорения.

Мини-методология: от идеи к финальной отрисовке

  1. Определите, какие элементы интерфейса будут рисоваться кодом, а какие — стандартными контролами.
  2. Проектируйте координатную систему (см. DPI и единицы измерения).
  3. Напишите минимальный обработчик Paint и постепенно добавляйте слои отрисовки.
  4. Профилируйте (время рисования, использование GDI-объектов).
  5. Внедрите двойную буферизацию и dispose-паттерны.
  6. Тестируйте на разных масштабах экрана и с разными темами ОС.

Чеклист для команды (роль-based)

  • Разработчик:

    • Использует using для всех GDI+ объектов.
    • Включил DoubleBuffered для форм/панелей.
    • Настроил SmoothingMode для требуемого качества.
  • Ревьюер кода:

    • Проверил отсутствие утечек (создание без Dispose).
    • Проверил обработку DPI и масштабирования.
  • Тестер:

    • Протестировал на разных масштабах экрана (100%, 125%, 150%).
    • Проверил перерисовку при изменении размеров окна и при скрытии/показе.

Критерии приёмки

  • Все требуемые фигуры отрисовываются корректно при запуске.
  • Не обнаружено утечек GDI-ресурсов при продолжительной работе (мониторинг дескрипторов).
  • Интерфейс не мерцает (включена двойная буферизация) и остаётся отзывчивым.
  • Масштабирование и DPI обработаны корректно.

Тестовые случаи и критерии успеха

  1. Рисование базовых фигур: линии, прямоугольники, окружности, полигоны — все видны и соответствуют координатам.
  2. Заливка кистью: SolidBrush, HatchBrush, TextureBrush — цвета и текстуры верны.
  3. Изображения: PictureBox или DrawImage корректно отображают файл и масштабируют при изменении размера.
  4. Устойчивость: запуск 24 часа без вырастания числа GDI-объектов.

Нюансы производительности и безопасности

  • Частые создания Bitmap из файлов во время Paint приводят к просадкам производительности. Загружайте и кешируйте изображения заранее.
  • Не используйте FileStream внутри Paint; загружайте данные в память в фоновом потоке.
  • При работе с большими изображениями применяйте режимы InterpolationMode и CompositingQuality для баланса качества/скорости.

Сопутствующие советы по миграции

  • При переносе на WPF обратите внимание: в WPF другая модель рендеринга (векторная), код на System.Drawing придётся переписать.
  • Для кроссплатформенности замените System.Drawing на SkiaSharp или другую кроссплатформенную библиотеку.

Однострочный глоссарий

  • Graphics: холст для рисования в методе Paint.
  • Pen: инструмент для рисования контуров.
  • Brush: инструмент для заливки областей.
  • DPI: плотность точек на дюйм, влияет на масштабирование интерфейса.

Краткое резюме

  • Windows Forms предоставляет простые API для рисования примитивов через Graphics, Pen и Brush.
  • Всегда управляйте временем жизни GDI+ объектов (using/Dispose), включайте двойную буферизацию и учитывайте DPI.
  • Для более сложной графики или кроссплатформенной поддержки рассмотрите альтернативы: WPF, SkiaSharp, Direct2D.

Дополнительные материалы: репозиторий с исходниками примеров доступен в GitHub (ссылка в исходном материале).

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

WhatsApp на iPhone: сообщение без контакта
Мобильные советы

WhatsApp на iPhone: сообщение без контакта

Запуск JavaScript из Python с Js2Py
Программирование

Запуск JavaScript из Python с Js2Py

Скелетные экраны в Next.js — реализация и советы
Frontend

Скелетные экраны в Next.js — реализация и советы

Регулярные выражения: проверка данных пользователей
Программирование

Регулярные выражения: проверка данных пользователей

Что такое CAPTCHA и как её создать на Python
Безопасность

Что такое CAPTCHA и как её создать на Python

Скачать Windows 11 ISO без ключа — инструкция
Windows

Скачать Windows 11 ISO без ключа — инструкция