Форум программистов, компьютерный форум, киберфорум
Visual Basic .NET
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.53/15: Рейтинг темы: голосов - 15, средняя оценка - 4.53
 Аватар для Vinemax
149 / 117 / 10
Регистрация: 12.09.2011
Сообщений: 785

Выделение участка изображения в PictureBox

25.01.2015, 17:16. Показов 3377. Ответов 11
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Привет всем!

Хотел бы реализовать функцию, которая бы позволяла на изображении в PictureBox менять размер и положение участка выделения (прямоугольника) с помощью мыши, то есть, например, как в Paint или любом другом графическом редакторе. На изображении стоит прямоугольник и, тягая за его края, можно было бы менять размер этого прямоугольника. Рисование самого прямоугольника делаю так:

VB.NET
1
2
3
4
5
6
7
8
9
       Dim g As Graphics
 
        Dim bmp As New Bitmap(PictureBox1.Image)
 
        g = Graphics.FromImage(bmp) 
 
        Dim pen As New Pen(Color.Red, 3)
 
        g.DrawRectangle(pen, rect)
где rect - это тип Rectangle, определяющий его границы.

Как можно мышь к прямоугольнику привязать, чтобы менять его размеры, подскажите, пожалуйста?

Спасибо!
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
25.01.2015, 17:16
Ответы с готовыми решениями:

Выделение области изображения в picturebox
Есть изображение, внутри которого нужно выделить область с которой дальше придется работать(передвигать по экранной форме). Худо бедно, с...

Работа с pictureBox (выделение части изображения)
Здравствуйте, уважаемые форумчане. У меня появилась проблема с выделением участка картинки в pictureBox. Я хочу, чтобы выделенная...

Выделение участка на странице
Добрый день! Помогите с проектом, не силен в JS, необходимо реализовать функцию выделения участка курсором(к примеру как на рабочем столе) ...

11
39 / 28 / 8
Регистрация: 14.04.2012
Сообщений: 249
25.01.2015, 19:33
Цитата Сообщение от Vinemax Посмотреть сообщение
Как можно мышь к прямоугольнику привязать, чтобы менять его размеры, подскажите, пожалуйста?
можно считывать координаты курсора. Когда он подойдёт к границы прямоугольника, произвести нужное действие.
1
 Аватар для Vinemax
149 / 117 / 10
Регистрация: 12.09.2011
Сообщений: 785
25.01.2015, 22:17  [ТС]
kostrorod, это очевидно ) Просто хотел знать как именно это сделать
0
39 / 28 / 8
Регистрация: 14.04.2012
Сообщений: 249
25.01.2015, 22:41
Цитата Сообщение от Vinemax Посмотреть сообщение
Просто хотел знать как именно это сделать
VB.NET
1
2
3
4
5
Private Sub PictureBox1_MouseMove(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles PictureBox1.MouseMove
        
            if e.X = PozX then ' если курсор подошёл к позиции Х прямоугольника  (PozX) совершить действие
            
end sub
1
 Аватар для Petr_S
213 / 230 / 87
Регистрация: 21.04.2013
Сообщений: 404
26.01.2015, 03:23
Лучший ответ Сообщение было отмечено Vinemax как решение

Решение

Цитата Сообщение от Vinemax Посмотреть сообщение
на изображении в PictureBox менять размер и положение участка выделения (прямоугольника) с помощью мыши
Я бы сделал отдельный контрол.
Для перемещения c копированием написАл такой пример (код сырой):
VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
Public Class UC
    Inherits UserControl
 
    Private _MouseDown As Boolean = False
    Private _Coords As Point
    Private _Rectangle As Rectangle
 
    Private _Image As Bitmap
    Public Property Image As Bitmap
        Get
            Return _Image
        End Get
        Set(ByVal value As Bitmap)
            _Image = value
            Me.Refresh()
        End Set
    End Property
 
    Private _Clip As Bitmap
    Public ReadOnly Property Clip As Bitmap
        Get
            Return _Clip
        End Get
    End Property
 
    Sub New()
        Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
        Me.SetStyle(ControlStyles.UserPaint, True)
        Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True)
    End Sub
 
    Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
        'MyBase.OnMouseDown(e)
 
        _MouseDown = True
        _Coords = e.Location
 
        If Not _Rectangle.Contains(_Coords) And _Clip IsNot Nothing Then
            Graphics.FromImage(_Image).DrawImage(_Clip, _Rectangle)
            _Clip = Nothing
            _Rectangle = Nothing
            Me.Refresh()
        End If
    End Sub
    Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
        'MyBase.OnMouseUp(e)
 
        _MouseDown = False
 
        If _Rectangle.Width > 0 And _Rectangle.Height > 0 And _Clip Is Nothing Then
            _Clip = New Bitmap(_Rectangle.Width, _Rectangle.Height, Imaging.PixelFormat.Format32bppArgb)
            Graphics.FromImage(_Clip).DrawImage(_Image, _
                                                New Rectangle(0, 0, _Rectangle.Width, _Rectangle.Height), _
                                                _Rectangle, _
                                                GraphicsUnit.Pixel)
        End If
    End Sub
 
    Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
        'MyBase.OnMouseMove(e)
 
        If _MouseDown Then
            Dim c As Point = e.Location
            Dim w As Integer = c.X - _Coords.X
            Dim h As Integer = c.Y - _Coords.Y
 
            If _Clip IsNot Nothing Then
                _Rectangle.X += w
                _Rectangle.Y += h
                _Coords = c
 
            Else
 
                If w <> 0 And h <> 0 Then
                    _Rectangle = New Rectangle(If(w > 0, _Coords.X, c.X), _
                                               If(h > 0, _Coords.Y, c.Y), _
                                               Math.Abs(w), _
                                               Math.Abs(h))
                End If
 
            End If
 
            Me.Refresh()
        End If
    End Sub
 
    Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
        MyBase.OnPaint(e)
 
        If _Image IsNot Nothing Then e.Graphics.DrawImage(_Image, 0, 0, _Image.Width, _Image.Height)
 
        If _Clip IsNot Nothing Then e.Graphics.DrawImage(_Clip, _Rectangle)
 
        If _Rectangle <> Nothing Then
            Dim p As New Pen(Color.Cyan, 1)
            p.DashStyle = DashStyle.Dash
            e.Graphics.DrawRectangle(p, _Rectangle)
            p.Dispose()
        End If
    End Sub
End Class
Миниатюры
Выделение участка изображения в PictureBox  
1
 Аватар для Юпатов Дмитрий
1721 / 1208 / 228
Регистрация: 23.12.2010
Сообщений: 1,544
26.01.2015, 07:46
Лучший ответ Сообщение было отмечено Памирыч как решение

Решение

VB.NET
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
Public Class RubberBand 
    ' ----- The three types of rubber bands. 
    Public Enum RubberBandStyle 
        DashedLine 
        ThickLine 
        SolidBox 
        SolidBoxWithDashedLine 
    End Enum 
 
    ' ----- The current drawing state. 
    Public Enum RubberBandState 
        Inactive 
        FirstTime 
        Active 
    End Enum 
 
    ' ----- Class-level variables. 
    Private BasePoint As Point 
    Private ExtentPoint As Point 
    Private CurrentState As RubberBandState 
    Private BaseControl As Control 
    Public Style As RubberBandStyle 
    Public BackColor As Color 
    Public Sub New(ByVal useControl As Control, _ 
          Optional ByVal useStyle As RubberBandStyle = _ 
          RubberBandStyle.DashedLine) 
        ' ----- Constructor with one or two parameters. 
        BaseControl = useControl 
        Style = useStyle 
        BackColor = Color.Black 
    End Sub 
 
    Public Sub New(ByVal useControl As Control, ByVal useStyle As RubberBandStyle, ByVal useColor As Color) 
        ' ----- Constructor with three parameters. 
        BaseControl = useControl 
        Style = useStyle 
        BackColor = useColor 
    End Sub 
 
    Public ReadOnly Property Rectangle() As Rectangle 
        Get 
            ' ----- Return the bounds of the  rubber-band area. 
            Dim result As Rectangle 
 
            ' ----- Ensure the coordinates go left to 
            ' right, top to bottom. 
            result.X = IIf(BasePoint.X < ExtentPoint.X, _ 
               BasePoint.X, ExtentPoint.X) 
            result.Y = IIf(BasePoint.Y < ExtentPoint.Y, _ 
               BasePoint.Y, ExtentPoint.Y) 
            result.Width = Math.Abs(ExtentPoint.X - BasePoint.X) 
            result.Height = Math.Abs(ExtentPoint.Y - BasePoint.Y) 
            Return result 
        End Get 
    End Property 
 
    Public Sub Start(ByVal x As Integer, ByVal y As Integer) 
        ' ----- Start drawing the rubber band. The user must 
        '       call Stretch() to actually draw the first 
        '       band image. 
        BasePoint.X = x 
        BasePoint.Y = y 
        ExtentPoint.X = x 
        ExtentPoint.Y = y 
        Normalize(BasePoint) 
        CurrentState = RubberBandState.FirstTime 
    End Sub 
 
    Public Sub Stretch(ByVal x As Integer, ByVal y As Integer) 
        ' ----- Change the size of the rubber band. 
        Dim newPoint As Point 
 
        ' ----- Prepare the new stretch point. 
        newPoint.X = x 
        newPoint.Y = y 
        Normalize(newPoint) 
 
        Select Case CurrentState 
            Case RubberBandState.Inactive 
                ' ----- Rubber band not in use. 
                Return 
            Case RubberBandState.FirstTime 
                ' ----- Draw the initial rubber band. 
                ExtentPoint = newPoint 
                DrawTheRectangle() 
                CurrentState = RubberBandState.Active 
            Case RubberBandState.Active 
                ' ----- Undraw the previous band, then 
                '       draw the new one. 
                DrawTheRectangle() 
                ExtentPoint = newPoint 
                DrawTheRectangle() 
        End Select 
    End Sub 
 
    Public Sub Finish() 
        ' ----- Stop drawing the rubber band. 
        DrawTheRectangle() 
        CurrentState = 0 
    End Sub 
 
    Private Sub Normalize(ByRef whichPoint As Point) 
        ' ----- Don't let the rubber band go outside the view. 
        If (whichPoint.X < 0) Then whichPoint.X = 0 
        If (whichPoint.X >= BaseControl.ClientSize.Width) Then whichPoint.X = BaseControl.ClientSize.Width - 1 
 
        If (whichPoint.Y < 0) Then whichPoint.Y = 0 
        If (whichPoint.Y >= BaseControl.ClientSize.Height) Then whichPoint.Y = BaseControl.ClientSize.Height - 1 
    End Sub 
 
    Private Sub DrawTheRectangle() 
        ' ----- Draw the rectangle on the control or 
        '       form surface. 
        Dim drawArea As Rectangle 
        Dim screenStart, screenEnd As Point 
 
        ' ----- Get the square that is the  rubber-band area. 
        screenStart = BaseControl.PointToScreen(BasePoint) 
        screenEnd = BaseControl.PointToScreen(ExtentPoint) 
        drawArea.X = screenStart.X 
        drawArea.Y = screenStart.Y 
        drawArea.Width = (screenEnd.X - screenStart.X) 
        drawArea.Height = (screenEnd.Y - screenStart.Y) 
 
        ' ----- Draw using the user-selected style. 
        Select Case Style 
            Case RubberBandStyle.DashedLine 
                ControlPaint.DrawReversibleFrame( _ 
                   drawArea, BackColor, FrameStyle.Dashed) 
            Case RubberBandStyle.ThickLine 
                ControlPaint.DrawReversibleFrame( _ 
                   drawArea, BackColor, FrameStyle.Thick) 
            Case RubberBandStyle.SolidBox 
                ControlPaint.FillReversibleRectangle( _ 
                   drawArea, BackColor) 
            Case RubberBandStyle.SolidBoxWithDashedLine 
                ControlPaint.FillReversibleRectangle( _ 
                   drawArea, BackColor) 
                ControlPaint.DrawReversibleFrame( _ 
                   drawArea, Color.Black, FrameStyle.Dashed) 
        End Select 
    End Sub 
