Как сделать picturebox paint

Обновлено: 07.07.2024

БлогNot. Visual C++/CLI: рисуем линию на PictureBox "как в Paint"

Visual C++/CLI: рисуем линию на PictureBox "как в Paint"

То есть, при движении мыши с зажатой кнопкой линия должна динамически обновляться, а при отпускании кнопки добавляться на существующий рисунок. Так как PictureBox удобно сохранять и легко снабдить полосами прокрутки, будем рисовать на ней. Компонента может быть частью интерфейса приложения как в этой заметке или растянутой на всю форму. Проект создан как приложение Windows Forms, код проверен в Visual Studio 2015.

Для самой формы нам понадобится запрограммировать только событие Load , где мы инициализируем всё, что нужно - создадим рисунок по текущим размерам PictureBox , назначим его компоненте, создадим перо и выставим в "ложь" флажок:

Ещё лучше было создать рисунок размером с клиентскую часть окна формы:

Всё остальное запрограммируем в событиях PictureBox . На нажатие кнопки мыши будем включать флажок и запоминать место клика p1 :

На отпускание кнопки получим координаты второй точки p2 и соединим её с первой, проведя линию на образе Img1 . В реальном коде можно добавлять точки в какой-то контейнер, например, в список как здесь.

На перемещение мыши обработка будет немного хитрей. Если кнопка не зажата, ничего делать не нужно, а в противном случае будем проводить текущую линию на копии рисунка Img2 , созданной из Img1 , чтобы не получилось "веера" из линий при перемещении мыши с зажатой кнопкой. Img2 всё равно придётся временно назначить рисунком для PictureBox , чтобы линия была видна в процессе движения мыши.

Это всё, приложение можно собирать.

P.S. Здесь у нас все координаты были "внутри PictureBox " и получались непосредственно из аргумента MouseEventArgs обработчика события. По-другому можно делать так:

К сожалению, из-за плохой "очистки мусора" (а мы создаём каждый раз временную копию рисунка при движении мыши с зажатой кнопкой) такое приложение может быстро пожирать память.

Можно, конечно, ввести ещё список "тип фигуры" и рисовать другие объекты.

Если хотим рисовать просто карандашом "по точкам", можно применять и подход с таймером (код для той же формы):


Чтобы область под график pictureBox изменяла свои размеры с изменением размеров формы, установим ей свойство Anchor как на картинке:


теперь если менять размеры формы, и область под график будет меняться соответственно:

Всю отрисовку на PictureBox, полагается выполнять внутри функции привязанного к событию Paint

Выбираем на форме pictureBox переходим в список событий, и кликаем дважды на свойство Paint


оказываемся в новосозданной функции

Попробуем нарисовать график, пока без учета коэффициентов.

Чтобы нарисовать график нам надо сформировать список точек, подготовим его

и так, точки у нас есть, теперь их надо нарисовать. Прежде чем вызвать функцию для отрисовки, надо указать как будет выглядеть линия, Для этого надо создать объект типа Pen (то бишь перо, ручка), у которого есть два основных параметра: цвет и ширина линии, создадим такой объект:

ну а теперь можно нарисовать график, для этого воспользуемся функций DrawLines, объекта Graphics (так называемый графический контекст устройства) который привязан к аргументу PaintEventArgs e

Увидим что-то несуразное:


Если попытаться угадать в этом параболу, то увидим сразу несколько проблем:

  • видно только правую ветвь параболы
  • парабола перевёрнута
  • график сильно маленький

Матрицы перехода являются одним из основополагающих математических инструментов в создании 3D графики, который в упрощённом виде работает и в 2D графике (с чем мы собственно сейчас и работаем).

Ко всякому объекту типа Graphics привязана матрица переходов (доступная через свойство Transform). По умолчанию она представляет собой единичную матрицу. Мы можем изменять матрицу используя методы объекта типа Graphics

  • TranslateTransform – для перемещения центра координат
  • ScaleTransform – для масштабирования
  • RotateTransform – для поворота вокруг центра координат

