Как я могу отобразить перекрестие курсора с координатами X-Y при наведении курсора на картинке? - PullRequest
0 голосов
/ 29 августа 2018

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

Мой код выглядит следующим образом:

private: System::Void button1_Click(System::Object^  sender, System::EventArgs^  e) {
        cv::VideoCapture cap;
        cap.open(0);

        if (!cap.isOpened()) {
            MessageBox::Show("Failed To Open WebCam");
            _getch();
            return;
        }

        ///query_maximum_resolution(cap, pictureBox1->Width, pictureBox1->Height);
        cap.set(CV_CAP_PROP_FRAME_WIDTH, pictureBox1->Width);
        cap.set(CV_CAP_PROP_FRAME_HEIGHT, pictureBox1->Height);

        Pen^ myPen = gcnew Pen(Brushes::Red);

        while (1)
        {
            cap.read(frame);

            pictureBox1->Image = mat2bmp.Mat2Bimap(frame);
            Graphics^ g = Graphics::FromImage(pictureBox1->Image);
            Point pos = this->PointToClient(System::Windows::Forms::Cursor::Position);
            g->DrawLine(myPen, pos.X, 0, pos.X, pictureBox1->Height);
            g->DrawLine(myPen, 0, pos.Y, pictureBox1->Width, pos.Y);
            pictureBox1->Refresh();
            delete g;
        }
    }

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

1 Ответ

0 голосов
/ 29 августа 2018

IO происходит в потоке пользовательского интерфейса, который является основным потоком рендеринга пользовательского интерфейса. Нажатие кнопки - это обработчик события, который будет добавлен в поток пользовательского интерфейса. Если в потоке пользовательского интерфейса выполняется цикл while, приложение будет зависать. Работа, выполняемая в потоке пользовательского интерфейса, должна быть небольшой или асинхронной.

Редактировать 1: только что обнаружил, что вы пометили winform как один из тегов. Если вы используете winforms, вы должны добавить обработчик события MouseHover к элементам управления вашего пользовательского интерфейса. Всякий раз, когда мышь достигает этой области, вызывается этот метод (https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.control.mousehover?view=netframework-4.7.2).. В этом методе просто напишите приведенный выше код без цикла while. Что-то вроде этого.

private: System::Void button1_MouseHover(System::Object^  sender, System::EventArgs^  e) {
    cv::VideoCapture cap;
    cap.open(0);

    if (!cap.isOpened()) {
        MessageBox::Show("Failed To Open WebCam");
        _getch();
        return;
    }

    ///query_maximum_resolution(cap, pictureBox1->Width, pictureBox1->Height);
    cap.set(CV_CAP_PROP_FRAME_WIDTH, pictureBox1->Width);
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, pictureBox1->Height);

    Pen^ myPen = gcnew Pen(Brushes::Red);

    cap.read(frame);

    pictureBox1->Image = mat2bmp.Mat2Bimap(frame);
    Graphics^ g = Graphics::FromImage(pictureBox1->Image);
    Point pos = this->PointToClient(System::Windows::Forms::Cursor::Position);
    g->DrawLine(myPen, pos.X, 0, pos.X, pictureBox1->Height);
    g->DrawLine(myPen, 0, pos.Y, pictureBox1->Width, pos.Y);
    pictureBox1->Refresh();
    delete g;
}

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

...