End Class
В коде формы
VB.NET
1
Friend SelectionArea As RubberBand
И, например в процедуре загрузки формы
VB.NET
1
SelectionArea = New RubberBand(Me.Poligon, RubberBand.RubberBandStyle.DashedLine, Color.FromArgb(255, 0, 255))
где poligon - контрол, на котором рисуем выделение (если форма - me)
RubberBand.RubberBandStyle.DashedLine - стиль очерчивания (описан в классе rubberband)
Последний параметр - Цвет области выделения
И работа с ним при нажатии на кнопку мыши в пределах контрола, на котором рисуем область (mouse_down)
VB.NET
1
SelectionArea.Start(e.X, e.Y)
при очерчивании прямоугольника (при нажатой кнопке мыши (mousemove)
VB.NET
1
2
3
If e.Button = Windows.Forms.MouseButtons.Left Then 
            SelectionArea.Stretch(e.X, e.Y) 
        End If
Ну и при отпускании кнопки, в конце очерчивания области (mouseup)
VB.NET
1
SelectionArea.Finish()
В итоге объект SelectionArea будет иметь в своей структуре координаты прямоугольной области выделения.
Ну а дальше с этой информацией уже обрабатывайте то, что выделяли.
3
 Аватар для Vinemax
149 / 117 / 10
Регистрация: 12.09.2011
Сообщений: 785
26.01.2015, 08:53  [ТС]
Юпатов Дмитрий, спасибо большое! Буду пробовать сейчас...
0
 Аватар для jkrnd
179 / 69 / 13
Регистрация: 22.12.2015
Сообщений: 2,648
18.12.2016, 04:36
Юпатов Дмитрий, прямоугольник выделения запаздывает за курсором мыши и сильно моргает при выделении - это неизбежно? Ведь в графических редакторах этих эфектов нет. А если попробовать вместо FillReversibleRectangle функцию API DrawFocusRect?
0
 Аватар для Юпатов Дмитрий
1721 / 1208 / 228
Регистрация: 23.12.2010
Сообщений: 1,544
18.12.2016, 11:40
не должен вообще то
0
 Аватар для jkrnd
179 / 69 / 13
Регистрация: 22.12.2015
Сообщений: 2,648
18.12.2016, 11:56
Юпатов Дмитрий, в архиве Ваш вариант, пример из MSDN и вариант с использованием API. Попробуйте

Не по теме:

Кстати, если подскажете как избавится от моргания изображения при старте захвата экрана (проект DrawFocusRect), буду очень признателен.

Вложения
Тип файла: rar SelectArea.rar (157.6 Кб, 92 просмотров)
3
 Аватар для Юпатов Дмитрий
1721 / 1208 / 228
Регистрация: 23.12.2010
Сообщений: 1,544
18.12.2016, 13:39
Хм... вариант с API самый шикарный, конечно.
2
85 / 75 / 15
Регистрация: 18.01.2014
Сообщений: 359
11.04.2018, 22:24
А с произвольной областью, не прямоугольной (например овал) можно что-нибудь придумать?

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

Или например System.Drawing.Drawing2D.GraphicsPath, в котором координаты вершин произвольной фигуры.

Добавлено через 4 часа 5 минут
Придумал алгоритм, но в одном месте застопорился.

1) Берем Path as GraphicPath,
2) у этого Path берем GetBounds
3) добавляем прямоугольник Getbounds к GraphicPath (Path.AddRectangle)
4) рисуем на отдельном новом BMP прямоугольную часть исходного изображения обрамленную Path.getbounds
5) Закрашиваем ненужные фрагменты у нового BMP, например белым цветом с помощью g.fillpath(white,Path)
6) Делаем белый цвет прозрачным
6.3) небольшая проблема с масштабом размеров между исходной картинкой и новым BMP, но она решаема
6.5) А вот здесь проблема: если в нужной части картинки тоже есть белый цвет, то он станет также прозрачным
7) в нужном месте исходной картинки рисуем этот BMP
Итого: копируется не прямоугольная, а произвольная замкнутая область
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
11.04.2018, 22:24
Помогаю со студенческими работами здесь

Склеивание изображения нескольких picturebox в один picturebox
Здравствуй, такой вопрос возник на счет picturebox. Можно ли из 3-ех к примеру picturebox(в каждом одинаковая картинка) Склеить все...

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

Как добиться качественного рисования изображения поверх изображения picturebox?
есть код: PictureBox p = (PictureBox)sender; p.SizeMode = PictureBoxSizeMode.Normal; ...

Поиск участка изображения
Как заскринить экран(каким способом?) найти небольшой кусок в изображении и занести его координаты в переменную. Как сделать еще это с...

Показ определённого участка изображения
Есть картинка picture.png на которой определённое количество мелких рисунков(четыре шт.). Разрешение у картинки 16x64. Картинка добавляется...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
12
Ответ Создать тему
Новые блоги и статьи
Реалии
Hrethgir 01.03.2026
Нет, я не закончил до сих пор симулятор. Эта задача сложнее. Не получилось уйти в плавсостав, но оно и к лучшему, возможно. Точнее получалось - но сварщиком в палубную команду, а это значит, в моём. . .
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка библиотек: SDL3, Box2D, FreeType, SDL3_ttf, SDL3_mixer и SDL3_image из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru