Skip to content

hilhool/-MDI--Multiple-Document-Interface-

Repository files navigation

MDIPaint — Растровый редактор изображений

О проекте

MDIPaint — настольное приложение для редактирования растровых изображений, реализованное на C# с использованием Windows Forms и паттерна MDI (Multiple Document Interface). Позволяет одновременно работать с несколькими изображениями в отдельных дочерних окнах внутри единого главного окна.

Технологии

Технология Назначение
C# / .NET Framework 4.7.2 Язык и платформа
Windows Forms Графический интерфейс
System.Drawing Работа с графикой и растровыми данными
System.Drawing.Imaging Форматы сохранения файлов

Сторонние зависимости (NuGet-пакеты) не используются.


Структура проекта

MDIPaint/
├── Program.cs                 — точка входа в приложение
├── MainForm.cs                — главная MDI-форма
├── MainForm.Designer.cs       — инициализация интерфейса главной формы
├── DocumentForm.cs            — дочерняя форма с холстом рисования
├── DocumentForm.Designer.cs
├── CanvasSizeForm.cs          — диалог изменения размера холста
├── CanvasSizeForm.Designer.cs
├── TextInputForm.cs           — диалог ввода текста для инструмента «Текст»
├── TextInputForm.Designer.cs
├── AboutForm.cs               — окно «О программе»
├── AboutForm.Designer.cs
└── MDIPaint.csproj            — файл проекта

Архитектура

Приложение построено по классическому MDI-паттерну Windows Forms:

MainForm  (IsMdiContainer = true)
│
├── DocumentForm  (дочернее окно #1)
├── DocumentForm  (дочернее окно #2)
└── ...

Диалоги: CanvasSizeForm, TextInputForm, AboutForm

MainForm — родительский контейнер. Хранит глобальные параметры рисования через статические свойства и управляет дочерними окнами через меню и панель инструментов.

DocumentForm — каждый открытый документ живёт в своём дочернем окне. Содержит Bitmap как основной холст, обрабатывает события мыши для рисования, поддерживает масштабирование и управляет сохранением файла.

Взаимодействие между формами прямое: DocumentForm читает статические свойства MainForm для получения параметров рисования и вызывает ((MainForm)MdiParent).UpdateStatus(...) для обновления строки состояния.


Поддерживаемые инструменты

Инструмент Клавиша Описание Режим заливки
Перо P Свободное рисование линией
Линия L Прямая линия / залитый прямоугольник
Эллипс E Эллипс контуром или залитый
Ластик R Стирание круглой областью (радиус 10 пкс)
Масштаб+ + Увеличение масштаба (до 8×)
Масштаб- - Уменьшение масштаба (до 0.25×)
Текст T Вставка текста с выбором шрифта и размера
Ведро с краской F Заливка замкнутой области (flood fill)
Стрелка A Стрелка с наконечником / закрашенным острием

Кнопка «Заливка» на панели инструментов включает режим заливки фигур для инструментов, поддерживающих его (✓).


Описание классов

Program

Файл: Program.cs

Точка входа. Инициализирует визуальные стили Windows и запускает главную форму.


MainForm

Файл: MainForm.cs

Главное окно приложения (MDI-контейнер). Содержит меню, панель инструментов и строку состояния.

Статические свойства (глобальные параметры рисования)

Свойство Тип По умолчанию Описание
PenColor Color Color.Black Текущий цвет пера
PenWidth int 3 Толщина пера (1–100 пикселей)
CurrentTool string "Pen" Активный инструмент рисования
FillShape bool false Режим заливки фигур
ZoomFactor float 1.0f Текущий масштаб отображения (0.25–8.0)

Ключевые методы

Метод Описание
UpdateStatus(x,y,w,h) Обновляет строку состояния. Вызывается из DocumentForm при движении мыши.
UpdateToolStatus() Обновляет название текущего инструмента в строке состояния.
UpdateCursor() Устанавливает курсор активного документа в соответствии с текущим инструментом.
SetTool(tool) Переключает инструмент, обновляет статус и курсор.
ProcessCmdKey(...) Перехватывает горячие клавиши P/L/E/R/T/F/A/+/−.

Структура меню

Файл
  ├── Создать       (Ctrl+N)
  ├── Открыть...    (Ctrl+O)
  ├── Сохранить     (Ctrl+S)       — активно при открытом документе
  ├── Сохранить как... (Ctrl+Shift+S)
  └── Выход         (Alt+F4)

Рисунок
  └── Размер холста...              — активно при открытом документе

Инструменты
  ├── Перо / Линия / Эллипс / Ластик
  ├── ─────────────
  ├── Масштаб+ / Масштаб-
  ├── Текст
  ├── Ведро с краской
  └── Стрелка

Цвет
  ├── Чёрный / Красный / Синий / Зелёный
  └── Другой...

Окно
  ├── Каскад / Горизонтально / Вертикально / Упорядочить значки
  └── [список дочерних окон]

Справка
  └── О программе...

DocumentForm

Файл: DocumentForm.cs

Дочерняя форма. Представляет один открытый документ. Содержит холст (Bitmap) и реализует всю логику рисования.

Поля

Поле Тип Назначение
bitmap Bitmap Основной холст — постоянное хранилище пикселей
previewBitmap Bitmap Временная копия для предпросмотра линии / эллипса / стрелки
startX, startY int Координаты точки нажатия кнопки мыши (в координатах холста)
isDrawing bool Флаг: идёт ли рисование в данный момент
isModified bool Флаг несохранённых изменений
filePath string Путь к файлу (null для нового документа)
zoom float Текущий масштаб отображения холста
ZoomLevels float[] static Допустимые уровни масштаба: 0.25, 0.5, 1, 2, 4, 8

Логика рисования (события мыши)

MouseDown

  • ZoomIn / ZoomOut: вызывает ApplyZoom и выходит.
  • Text: открывает TextInputForm, рисует строку на bitmap и выходит.
  • Fill: запускает FloodFill и выходит.
  • Остальные инструменты: запоминает (startX, startY) в координатах холста, устанавливает isDrawing = true.

MouseMove

Инструмент Действие
Pen Рисует отрезок на bitmap, обновляет стартовую точку.
Eraser Закрашивает белым эллипс радиуса 10 пкс на bitmap.
Line/Ellipse/Arrow Клонирует bitmappreviewBitmap, рисует фигуру для предпросмотра.

MouseUp

  • Для Line / Ellipse / Arrow: рисует итоговую фигуру на основном bitmap.
  • Сбрасывает previewBitmap, устанавливает isModified = true.

Масштабирование

  • Уровни масштаба: 0.25×, 0.5×, 1×, 2×, 4×, 8× (переключение кликом).
  • Отрисовка использует InterpolationMode.NearestNeighbor — чёткие пиксели без размытия.
  • AutoScrollMinSize обновляется при каждом изменении масштаба — прокрутка при zoom > 1.
  • Координаты мыши переводятся в координаты холста через ScreenToCanvas(sx, sy): canvasX = (screenX - scrollOffset.X) / zoom.

Flood Fill

  • Итеративный алгоритм на основе Stack<Point> — нет риска StackOverflow на больших областях.
  • 4-связная связность (вверх / вниз / влево / вправо).
  • Заменяет все пиксели цвета targetColor на fillColor начиная от точки клика.
  • Если targetColor == fillColor — операция пропускается.
  • Реализовано через LockBits + Marshal.Copy — пиксели обрабатываются как массив int[] без вызова GetPixel/SetPixel на каждый пиксель, что даёт прирост скорости в ~100× по сравнению с наивной реализацией.

Инструмент «Стрелка»

  • Рисует основную линию от (x1, y1) до (x2, y2).
  • Добавляет два луча наконечника под углом ±π/7 (~25.7°) длиной 15 пикселей.
  • При FillShape = true наконечник закрашивается как залитый треугольник.

Работа с файлами

Метод Поведение
OpenFile(path) Загружает изображение через new Bitmap(path). Обновляет заголовок.
SaveFile() Сохраняет по существующему filePath или вызывает SaveFileAs.
SaveFileAs() Показывает диалог сохранения (BMP / JPEG), обновляет filePath и заголовок.

Поддерживаемые форматы:

Операция Форматы
Открытие BMP, JPG, JPEG, PNG
Сохранение BMP, JPEG

Изменение размера холста (ResizeCanvas)

Создаёт новый Bitmap заданного размера, заливает белым, копирует старое содержимое. Пересчитывает AutoScrollMinSize для текущего масштаба.

Обработка закрытия

При isModified = true показывает диалог «Сохранить изменения?». Ответ «Нет» — закрывает без сохранения, «Отмена» — отменяет закрытие.


CanvasSizeForm

Файл: CanvasSizeForm.cs

Модальный диалог изменения размера холста. Содержит два NumericUpDown (диапазон 1–9999).


TextInputForm

Файл: TextInputForm.cs

Модальный диалог для инструмента «Текст». Позволяет задать:

  • Текст — строка для вставки на холст.
  • Шрифт — выпадающий список: Arial, Times New Roman, Courier New, Verdana, Tahoma.
  • Размер — кегль шрифта от 6 до 144 пт (по умолчанию 12).

AboutForm

Файл: AboutForm.cs

Стандартный диалог «О программе».


Потоки выполнения

Рисование пером (Pen)

MouseDown  →  startX/Y = ScreenToCanvas(e.X, e.Y), isDrawing = true
MouseMove  →  DrawLine(bitmap, startX,Y → canvas.X,Y)
              startX/Y = canvas.X,Y
              Invalidate()
MouseUp    →  isModified = true, isDrawing = false

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

MouseDown  →  startX/Y = ScreenToCanvas(e.X, e.Y), isDrawing = true
MouseMove  →  previewBitmap = bitmap.Clone()
              DrawShape(previewBitmap, startX,Y → canvas)
              Invalidate()          // показываем предпросмотр
MouseUp    →  DrawShape(bitmap, startX,Y → canvas)
              previewBitmap.Dispose()
              isModified = true

Масштабирование

MouseDown (ZoomIn/ZoomOut)
  └─ ApplyZoom(bool zoomIn)
        ├─ найти текущий индекс в ZoomLevels
        ├─ idx++ / idx--
        └─ Zoom = ZoomLevels[idx]
              ├─ AutoScrollMinSize = bitmap.Size * zoom
              └─ Invalidate()

Вставка текста

MouseDown (Text)
  └─ TextInputForm.ShowDialog()
        └─ OK → DrawString(bitmap, text, font, brush, canvasX, canvasY)
                isModified = true

Flood Fill

MouseDown (Fill)
  └─ targetColor = bitmap.GetPixel(x, y)
     FloodFill(x, y, targetColor, PenColor)
       └─ Stack<Point> итерация 4-связная:
            SetPixel(p, fillColor) → push соседей

Сборка и запуск

Требования: Visual Studio 2019+ с поддержкой .NET Framework 4.7.2 (или MSBuild 15+).

1. Открыть MDIPaint-main_v2.sln в Visual Studio
2. Сборка → Собрать решение  (Ctrl+Shift+B)
3. Запуск: F5 (с отладчиком) или Ctrl+F5 (без отладчика)

Через MSBuild из командной строки:

msbuild MDIPaint.csproj /p:Configuration=Debug

Исполняемый файл после сборки: bin\Debug\MDIPaint.exe


История изменений

v2 — Новые инструменты и исправления

  • Инструменты: добавлены «Ведро с краской» (F), «Текст» (T), «Стрелка» (A), масштабирование (+/−).
  • Flood Fill: алгоритм заливки переведён на LockBits — устранено зависание при работе с изображениями любого размера.
  • TextInputForm: диалог ввода текста добавлен в проект (MDIPaint.csproj).
  • Предпросмотр: линия, эллипс и стрелка отображаются в реальном времени при перетаскивании мыши.

About

MDI-приложение (Multiple Document Interface), позволяющее редактировать растровые изображения в форматах BMP, JPG и PNG.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages