Создание программы, похожей на Photoshop, — увлекательный проект.
На вашем пути будет много испытаний, и стоит немного подумать наперед.
Вот краткий и неполный список вещей, о которых следует помнить:
- Рисовать и раскрашивать действия
- Отменить, повторить, изменить
- Несколько слоев
- Масштабирование и прокрутка
- Сохранение и печать
Так что получить фон в виде шахматной доски — это только начало большого пути.
Использование PictureBox
в качестве основного холста — очень хороший выбор, так как его несколько слоев помогут. Вот фрагмент кода, который предоставит вам гибкий фон шахматной доски, который сохранит свой размер, даже когда вы масштабируете реальную графику:
void setBackGround(PictureBox pb, int size, Color col)
{
if (size == 0 && pb.BackgroundImage != null)
{
pb.BackgroundImage.Dispose();
pb.BackgroundImage = null;
return;
}
Bitmap bmp = new Bitmap(size * 2, size * 2);
using (SolidBrush brush = new SolidBrush(col))
using (Graphics G = Graphics.FromImage(bmp) )
{
G.FillRectangle(brush, 0,0,size, size);
G.FillRectangle(brush, size,size, size, size);
}
pb.BackgroundImage = bmp;
pb.BackgroundImageLayout = ImageLayout.Tile;
}
Загрузите изображение для тестирования, и вот что вы получите, слева нормально, справа увеличено:
Да, для сохранения этот фон надо убрать; как вы можете видеть в коде, передача size = 0 сделает это.
Что дальше? Позвольте мне дать вам несколько советов о том, как подходить к различным задачам сверху:
Прокрутка: Picturebox
не может прокручивать. Вместо этого поместите его в Panel
с AutoScroll = true
и сделайте его настолько большим, насколько это необходимо.
Масштабирование: Играя с его Size
и SizeMode
, вы сможете увеличивать и уменьшать масштаб Image
без проблем. BackgroundImage
останется немасштабированным, как в Photoshop. Однако вам придется добавить еще немного кода, чтобы увеличить графику, которую вы рисуете поверх PB или слоев. Ключевым моментом здесь является масштабирование объекта Graphics
с помощью Graphics.MultiplyTransform(Matrix)
.
Слои: Слои — это самая полезная функция в PhotoShop (и других качественных программах). Их можно достичь путем вложения прозрачных холстов для рисования. Можно использовать Panels
, я предпочитаю Labels
. Если каждый из них находится внутри расположенного под ним, а тот, что находится внизу, имеет PB в качестве Parent
, все их содержимое будет показано вместе.
- Don't use the
Label
directly but create a subclass
to hold additional data and know-how!
- Изменить их порядок не очень сложно, просто помните о вложенной структуре!
- Скрытие слоя выполняется путем установки флага и проверки этого флага в действиях рисования.
- Другие данные могут включать в себя имя, непрозрачность, возможно, цвет наложения.
- Слои также должны отображаться в палитре слоев, лучше всего создать миниатюру и вставить пользовательский объект слоя в
FlowLayoutPanel
Действия рисования: они всегда являются ключом к любому рисованию в WinForms
. При использовании мыши для рисования каждое такое действие создает объект класса DrawAction
, который вам нужно спроектировать, который содержит всю информацию, необходимую для фактического рисования, например:
- Type (Rectangle, filledRectangle, Line, FreeHandLine (a series of Points), Text, etc.etc..)
- Цвета
- Точки
- Ширина
- Текст
- Слой для рисования
- может даже поворот
Наряду с классом LayerCanvas класс DrawAction будет самым важным классом в проекте, поэтому над его дизайном стоит поработать!
Только самый верхний слой будет получать события мыши. Поэтому вам нужно отслеживать, какой слой является активным, и добавлять действие в его список действий. Разумеется, активный слой также должен быть указан в палитре слоев.
Поскольку все рисунки хранятся в списках, реализовать неограниченное количество отмен и повторов очень просто. Чтобы обеспечить эффективное рисование и отмену, возможно, лучше всего использовать общий список действий и отдельный список для каждого слоя.
- Undo and Redo are just matter of removing the last list element and pushing it onto a redo-stack.
- Также возможно редактирование действий, включая изменение параметров, перемещение их вверх или вниз по списку действий или удаление одного из середины списка. Это помогает показать палитру действий, например F9 в PhotoShop.
- Чтобы объединить два или более слоев вместе, вам нужно всего лишь объединить их списки действий.
- Чтобы свести все слои в
Image
, вам нужно всего лишь нарисовать их не на их холсте, а в изображение. Для разницы рисования в элемент управления или в растровое изображение см. здесь! Здесь у нас есть PictureBox.Image
как второй уровень структуры ПБ над Background.Image
. (Третий — это поверхность Control
, но с несколькими слоями сверху он нам на самом деле не нужен..)
Сохранение может быть выполнено либо с помощью Image.Save()
после объединения всех слоев, либо после того, как вы выключили BackgroundImage, сказав PB нарисовать себя в Bitmap
( control.DrawToBitmap()
), который вы затем можете сохранить.
Развлекайся!
person
TaW
schedule
17.01.2015