Применяя эти методы в разных порядках можно перемещать, масштабировать и крутить объекты и даже группы объектов малой кровью.

Мы конечно особо ничего крутить ничего не планируем. Но давайте перенесем центр координат в центр pictureBox, добавим строчку:


Очевидно, что у параболы с коэффициентом 1, ветви параболы должны быть направлены вверх. И хотя мы абсолютно верно формируем список точек:

ошибка возникает из-за того, что центр координат, у большинства системных объектов, находится в левом верхнем углу:


чтобы перевернуть график воспользуемся функцией ScaleTransform


И вот вроде все отлично, но график рисуется в пиксельной системе координат. Что на небольших мониторах выглядит еще куда ни шло, но на современных Ultra HD и 4K придется использовать лупу. Мы конечно не хотим заставлять пользователя доставать лупу, но зато мы можем увеличить масштаб графика, снова воспользовавшись функций ScaleTransform. Добавим строчку:


неплохо, но линия какая-та толстая. Она масштабируется вместе со всем остальным, что не есть хорошо. Чтобы избавится от масштабирования линии придется модифицировать ее матрицу перехода. Да-да, у объекта типа Pen тоже есть своя матрица перехода, также доступная через свойство Transform.

Какую же матрицу перехода применять к линии? Очевидно, обратную к матрице основного Graphics. Сделаем это:

вот теперь другое дело


Чтобы лучше ориентироваться где какая точка находится нарисуем сетку с размером ячейки в одну единицу


кстати можно сделать чтобы единица на экране соответствовала одному сантиметру в реальной жизни и получить своего рода экранную линейку. Для этого надо воспользоваться свойством DpiX и DpiY объекта Graphics, пробуем. Dpi определяет количество точек на дюйм. В одном дюйме примерно 2.54 сантиметра, следовательно, нам надо отредактировать вызов функции скалирования следующим образом:

достаем линейку, прикладываем к экрану:


так себе точность, конечно, получается, но результат все-таки радует.

Возможны вы уже пробовали менять размеры формы, и заметили, что получаемый результат далек от ожидаемого.

связано такое поведение с особенностью перерисовки объектов на форме. Перерисовывается только изменённая часть. А так как при разных размерах формы положение графика и сетки разное получается наложение десятка разных изображений, что приводит к таким ужасным артефактам.

Чтобы при изменении размера формы изображение перерисовывалось всегда целиком, добавьте обработчик событию Resize, объекта pictureBox


и в обработчике вставьте строчку:

Сейчас у нас графи рисуется по целым координатам, из-за чего выглядит слегка уродливо и сильно угловато. Давайте увеличим количество точек. В этот раз, при формировании списка точек, я, вместо цикла, воспользуюсь Linq функциями, которые позволят мне сформировать список точек в функциональной манере с использованием лямбда-выражений.

запускаем, получаем гладенький график:


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

хм, чего-то не работает…

А ну да, нам же надо чтобы при изменении значения, вызывался метод pictureBox.Invalidate(), тот самый которые отправляет запрос на перерисовку всего pictureBox. Переключаемся на форму, и кликаем два разу на txtK, а затем на txtN, добавляем код в соответствующие обработчики:

Если вы в какой-то момент запутались, то вот вам итоговый код функции отрисовки:

Всем привет! У меня вот такая проблема.. на форме размещен pictureBox и нужно нарисовать, используя события мыши прямоугольник. Дело в том что DrawRectangle рисует только вниз и в право, а нужно чтобы прямоугольник рисовался во все стороны. В общем то рисование прямоугольника вверх лево реализовать удалось а на остальное мозгов не хватило . Пожалуйста момогите помогите!!

__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь

Рисование прямоугольника мышью: фон PictureBox становится черным
Всё просто. необходимо мышью нарисовать прямоугольник на picturebox Прямоугольник рисуется, но.

Рисование круга мышью на PictureBox
Доброго времени суток, в ходе обучения возник вопрос "а как сделать круг" из имеющиеся функции.

Рисование прямоугольника на picturebox
На форме находится picturebox, на котором нужно нарисовать прямоугольник. В метод Draw с помощью.

