0 / 0 / 1
Регистрация: 09.11.2013
Сообщений: 72
1

Выделение прямоугольной области в PictureBox мышкой

14.08.2014, 04:03. Показов 11701. Ответов 5
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Делаю простенький редактор изображений для себя.
Нужно сделать что то типа выделения отдельного прямоугольника изображения для дальнейших манипуляций с этим куском изображения.

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

C#
1
2
3
4
5
6
7
8
9
10
Graphics g1 = this.pictureBox.CreateGraphics();
private void pictureBox_MouseMove(object sender, MouseEventArgs e) //событие на перемещение мыши
        {
            if (mousePressed == true)
            {
                pictureBox.Image = my_bmp;  // перерисовываю картинку 
                g1.DrawRectangle(new Pen(Color.Green, 3), MM.Create_rect(drag_start, e.Location)); // тут обвожу выделяемую область прамоугольником.  
                
            }
        }
все какбы работает более менее сносно, но каким то образом pictureBox.Image = my_bmp отрисовывается позже чем g1.DrawRectangle. Тоесть пока тяну мышкой прямоугольниг моргает, но при остановке его закрывает pictureBox.Image = my_bmp.

я ради теста пробовал обновлять рисунок pictureBox.Image = my_bmp. только на каждое третее срабатывание MouseMove. тогда прямоугольник рисуемый в g1.DrawRectangle() остовался видемым примерно и 66% случаев. Тоесть проблема имено в том что pictureBox.Image = my_bmp рисуется после g1.DrawRectangle();
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
14.08.2014, 04:03
Ответы с готовыми решениями:

Программное выделение области на PictureBox
Всем привет, есть небольшая проблема, возможно ли сделать чтобы на одном picturebox выделялась...

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

Выделение области в PictureBox и сохранение ее в Bitmap
Вот к примеру pictureBox, как сделать так что бы на нем можно было выделить область и эта...

Выделение мышкой 2D объекта не прямоугольной формы
Добрый день. У меня вопрос: есть ли в юнити функционал для выделения объектов 2D, но не...

5
8942 / 4854 / 1886
Регистрация: 11.02.2013
Сообщений: 10,246
14.08.2014, 04:47 2
Лучший ответ Сообщение было отмечено Figga как решение

Решение

Если ты назначил рисунок через свойство Image, то его не нужно перерисовывать. Оно находится как бы в бэкграунде и всё рисуется поверх него.
Я предпочитаю переключать события рисования. См. пример:
C#
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
using System;
using System.Drawing;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {
        Rectangle selRect;
        Point orig;
        Pen pen = new Pen(Brushes.Blue, 0.8f) { DashStyle = System.Drawing.Drawing2D.DashStyle.Dash };
        public Form1() {
            InitializeComponent();
            pictureBox1.Paint += pictureBox1_Paint;
            pictureBox1.MouseMove += pictureBox1_MouseMove;
            pictureBox1.MouseUp += pictureBox1_MouseUp;
            pictureBox1.MouseDown += pictureBox1_MouseDown;
        }
 
        void pictureBox1_MouseUp(object sender, MouseEventArgs e) {
            //Возвращаем основную процедуру рисования
            pictureBox1.Paint -= Selection_Paint;
            pictureBox1.Paint += pictureBox1_Paint;
            pictureBox1.Invalidate();
        }
 
        void pictureBox1_MouseDown(object sender, MouseEventArgs e) {
            //Назначаем процедуру рисования при выделении
            pictureBox1.Paint -= pictureBox1_Paint;
            pictureBox1.Paint += Selection_Paint;
            orig = e.Location;
        }
 
        //Рисование мышкой с нажатой кнопкой
        private void Selection_Paint(object sender, PaintEventArgs e) {
            e.Graphics.DrawRectangle(pen, selRect);
        }
 
        void pictureBox1_MouseMove(object sender, MouseEventArgs e) {
            //при движении мышкой считаем прямоугольник и обновляем picturebox
            selRect = GetSelRectangle(orig, e.Location);
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
                (sender as PictureBox).Refresh();
        }
 
        //основное событие рисования
        void pictureBox1_Paint(object sender, PaintEventArgs e) {
            e.Graphics.DrawRectangle(Pens.Black, selRect);
        }
 
        Rectangle GetSelRectangle(Point orig, Point location) {
            int deltaX = location.X - orig.X, deltaY = location.Y - orig.Y;
            Size s = new Size(Math.Abs(deltaX), Math.Abs(deltaY));
            Rectangle rect = new Rectangle();
            if (deltaX >= 0 & deltaY >= 0)
                rect = new Rectangle(orig, s);
            if (deltaX < 0 & deltaY > 0)
                rect = new Rectangle(location.X, orig.Y, s.Width, s.Height);
            if (deltaX < 0 & deltaY < 0)
                rect = new Rectangle(location, s);
            if (deltaX > 0 & deltaY < 0)
                rect = new Rectangle(orig.X, location.Y, s.Width, s.Height);
            return rect;
        }
    }
}
5
Заблокирован
14.08.2014, 05:13 3
Тоесть пока тяну мышкой прямоугольниг моргает
Потому что pictureBox.CreateGraphics() - это как бы не та картинка, которая Image и лежит в picturebox, а другая. Перед тем, как начинаете на ней рисовать, в ней оказывается тот же рисунок, что и на той картинке, но когда пытаетесь на этой что-то нарисовать, начинает рисоваться Image.
Ну как-то так...

Надо рисовать именно на Image. А для этого
C#
1
2
3
4
using (Graphics g1 = Graphics.FromImage(pictureBox.Image))
{
    ...
}
Подробнее про графику тут читайте: https://www.cyberforum.ru/cpp-... ost6471063
Это C++/CLI, но объектная модель, свойства и методы и в C# почти что те же.
1
0 / 0 / 1
Регистрация: 09.11.2013
Сообщений: 72
14.08.2014, 06:04  [ТС] 4
Гранд мерси!!!! Это я рисовал черт знает из какого события.
сделал как в примере через событие Paint и e.graphics и нет проблем =))

0
0 / 0 / 1
Регистрация: 13.06.2014
Сообщений: 29
13.06.2016, 22:49 5
Помогите, пожалуйста! Тоже столкнулся с подобной задачей - код, приведенный выше, прекрасно подходит для выделения. Но мне дальше нужно в выделенной области подредактировать цвета.Я написал небольшой кусочек кода, который работает по всей картинке так, как мне нужно:
C#
1
2
3
4
5
6
7
8
9
for(int i=0; i<image.Height; i++)
                for (int j=0; j<image.Width; j++)
                {
                    Color pixelColor = image.GetPixel(j,i);
                    Color color = Color.FromArgb(40, pixelColor.G, pixelColor.B);
                    if (pixelColor.R > 100 && pixelColor.G < 100 && pixelColor.B < 100)
                        image.SetPixel(j, i, color);
                }
            pictureBox1.Image = image;
Как применить это к выделенной области, к тому Rectangle, что рисуется мышкой? Или как получить его координаты, чтобы по ним запустить циклы? Никак не соображу, помогите, пожалуйста)

Добавлено через 1 час 6 минут
ViterAlex, можете подсказать решение?
0
0 / 0 / 1
Регистрация: 13.06.2014
Сообщений: 29
10.10.2016, 19:29 6
Здравствуйте, помогите пожалуйста! Приведенный выше код очень помог, но мне нужно чтобы при новом выделении старый прямоугольник не исчезал, чтобы происходило наложение. Не получается это реализовать, можете помочь?
C#
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
using System;
using System.Drawing;
using System.Windows.Forms;
 
namespace WindowsFormsApplication1 {
    public partial class Form1 : Form {
        Rectangle selRect;
        Point orig;
        Pen pen = new Pen(Brushes.Blue, 0.8f) { DashStyle = System.Drawing.Drawing2D.DashStyle.Dash };
        public Form1() {
            InitializeComponent();
            pictureBox1.Paint += pictureBox1_Paint;
            pictureBox1.MouseMove += pictureBox1_MouseMove;
            pictureBox1.MouseUp += pictureBox1_MouseUp;
            pictureBox1.MouseDown += pictureBox1_MouseDown;
        }
 
        void pictureBox1_MouseUp(object sender, MouseEventArgs e) {
            //Возвращаем основную процедуру рисования
            pictureBox1.Paint -= Selection_Paint;
            pictureBox1.Paint += pictureBox1_Paint;
            pictureBox1.Invalidate();
        }
 
        void pictureBox1_MouseDown(object sender, MouseEventArgs e) {
            //Назначаем процедуру рисования при выделении
            pictureBox1.Paint -= pictureBox1_Paint;
            pictureBox1.Paint += Selection_Paint;
            orig = e.Location;
        }
 
        //Рисование мышкой с нажатой кнопкой
        private void Selection_Paint(object sender, PaintEventArgs e) {
            e.Graphics.DrawRectangle(pen, selRect);
        }
 
        void pictureBox1_MouseMove(object sender, MouseEventArgs e) {
            //при движении мышкой считаем прямоугольник и обновляем picturebox
            selRect = GetSelRectangle(orig, e.Location);
            if (e.Button == System.Windows.Forms.MouseButtons.Left)
                (sender as PictureBox).Refresh();
        }
 
        //основное событие рисования
        void pictureBox1_Paint(object sender, PaintEventArgs e) {
            e.Graphics.DrawRectangle(Pens.Black, selRect);
        }
 
        Rectangle GetSelRectangle(Point orig, Point location) {
            int deltaX = location.X - orig.X, deltaY = location.Y - orig.Y;
            Size s = new Size(Math.Abs(deltaX), Math.Abs(deltaY));
            Rectangle rect = new Rectangle();
            if (deltaX >= 0 & deltaY >= 0)
                rect = new Rectangle(orig, s);
            if (deltaX < 0 & deltaY > 0)
                rect = new Rectangle(location.X, orig.Y, s.Width, s.Height);
            if (deltaX < 0 & deltaY < 0)
                rect = new Rectangle(location, s);
            if (deltaX > 0 & deltaY < 0)
                rect = new Rectangle(orig.X, location.Y, s.Width, s.Height);
            return rect;
        }
    }
}
Добавлено через 25 минут
ViterAlex, можете помочь?
0
10.10.2016, 19:29
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
10.10.2016, 19:29
Помогаю со студенческими работами здесь

Выделение прямоугольной области в datagridview
Доброго времени суток. У объекта datagridview есть метод SelectAll котроый выделяет все ячейки в...

Рисование на PictureBox мышкой
Товарищи программисты такая задача для умных.рисование на PictureBox с помощью мышки... То есть...

Перемещение компонента PictureBox мышкой
Всем привет! Собственно сама задача, это при зажатой левой кнопке мыши перемешать PictureBox...

Перемещение мышкой PictureBox'а по форме
Подскажите как мне сделать,чтобы в процессе компиляции я мог при нажатии на Pickturebox перемещать...


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

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru