From ec353dbddad4a1b78de19299de9e609e41b148d5 Mon Sep 17 00:00:00 2001 From: Gregory Morse Date: Thu, 18 Jan 2018 05:49:47 +0100 Subject: [PATCH] Merge pull request #10412 from GregoryMorse:patch-2 Update to add window position and size retrieval to HighGUI (#10412) * Update highgui.hpp Add read only property retrieval for enhanced rendering capabilities and more sophisticated research tools * Update window.cpp * Update window_w32.cpp * Update window_QT.cpp * Update window_QT.h * Update window_QT.h * Update window_gtk.cpp * Update precomp.hpp * Update highgui_c.h * Update highgui_c.h * Update window_w32.cpp * Update precomp.hpp * Update window_QT.cpp * Update window_QT.h * Update window_gtk.cpp * Update window_gtk.cpp * Update window_w32.cpp * Update window_QT.cpp * Update window_carbon.cpp * Update window_cocoa.mm * Update precomp.hpp * Update window_cocoa.mm * Update window_w32.cpp * Update window_gtk.cpp * Update window_QT.cpp * Update window_gtk.cpp * Update window_QT.cpp * Update window_cocoa.mm * Update window_carbon.cpp * Update window_w32.cpp * Update window_cocoa.mm * Update window_gtk.cpp * Update window_cocoa.mm * Update window_gtk.cpp * Update window_cocoa.mm * Update window_cocoa.mm * Update window.cpp * Update test_gui.cpp * Update test_gui.cpp * Update test_gui.cpp * Update highgui_c.h * Update highgui.hpp * Update window.cpp * Update highgui_c.h * Update test_gui.cpp * Update highgui.hpp * Update window.cpp * Update window.cpp * Update window.cpp * Update window.cpp * Update window.cpp --- modules/highgui/include/opencv2/highgui.hpp | 10 ++++ .../include/opencv2/highgui/highgui_c.h | 3 + modules/highgui/src/precomp.hpp | 6 ++ modules/highgui/src/window.cpp | 27 ++++++++- modules/highgui/src/window_QT.cpp | 31 +++++++++- modules/highgui/src/window_QT.h | 3 +- modules/highgui/src/window_carbon.cpp | 37 ++++++++++++ modules/highgui/src/window_cocoa.mm | 32 ++++++++++ modules/highgui/src/window_gtk.cpp | 59 +++++++++++++++++++ modules/highgui/src/window_w32.cpp | 27 +++++++++ modules/highgui/test/test_gui.cpp | 3 + 11 files changed, 235 insertions(+), 3 deletions(-) diff --git a/modules/highgui/include/opencv2/highgui.hpp b/modules/highgui/include/opencv2/highgui.hpp index e8aff6d0e1..0394c7d70d 100644 --- a/modules/highgui/include/opencv2/highgui.hpp +++ b/modules/highgui/include/opencv2/highgui.hpp @@ -442,6 +442,16 @@ The function getWindowProperty returns properties of a window. */ CV_EXPORTS_W double getWindowProperty(const String& winname, int prop_id); +/** @brief Provides rectangle of image in the window. + +The function getWindowImageRect returns the client screen coordinates, width and height of the image rendering area. + +@param winname Name of the window. + +@sa resizeWindow moveWindow + */ +CV_EXPORTS_W Rect getWindowImageRect(const String& winname); + /** @brief Sets mouse handler for the specified window @param winname Name of the window. diff --git a/modules/highgui/include/opencv2/highgui/highgui_c.h b/modules/highgui/include/opencv2/highgui/highgui_c.h index d8323d0d93..1eb414a76c 100644 --- a/modules/highgui/include/opencv2/highgui/highgui_c.h +++ b/modules/highgui/include/opencv2/highgui/highgui_c.h @@ -135,6 +135,9 @@ CVAPI(int) cvNamedWindow( const char* name, int flags CV_DEFAULT(CV_WINDOW_AUTOS CVAPI(void) cvSetWindowProperty(const char* name, int prop_id, double prop_value); CVAPI(double) cvGetWindowProperty(const char* name, int prop_id); +/* Get window image rectangle coordinates, width and height */ +CVAPI(cv::Rect)cvGetWindowImageRect(const char* name); + /* display image within window (highgui windows remember their content) */ CVAPI(void) cvShowImage( const char* name, const CvArr* image ); diff --git a/modules/highgui/src/precomp.hpp b/modules/highgui/src/precomp.hpp index e6af8afbcf..1d72a5d7a2 100644 --- a/modules/highgui/src/precomp.hpp +++ b/modules/highgui/src/precomp.hpp @@ -94,6 +94,11 @@ void cvSetModeWindow_CARBON(const char* name, double prop_value); void cvSetModeWindow_COCOA(const char* name, double prop_value); void cvSetModeWindow_WinRT(const char* name, double prop_value); +CvRect cvGetWindowRect_W32(const char* name); +CvRect cvGetWindowRect_GTK(const char* name); +CvRect cvGetWindowRect_CARBON(const char* name); +CvRect cvGetWindowRect_COCOA(const char* name); + double cvGetModeWindow_W32(const char* name); double cvGetModeWindow_GTK(const char* name); double cvGetModeWindow_CARBON(const char* name); @@ -111,6 +116,7 @@ double cvGetOpenGlProp_GTK(const char* name); //for QT #if defined (HAVE_QT) +CvRect cvGetWindowRect_QT(const char* name); double cvGetModeWindow_QT(const char* name); void cvSetModeWindow_QT(const char* name, double prop_value); diff --git a/modules/highgui/src/window.cpp b/modules/highgui/src/window.cpp index 2982a632d6..251d1d31da 100644 --- a/modules/highgui/src/window.cpp +++ b/modules/highgui/src/window.cpp @@ -160,12 +160,37 @@ CV_IMPL double cvGetWindowProperty(const char* name, int prop_id) return -1; #endif break; - default: return -1; } } +cv::Rect cvGetWindowImageRect(const char* name) +{ + if (!name) + return cv::Rect(-1, -1, -1, -1); + + #if defined (HAVE_QT) + return cvGetWindowRect_QT(name); + #elif defined(HAVE_WIN32UI) + return cvGetWindowRect_W32(name); + #elif defined (HAVE_GTK) + return cvGetWindowRect_GTK(name); + #elif defined (HAVE_CARBON) + return cvGetWindowRect_CARBON(name); + #elif defined (HAVE_COCOA) + return cvGetWindowRect_COCOA(name); + #else + return cv::Rect(-1, -1, -1, -1); + #endif +} + +cv::Rect cv::getWindowImageRect(const String& winname) +{ + CV_TRACE_FUNCTION(); + return cvGetWindowImageRect(winname.c_str()); +} + void cv::namedWindow( const String& winname, int flags ) { CV_TRACE_FUNCTION(); diff --git a/modules/highgui/src/window_QT.cpp b/modules/highgui/src/window_QT.cpp index 5e44de6511..c161a66a9b 100644 --- a/modules/highgui/src/window_QT.cpp +++ b/modules/highgui/src/window_QT.cpp @@ -166,7 +166,6 @@ void cvSetRatioWindow_QT(const char* name,double prop_value) Q_ARG(double, prop_value)); } - double cvGetPropWindow_QT(const char* name) { if (!guiMainThread) @@ -220,6 +219,21 @@ void cvSetModeWindow_QT(const char* name, double prop_value) Q_ARG(double, prop_value)); } +CvRect cvGetWindowRect_QT(const char* name) +{ + if (!guiMainThread) + CV_Error( CV_StsNullPtr, "NULL guiReceiver (please create a window)" ); + + CvRect result = cvRect(-1, -1, -1, -1); + + QMetaObject::invokeMethod(guiMainThread, + "getWindowRect", + autoBlockingConnection(), + Q_RETURN_ARG(CvRect, result), + Q_ARG(QString, QString(name))); + + return result; +} double cvGetModeWindow_QT(const char* name) { @@ -946,6 +960,21 @@ void GuiReceiver::setWindowTitle(QString name, QString title) w->setWindowTitle(title); } +CvRect GuiReceiver::getWindowRect(QString name) +{ + QPointer w = icvFindWindowByName(name); + + if (!w) + return cvRect(-1, -1, -1, -1); + + QPoint org = w->myView->mapToGlobal(new QPoint(0, 0)); +#ifdef HAVE_QT_OPENGL + if (isOpenGl()) { + return cvRect(w->myView->pos().x() + org.x, w->myView->pos().y() + org.y, w->myView->width(), w->myView->height()); + } else +#endif + return cvRect(w->myView->viewport()->pos().x() + org.x, w->myView->viewport()->pos().y() + org.y, w->myView->viewport()->width(), w->myView->viewport()->height()); +} double GuiReceiver::isFullScreen(QString name) { diff --git a/modules/highgui/src/window_QT.h b/modules/highgui/src/window_QT.h index 8be4bf4f48..d86321aad0 100644 --- a/modules/highgui/src/window_QT.h +++ b/modules/highgui/src/window_QT.h @@ -76,6 +76,7 @@ #include #include #include + #include #include #include @@ -98,7 +99,6 @@ enum { shortcut_zoom_normal = Qt::CTRL + Qt::Key_Z, shortcut_panning_up = Qt::CTRL + Qt::Key_Up, shortcut_panning_down = Qt::CTRL + Qt::Key_Down }; - //end enum class CvWindow; @@ -132,6 +132,7 @@ public slots: void displayStatusBar( QString name, QString text, int delayms ); void timeOut(); void toggleFullScreen(QString name, double flags ); + CvRect getWindowRect(QString name); double isFullScreen(QString name); double getPropWindow(QString name); void setPropWindow(QString name, double flags ); diff --git a/modules/highgui/src/window_carbon.cpp b/modules/highgui/src/window_carbon.cpp index 46c509cda2..9c90043303 100644 --- a/modules/highgui/src/window_carbon.cpp +++ b/modules/highgui/src/window_carbon.cpp @@ -718,6 +718,43 @@ CV_IMPL void cvSetTrackbarPos(const char* trackbar_name, const char* window_name return ; } +CvRect cvGetWindowRect_CARBON(const char* name) +{ + CvRect result = cvRect(-1, -1, -1, -1); + + CV_FUNCNAME( "cvGetWindowRect_QT" ); + + __BEGIN__; + + CvWindow* window; + + if(!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + + window = icvFindWindowByName( name ); + if( !window ) + CV_ERROR( CV_StsNullPtr, "NULL window" ); + + + Rect portrect; + GetWindowPortBounds(window->window, &portrect); + LocalToGlobal(&topLeft(portrect)); + LocalToGlobal(&botRight(portrect)); + if(!( window->flags & CV_WINDOW_AUTOSIZE) ) + { + result = cvRect(portrect.left, portrect.top, portrect.right-portrect.left, + portrect.bottom-portrect.top-window->trackbarheight); + } + else + { + result = cvRect(portrect.left, portrect.bottom - height - window->trackbarheight, + window->imageWidth, window->imageHeight); + } + + __END__; + return result; +} + CV_IMPL void* cvGetWindowHandle( const char* name ) { WindowRef result = 0; diff --git a/modules/highgui/src/window_cocoa.mm b/modules/highgui/src/window_cocoa.mm index a653cd355c..73959fd3d3 100644 --- a/modules/highgui/src/window_cocoa.mm +++ b/modules/highgui/src/window_cocoa.mm @@ -606,6 +606,38 @@ CV_IMPL int cvWaitKey (int maxWait) return returnCode; } +CvRect cvGetWindowRect_COCOA( const char* name ) +{ + CvRect result = cvRect(-1, -1, -1, -1); + CVWindow *window = nil; + + CV_FUNCNAME( "cvGetWindowRect_COCOA" ); + + __BEGIN__; + if( name == NULL ) + { + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + } + + window = cvGetWindow( name ); + if ( window == NULL ) + { + CV_ERROR( CV_StsNullPtr, "NULL window" ); + } else { + NSRect rect = [window frame]; +#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_6 + NSPoint pt = [window convertRectToScreen:rect].origin; +#else + NSPoint pt = [window convertBaseToScreen:rect.origin]; +#endif + NSSize sz = [[[window contentView] image] size]; + result = cvRect(pt.x, pt.y, sz.width, sz.height); + } + + __END__; + return result; +} + double cvGetModeWindow_COCOA( const char* name ) { double result = -1; diff --git a/modules/highgui/src/window_gtk.cpp b/modules/highgui/src/window_gtk.cpp index 94337d27e9..9d107fbd4f 100644 --- a/modules/highgui/src/window_gtk.cpp +++ b/modules/highgui/src/window_gtk.cpp @@ -705,6 +705,46 @@ static CvWindow* icvWindowByWidget( GtkWidget* widget ) return NULL; } +CvRect cvGetWindowRect_GTK(const char* name) +{ + CV_Assert(name && "NULL name string"); + + CV_LOCK_MUTEX(); + CvWindow* window = icvFindWindowByName(name); + if (!window) + CV_Error( CV_StsNullPtr, "NULL window" ); + + gint wx, wy; +#ifdef HAVE_OPENGL + if (window->useGl) { + gtk_widget_translate_coordinates(window->widget, gtk_widget_get_toplevel(window->widget), 0, 0, &wx, &wy); + return cvRect(wx, wy, window->widget->allocation.width, window->widget->allocation.height); + } +#endif + + CvImageWidget * image_widget = CV_IMAGE_WIDGET( window->widget ); + gtk_widget_translate_coordinates(&image_widget->widget, gtk_widget_get_toplevel(&image_widget->widget), 0, 0, &wx, &wy); + if (image_widget->scaled_image) { +#if defined (GTK_VERSION3) + return cvRect(wx, wy, MIN(image_widget->scaled_image->cols, gtk_widget_get_allocated_width(window->widget)), + MIN(image_widget->scaled_image->rows, gtk_widget_get_allocated_height(window->widget))); +#else + return cvRect(wx, wy, MIN(image_widget->scaled_image->cols, window->widget->allocation.width), + MIN(image_widget->scaled_image->rows, window->widget->allocation.height)); +#endif //GTK_VERSION3 + } else if (image_widget->original_image) { +#if defined (GTK_VERSION3) + return cvRect(wx, wy, MIN(image_widget->original_image->cols, gtk_widget_get_allocated_width(window->widget)), + MIN(image_widget->original_image->rows, gtk_widget_get_allocated_height(window->widget))); +#else + return cvRect(wx, wy, MIN(image_widget->original_image->cols, window->widget->allocation.width), + MIN(image_widget->original_image->rows, window->widget->allocation.height)); +#endif //GTK_VERSION3 + } + + return cvRect(-1, -1, -1, -1); +} + double cvGetModeWindow_GTK(const char* name)//YV { CV_Assert(name && "NULL name string"); @@ -891,21 +931,40 @@ static gboolean cvImageWidget_draw(GtkWidget* widget, cairo_t *cr, gpointer data if( image_widget->scaled_image ){ // center image in available region +#if defined (GTK_VERSION3) int x0 = (gtk_widget_get_allocated_width(widget) - image_widget->scaled_image->cols)/2; int y0 = (gtk_widget_get_allocated_height(widget) - image_widget->scaled_image->rows)/2; +#else + int x0 = (widget->allocation.width - image_widget->scaled_image->cols)/2; + int y0 = (widget->allocation.height - image_widget->scaled_image->rows)/2; +#endif //GTK_VERSION3 +#if defined (GTK_VERSION3) pixbuf = gdk_pixbuf_new_from_data(image_widget->scaled_image->data.ptr, GDK_COLORSPACE_RGB, false, 8, MIN(image_widget->scaled_image->cols, gtk_widget_get_allocated_width(widget)), MIN(image_widget->scaled_image->rows, gtk_widget_get_allocated_height(widget)), image_widget->scaled_image->step, NULL, NULL); +#else + pixbuf = gdk_pixbuf_new_from_data(image_widget->scaled_image->data.ptr, GDK_COLORSPACE_RGB, false, + 8, MIN(image_widget->scaled_image->cols, widget->allocation.width), + MIN(image_widget->scaled_image->rows, widget->allocation.height), + image_widget->scaled_image->step, NULL, NULL); +#endif //GTK_VERSION3 gdk_cairo_set_source_pixbuf(cr, pixbuf, x0, y0); } else if( image_widget->original_image ){ +#if defined (GTK_VERSION3) pixbuf = gdk_pixbuf_new_from_data(image_widget->original_image->data.ptr, GDK_COLORSPACE_RGB, false, 8, MIN(image_widget->original_image->cols, gtk_widget_get_allocated_width(widget)), MIN(image_widget->original_image->rows, gtk_widget_get_allocated_height(widget)), image_widget->original_image->step, NULL, NULL); +#else + pixbuf = gdk_pixbuf_new_from_data(image_widget->original_image->data.ptr, GDK_COLORSPACE_RGB, false, + 8, MIN(image_widget->original_image->cols, widget->allocation.width), + MIN(image_widget->original_image->rows, widget->allocation.height), + image_widget->original_image->step, NULL, NULL); +#endif //GTK_VERSION3 gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0); } diff --git a/modules/highgui/src/window_w32.cpp b/modules/highgui/src/window_w32.cpp index 929f39a2ce..5df18b3c03 100644 --- a/modules/highgui/src/window_w32.cpp +++ b/modules/highgui/src/window_w32.cpp @@ -423,6 +423,33 @@ icvSaveWindowPos( const char* name, CvRect rect ) RegCloseKey(hkey); } +CvRect cvGetWindowRect_W32(const char* name) +{ + CvRect result = cvRect(-1, -1, -1, -1); + + CV_FUNCNAME( "cvGetWindowRect_W32" ); + + __BEGIN__; + + CvWindow* window; + + if (!name) + CV_ERROR( CV_StsNullPtr, "NULL name string" ); + window = icvFindWindowByName( name ); + if (!window) + EXIT; // keep silence here + + RECT rect; + GetClientRect(window->hwnd, &rect); + { + POINT pt = {rect.left, rect.top}; + ClientToScreen(window->hwnd, &pt); + result = cvRect(pt.x, pt.y, rect.right - rect.left, rect.bottom - rect.top); + } + __END__; + return result; +} + double cvGetModeWindow_W32(const char* name)//YV { double result = -1; diff --git a/modules/highgui/test/test_gui.cpp b/modules/highgui/test/test_gui.cpp index e53accfe71..8efd24e9d9 100644 --- a/modules/highgui/test/test_gui.cpp +++ b/modules/highgui/test/test_gui.cpp @@ -84,6 +84,9 @@ void CV_HighGuiOnlyGuiTest::run( int /*start_from */) waitKey(500); ts->printf(ts->LOG, "GUI 8\n"); + getWindowImageRect("Win"); + + ts->printf(ts->LOG, "GUI 9\n"); destroyAllWindows(); ts->set_failed_test_info(cvtest::TS::OK); }