Рисование прямоугольника на PictureBox с помощью мыши
Добрый день. Можете подсказать элементарное рисование на PictureBox прямоугольника мышью. Заранее.

Петр, попробовала вставить ваш код в свою прогу. Возникли небольшие проблемы:
В общем, мне надо, чтобы прямоугольник можно было рисовать после нажатия кнопки:

Все остальные события для MouseMove,MouseDown,MouseUp,pictureBox_Paint делаю в точности, как у вас.

При этом прямоугольник, все равно рисуется даже без нажатия кнопки.
Пробовала сделать так:

Но тогда прямоугольник отрисовывается некорректно: за начальную точку всегда берется конечная точка предыдущего треугольника. Я предполагаю, что как-то по-другому надо задать начальную точку Но как это сделать, ума не приложу. Подскажите, пожалуйста.

Ну в общем то поспрашивал у своих коллег и решил проблему.. скинул тут код:

тут задаются начальные координаты:


Ну а тут уже на событии MouseUp оставляем рисунок на Picturebox:
TheMrCPlay, пожалуйста, скиньте ту часть кода, где определяются переменные, потому что не совсем понятно, что такое drawG и picG, и чем они отличаются.

Прошу прощение что так поздно отвечаю! Но лучше поздно, чем никогда

Тут определение переменных:

TheMrCPlay, пожалуйста, скиньте ту часть кода, где определяются переменные, потому что не совсем понятно, что такое drawG и picG, и чем они отличаются. DrawG-обозначил как черновк т.е как в паинте пытаешься нарисовать какую либо фигуру, когда ты ее тянешь
A PicG - когда уже на pictureBox рисуется фигура тех размеров которая тебе нужна

Петррр, такой вопрос. А если поместить в picturebox картинку, у которой размер подогнан под размер picturebox-а (что-то вроде отмасштабирована), то как можно узнать (пересчитать) начальную и конечную точки прямоугольника?

Т.е. после рисования прямоугольника моя программа должна будет вставить некий объект в файл, а чтобы получить область вставки и не перекрыть уже существующие объекты, как раз и хочу воспользоваться вашим методом рисования на превьюшке, для получения начальной и конечной точки области.
Спасибо.

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Представляет элемент управления Windows "поле рисунка", предназначенный для отображения рисунков.

Примеры

В следующем примере кода показано, как можно задать изображение и изменить размер области отображения окна изображения. В этом примере требуется, ShowMyImage чтобы он вызывался в существующей форме, а System.Drawing пространство имен было добавлено в исходный код для формы.

Комментарии

Обычно PictureBox используется для вывода графических изображений из файла точечного рисунка, метафайла, значка, JPEG, GIF или PNG.

Задайте Image для свойства значение, которое нужно Image отобразить во время разработки или во время выполнения. Можно также указать образ, задав ImageLocation свойство и загружая образ синхронно с помощью Load метода или асинхронно с помощью LoadAsync метода.

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

SizeModeСвойство, для которого заданы значения в PictureBoxSizeMode перечислении, управляет обрезкой и положением изображения в области просмотра. Можно изменить размер области просмотра во время выполнения с помощью ClientSize Свойства.

По умолчанию PictureBox элемент управления отображается без границ. Можно предоставить стандартную или трехмерную границу с помощью BorderStyle свойства, чтобы отличить поле изображения от остальной части формы, даже если оно не содержит изображения. Не PictureBox является выбираемым элементом управления, что означает, что он не может получать фокус ввода.

Конструкторы

Инициализирует новый экземпляр класса PictureBox.

Свойства

Получает объект AccessibleObject, назначенный элементу управления.

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

Возвращает или задает описание элемента управления, используемого клиентскими приложениями со специальными возможностями.

Возвращает или задает имя элемента управления, используемого клиентскими приложениями со специальными возможностями.

Возвращает или задает доступную роль элемента управления.

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

Возвращает или задает местоположение, в котором выполняется прокрутка этого элемента управления в ScrollControlIntoView(Control).

Данное свойство не применимо к этому классу.

Возвращает или задает цвет фона для элемента управления.

Возвращает или задает фоновое изображение, отображаемое на элементе управления.

Возвращает или задает макет фонового изображения в соответствии с перечислением ImageLayout.

Возвращает или задает значение BindingContext для элемента управления.

Указывает стиль границы элемента управления.

Возвращает расстояние в пикселях между нижней границей элемента управления и верхней границей клиентской области контейнера.

Возвращает или задает размер и местоположение (в пикселях) элемента управления, включая его неклиентские элементы, относительно его родительского элемента управления.

Получает значение, указывающее, можно ли для свойства ImeMode установить активное значение с целью включения поддержки IME.

Возвращает значение, указывающее, может ли элемент управления получать фокус.

Определяет, могут ли вызываться события в элементе управления.

Возвращает значение, указывающее, доступен ли элемент управления для выбора.

Возвращает или задает значение, указывающее, была ли мышь захвачена элементом управления.

Возвращает прямоугольник, представляющий клиентскую область элемента управления.

Возвращает или задает высоту и ширину клиентской области элемента управления.

Возвращает название организации или имя создателя приложения, содержащего элемент управления.

Возвращает объект IContainer, который содержит коллекцию Component.

Возвращает значение, указывающее, имеет ли элемент управления или один из его дочерних элементов фокус ввода в настоящий момент.

Возвращает или задает контекстное меню, связанное с элементом управления.

Возвращает или задает объект ContextMenuStrip, сопоставленный с этим элементом управления.

Возвращает коллекцию элементов управления, содержащихся в элементе управления.

Возвращает значение, указывающее, был ли создан элемент управления.

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

Возвращает привязки данных для элемента управления.

Возвращает или задает курсор по умолчанию для элемента управления.

Получает значение, определяющее режим редактора методов ввода для PictureBox.

Возвращает размер пустого пространства в пикселях между элементами управления, которое определено по умолчанию.

Возвращает длину и высоту в пикселях, которые были указаны в качестве максимального размера элемента управления.

Возвращает длину и высоту в пикселях, которые были указаны в качестве минимального размера элемента управления.

Возвращает внутренние промежутки в содержимом элемента управления в пикселях.

Получает размер элемента управления по умолчанию.

Возвращает значение, указывающее, находится ли данный компонент Component в режиме конструктора в настоящее время.

Получает значение DPI для устройства, на котором сейчас отображается элемент управления.

Возвращает прямоугольник, представляющий отображаемую область элемента управления.

Получает значение, указывающее, находится ли базовый класс Control в процессе удаления.

Возвращает или задает границы элемента управления, прикрепленные к его родительскому элементу управления, и определяет способ изменения размеров элемента управления с его родительским элементом управления.

Возвращает или задает значение, указывающее, должна ли поверхность этого элемента управления перерисовываться с помощью дополнительного буфера, чтобы уменьшить или предотвратить мерцание.

Возвращает или задает значение, указывающее, может ли элемент управления отвечать на действия пользователя.

Возвращает или задает изображение, предназначенное для отображения при возникновении ошибки во время загрузки изображения или при отмене загрузки.

Возвращает список обработчиков событий, которые прикреплены к этому объекту Component.

Возвращает значение, указывающее, имеется ли на элементе управления фокус ввода.

Возвращает или задает шрифт текста, отображаемого элементом управления.

Возвращает или задает высоту шрифта элемента управления.

Возвращает дескриптор окна, с которым связан элемент управления.

Возвращает значение, указывающее, содержит ли элемент управления один или несколько дочерних элементов.

Возвращает или задает высоту элемента управления.

Получает или задает изображение, отображаемое элементом управления PictureBox.

Получает или задает путь или URL-адрес изображения для отображения в PictureBox.

Возвращает или задает режим редактора метода ввода, поддерживаемый данным элементом управления.

Получает или задает режим IME элемента управления.

Получает или задает изображение, отображаемое в элементе управления PictureBox при загрузке основного изображения.

Возвращает значение, указывающее, следует ли вызывающему оператору обращаться к методу invoke во время вызовов метода из элемента управления, так как вызывающий оператор находится не в том потоке, в котором был создан элемент управления.

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

Указывает, является ли один из предков этого элемента управления узлом и этим сайтом в Десигнмоде. Это свойство доступно только для чтения.

Возвращает значение, указывающее, был ли удален элемент управления.

Возвращает значение, указывающее, имеется ли у элемента управления связанный с ним дескриптор.

Возвращает значение, указывающее, отображается ли зеркально элемент управления.

Получает кэшированный экземпляр механизма размещения элемента управления.

Возвращает или задает расстояние в пикселях между левой границей элемента управления и левой границей клиентской области его контейнера.

Возвращает или задает координаты левого верхнего угла элемента управления относительно левого верхнего угла его контейнера.

Возвращает или задает расстояние между элементами управления.

Возвращает или задает размер, являющийся верхней границей, которую может указать метод GetPreferredSize(Size).

Возвращает или задает размер, являющийся нижней границей, которую может указать метод GetPreferredSize(Size).

Возвращает или задает имя элемента управления.

Возвращает или задает заполнение в элементе управления.

Возвращает или задает родительский контейнер элемента управления.

Возвращает размер прямоугольной области, в которую может поместиться элемент управления.

Возвращает имя продукта сборки, содержащей элемент управления.

Возвращает версию сборки, содержащую элемент управления.

Возвращает значение, указывающее, осуществляет ли в настоящий момент элемент управления повторное создание дескриптора.

Возвращает или задает область окна, связанную с элементом управления.

Это свойство устарело.

Возвращает или задает значение, указывающее, перерисовывается ли элемент управления при изменении размеров.

Возвращает расстояние в пикселях между правой границей элемента управления и левой границей клиентской области его контейнера.

Возвращает или задает значение, указывающее, выровнены ли компоненты элемента управления для поддержки языков, в которых используется направление письма справа налево.

Получает значение, определяющее масштабирование дочерних элементов управления.

Возвращает значение, указывающее, должен ли элемент управления отображать прямоугольники фокуса.

Возвращает значение, указывающее, имеет ли пользовательский интерфейс соответствующее состояние, при котором отображаются или скрываются сочетания клавиш.

Возвращает или задает местонахождение элемента управления.

Возвращает или задает высоту и ширину элемента управления.

Указывает способ отображения изображения.

Возвращает или задает значение индекса перехода по TAB.

Возвращает или задает значение, указывающее, может ли пользователь переместить фокус на элемент управления при помощи клавиши TAB.

Возвращает или задает объект, содержащий данные об элементе управления.

Получает или задает текст объекта PictureBox.

Возвращает или задает расстояние в пикселях между верхней границей элемента управления и верхней границей клиентской области его контейнера.

Получает родительский элемент управления, не имеющий другого родительского элемента управления Windows Forms. Как правило, им является внешний объект Form, в котором содержится элемент управления.

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

Возвращает или задает значение, указывающее, отображаются ли элемент управления и все его дочерние элементы управления.

Возвращает или задает значение, указывающее, синхронно ли загружено изображение.

Возвращает или задает ширину элемента управления.

Данное свойство не применимо к этому классу.

Методы

Уведомляет клиентские приложения со специальными возможностями об указанном перечислении AccessibleEvents для указанного дочернего элемента управления.

Уведомляет клиентские приложения со специальными возможностями об указанном перечислении AccessibleEvents для указанного дочернего элемента управления.

Выполняет указанный делегат асинхронно в потоке, в котором был создан базовый дескриптор элемента управления.

Выполняет указанный делегат асинхронно в потоке, в котором был создан базовый дескриптор элемента управления.

Выполняет указанный делегат асинхронно с указанными аргументами в потоке, в котором был создан базовый дескриптор элемента управления.

Помещает элемент управления в начало z-порядка.

Отменяет асинхронную загрузку изображения.

Возвращает значение, указывающее, является ли указанный элемент управления дочерним элементом.

Создает для элемента управления новый объект с поддержкой специальных возможностей.

Вызывает принудительное создание видимого элемента управления, включая создание дескриптора и всех видимых дочерних элементов.

Создает новый экземпляр коллекции элементов управления для данного элемента управления.

Создает объект Graphics для элемента управления.

Создает дескриптор для элемента управления.

Создает объект, который содержит всю необходимую информацию для создания прокси-сервера, используемого для взаимодействия с удаленным объектом.

Удаляет дескриптор, связанный с элементом управления.

Освобождает все ресурсы, занятые модулем Component.

Освобождает неуправляемые ресурсы, используемые объектом PictureBox, а при необходимости освобождает также управляемые ресурсы.

Начинает операцию перетаскивания.

Поддерживает отрисовку в указанном точечном рисунке.

Получает возвращаемое значение асинхронной операции, представленное переданным объектом IAsyncResult.

Определяет, равен ли указанный объект текущему объекту.

Возвращает форму, в которой находится элемент управления.

Устанавливает фокус ввода на элемент управления.

Получает указанный объект AccessibleObject.

Получает значение, указывающее, как будет вести себя элемент управления, когда его свойство AutoSize включено.

Возвращает дочерний элемент управления, имеющий указанные координаты.

Возвращает дочерний элемент управления, расположенный по указанным координатам, определяя, следует ли игнорировать дочерние элементы управления конкретного типа.

Возвращает следующий объект ContainerControl в цепочке родительских элементов управления данного элемента.

Служит хэш-функцией по умолчанию.

Извлекает объект обслуживания во время существования, который управляет политикой времени существования данного экземпляра.

Возвращает следующий или предыдущий элемент среди дочерних элементов управления в последовательности клавиши TAB.

Вычисляет размер прямоугольной области, в которую помещается элемент управления.

Возвращает границы, внутри которых масштабируется элемент управления.

Возвращает объект, представляющий службу, предоставляемую классом Component или классом Container.

Возвращает значение указанного бита стиля элемента управления для данного элемента управления.

Определяет, находится ли элемент управления на верхнем уровне.

Возвращает объект Type для текущего экземпляра.

Скрывает элемент управления от пользователя.

Получает объект службы времени существования для управления политикой времени существования для этого экземпляра.

Вызывается после добавления элемента управления в другой контейнер.

Делает недействительной всю поверхность элемента управления и вызывает его перерисовку.

Выполняет указанный делегат в том потоке, которому принадлежит базовый дескриптор окна элемента управления.

Выполняет указанный делегат в том потоке, которому принадлежит базовый дескриптор окна элемента управления.

Выполняет указанный делегат в том потоке, которому принадлежит основной дескриптор окна элемента управления, с указанным списком аргументов.

Выполняет указанный делегат в том потоке, которому принадлежит базовый дескриптор окна элемента управления.

Вызывает событие GotFocus для указанного элемента управления.

Вызывает событие LostFocus для указанного элемента управления.

Вызывает событие Click для указанного элемента управления.

Вызывает событие Paint для указанного элемента управления.

Вызывает событие PaintBackground для указанного элемента управления.

Определяет, является ли символ входным символом, который распознается элементом управления.

Определяет, является ли заданная клавиша обычной клавишей ввода или специальной клавишей, нуждающейся в предварительной обработке.

Отображает изображение, указанное в свойстве ImageLocation объекта PictureBox.

Задает значение свойства ImageLocation, равное указанному URL-адресу, и отображает указанное изображение.

Асинхронно загружает изображение.

Асинхронно загружает изображение в указанное расположение.

Преобразует логическое значение DPI в эквивалентное значение DPI DeviceUnit.

Преобразует размер из логических единиц в единицы устройства путем его масштабирования к текущему DPI и округлением вниз до ближайшего целого значения ширины и высоты.

Создает неполную копию текущего объекта Object.

Создает неполную копию текущего объекта MarshalByRefObject.

Вызывает событие Invalidated, чтобы сделать недействительной указанную область элемента управления.

Читайте также: