Forráskód Böngészése

Add ctk::grabWidget, ctk::vtkImageDataToQImage and ctk::grabVTKWidget

Julien Finet 13 éve
szülő
commit
38a47bfefc

+ 2 - 0
Libs/Visualization/VTK/Widgets/CMakeLists.txt

@@ -42,6 +42,8 @@ SET(KIT_SRCS
   ctkVTKThresholdWidget.h
   ctkVTKThumbnailView.cpp
   ctkVTKThumbnailView.h
+  ctkVTKWidgetsUtils.cpp
+  ctkVTKWidgetsUtils.h
   )
 
 # Headers that should run through moc

+ 2 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/CMakeLists.txt

@@ -21,6 +21,7 @@ SET(TEST_SOURCES
   ctkVTKSurfaceMaterialPropertyWidgetTest1.cpp
   ctkVTKTextPropertyWidgetTest1.cpp
   ctkVTKThumbnailViewTest1.cpp
+  ctkVTKWidgetsUtilsTestGrabWidget.cpp
   )
 
 IF(CTK_USE_CHARTS)
@@ -114,6 +115,7 @@ SIMPLE_TEST( ctkVTKSliceViewTest1 )
 SIMPLE_TEST( ctkVTKSurfaceMaterialPropertyWidgetTest1 )
 SIMPLE_TEST( ctkVTKTextPropertyWidgetTest1 )
 SIMPLE_TEST( ctkVTKThumbnailViewTest1 )
+SIMPLE_TEST( ctkVTKWidgetsUtilsTestGrabWidget )
 
 #
 # Add Tests expecting CTKData to be set

+ 74 - 0
Libs/Visualization/VTK/Widgets/Testing/Cpp/ctkVTKWidgetsUtilsTestGrabWidget.cpp

@@ -0,0 +1,74 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  =========================================================================*/
+
+// QT includes
+#include <QApplication>
+#include <QDialog>
+#include <QFrame>
+#include <QTimer>
+#include <QVBoxLayout>
+
+// CTK includes
+#include "ctkVTKRenderView.h"
+#include "ctkVTKWidgetsUtils.h"
+#include "ctkWidgetsUtils.h"
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkVTKWidgetsUtilsTestGrabWidget(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  QFrame parentWidget;
+  parentWidget.setFrameStyle(QFrame::Panel | QFrame::Raised);
+  parentWidget.setLineWidth(2);
+
+  ctkVTKRenderView vtkWidget(&parentWidget);
+  QVBoxLayout* layout = new QVBoxLayout(&parentWidget);
+  layout->addWidget(&vtkWidget);
+  parentWidget.setLayout(layout);
+
+  parentWidget.resize(200, 200);
+  parentWidget.show();
+  // Add a dialog to cover vtkWidget to test if grabWidget works even when the
+  // opengl view is covered.
+  QDialog dialog(0);
+  dialog.move(parentWidget.pos());
+  dialog.show();
+
+  QImage screenshot =
+    ctk::grabVTKWidget(&parentWidget);
+
+  if (QColor(screenshot.pixel(100, 100)) != QColor(Qt::black))
+    {
+    std::cout << "Failed to grab QVTKWidget, pixel at (100,100)="
+              << screenshot.pixel(100, 100) << " " << QColor(Qt::black).rgb() << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  if (argc < 2 && QString(argv[1]) != "-I")
+    {
+    QTimer::singleShot(100, &app, SLOT(quit()));
+    }
+  return app.exec();
+}

+ 85 - 0
Libs/Visualization/VTK/Widgets/ctkVTKWidgetsUtils.cpp

@@ -0,0 +1,85 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+// Qt includes
+#include <QImage>
+#include <QPainter>
+#include <QWidget>
+
+// ctkWidgets includes
+#include "ctkVTKWidgetsUtils.h"
+#include "ctkWidgetsUtils.h"
+
+// VTK includes
+#include <QVTKWidget.h>
+#include <vtkImageData.h>
+
+//----------------------------------------------------------------------------
+QImage ctk::grabVTKWidget(QWidget* widget, QRect rectangle)
+{
+  if (!widget)
+    {
+    return QImage();
+    }
+  if (!rectangle.isValid())
+    {
+    rectangle = QRect(0,0,widget->width(),widget->height());
+    }
+  QImage widgetImage = ctk::grabWidget(widget, rectangle);
+  QPainter painter;
+  painter.begin(&widgetImage);
+  foreach(QVTKWidget* vtkWidget, widget->findChildren<QVTKWidget*>())
+    {
+    QRect subWidgetRect = QRect(vtkWidget->mapTo(widget, QPoint(0,0)), vtkWidget->size());
+    if (!rectangle.intersects(subWidgetRect))
+      {
+      continue;
+      }
+    vtkImageData* imageData = vtkWidget->cachedImage();
+    /// \todo retrieve just the rectangle.intersected(
+    QImage subImage = ctk::vtkImageDataToQImage(imageData);
+    painter.drawImage(subWidgetRect, subImage);
+    }
+  painter.end();
+  return widgetImage;
+}
+
+//----------------------------------------------------------------------------
+QImage ctk::vtkImageDataToQImage(vtkImageData* imageData)
+{
+  if (!imageData)
+    {
+    return QImage();
+    }
+  imageData->Update();
+  /// \todo retrieve just the UpdateExtent
+  int width = imageData->GetDimensions()[0];
+  int height = imageData->GetDimensions()[1];
+  QImage image(width, height, QImage::Format_RGB32);
+  QRgb* rgbPtr = reinterpret_cast<QRgb*>(image.bits());
+  unsigned char* colorsPtr = reinterpret_cast<unsigned char*>(
+    imageData->GetScalarPointer());
+  for(int i = 0; i < width * height; ++i)
+    {
+    *(rgbPtr++) = QColor(colorsPtr[0], colorsPtr[1], colorsPtr[2]).rgb();
+    colorsPtr +=  3;
+    }
+  return image;
+}

+ 51 - 0
Libs/Visualization/VTK/Widgets/ctkVTKWidgetsUtils.h

@@ -0,0 +1,51 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+=========================================================================*/
+
+#ifndef __ctkVTKWidgetsUtils_h
+#define __ctkVTKWidgetsUtils_h
+
+// Qt includes
+#include <QRect>
+class QImage;
+class QWidget;
+
+// CTKVTKWidgets includes
+#include "ctkVisualizationVTKWidgetsExport.h"
+
+// VTK includes
+class vtkImageData;
+
+namespace ctk {
+
+///
+/// \ingroup VTKWidgets
+/// Grab the contents of a QWidget and all its children.
+/// Handle correctly the case of QVTKWidget.
+/// \sa ctk::grabWidget QWidget::grabWidget
+QImage CTK_VISUALIZATION_VTK_WIDGETS_EXPORT grabVTKWidget(QWidget* widget, QRect rectangle = QRect());
+
+///
+/// \ingroup VTKWidgets
+/// Convert a vtkImageData into a QImage
+QImage CTK_VISUALIZATION_VTK_WIDGETS_EXPORT vtkImageDataToQImage(vtkImageData* imageData);
+
+}
+
+#endif

+ 2 - 0
Libs/Widgets/Testing/Cpp/CMakeLists.txt

@@ -67,6 +67,7 @@ SET(TEST_SOURCES
   ctkToolTipTrapperTest1.cpp
   ctkTreeComboBoxTest1.cpp
   ctkWidgetsUtilsTest1.cpp
+  ctkWidgetsUtilsTestGrabWidget.cpp
   ctkWorkflowWidgetTest1.cpp
   ctkWorkflowWidgetTest2.cpp
   ctkExampleUseOfWorkflowWidgetUsingDerivedSteps.cpp
@@ -194,6 +195,7 @@ SIMPLE_TEST( ctkThumbnailWidgetTest1 )
 SIMPLE_TEST( ctkToolTipTrapperTest1 )
 SIMPLE_TEST( ctkTreeComboBoxTest1 )
 SIMPLE_TEST( ctkWidgetsUtilsTest1 )
+SIMPLE_TEST( ctkWidgetsUtilsTestGrabWidget )
 SIMPLE_TEST( ctkWorkflowWidgetTest1 )
 SIMPLE_TEST( ctkWorkflowWidgetTest2 )
 

+ 73 - 0
Libs/Widgets/Testing/Cpp/ctkWidgetsUtilsTestGrabWidget.cpp

@@ -0,0 +1,73 @@
+/*=========================================================================
+
+  Library:   CTK
+
+  Copyright (c) Kitware Inc.
+
+  Licensed under the Apache License, Version 2.0 (the "License");
+  you may not use this file except in compliance with the License.
+  You may obtain a copy of the License at
+
+  http://www.apache.org/licenses/LICENSE-2.0.txt
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+
+  =========================================================================*/
+
+// QT includes
+#include <QApplication>
+#include <QDialog>
+#include <QFrame>
+#include <QGLWidget>
+#include <QTimer>
+#include <QVBoxLayout>
+
+// CTK includes
+#include "ctkWidgetsUtils.h"
+
+// STD includes
+#include <cstdlib>
+#include <iostream>
+
+//-----------------------------------------------------------------------------
+int ctkWidgetsUtilsTestGrabWidget(int argc, char * argv [] )
+{
+  QApplication app(argc, argv);
+
+  QFrame parentWidget;
+  parentWidget.setFrameStyle(QFrame::Panel | QFrame::Raised);
+  parentWidget.setLineWidth(2);
+
+  QGLWidget glWidget(&parentWidget);
+  QVBoxLayout* layout = new QVBoxLayout(&parentWidget);
+  layout->addWidget(&glWidget);
+  parentWidget.setLayout(layout);
+
+  parentWidget.resize(200, 200);
+  parentWidget.show();
+  // Add a dialog to cover vtkWidget to test if grabWidget works even when the
+  // opengl view is covered.
+  QDialog dialog(0);
+  dialog.move(parentWidget.pos());
+  dialog.show();
+
+  QImage screenshot =
+    ctk::grabWidget(&parentWidget);
+
+  if (QColor(screenshot.pixel(100, 100)) != QColor(Qt::black))
+    {
+    std::cout << "Failed to grab QGLWidget, pixel at (100,100)="
+              << screenshot.pixel(100, 100) << " " << QColor(Qt::black).rgb() << std::endl;
+    return EXIT_FAILURE;
+    }
+
+  if (argc < 2 && QString(argv[1]) != "-I")
+    {
+    QTimer::singleShot(100, &app, SLOT(quit()));
+    }
+  return app.exec();
+}

+ 32 - 0
Libs/Widgets/ctkWidgetsUtils.cpp

@@ -21,6 +21,9 @@
 // Qt includes
 #include <QBuffer>
 #include <QImage>
+#include <QGLWidget>
+#include <QPainter>
+#include <QWidget>
 
 // ctkWidgets includes
 #include "ctkWidgetsUtils.h"
@@ -37,6 +40,35 @@ QString ctk::base64HTMLImageTagSrc(const QImage& image)
 }
 
 //----------------------------------------------------------------------------
+QImage ctk::grabWidget(QWidget* widget, QRect rectangle)
+{
+  if (!widget)
+    {
+    return QImage();
+    }
+  if (!rectangle.isValid())
+    {
+    rectangle = QRect(0,0,widget->width(),widget->height());
+    }
+  QPixmap widgetPixmap = QPixmap::grabWidget(widget, rectangle);
+  QImage widgetImage = widgetPixmap.toImage();
+  QPainter painter;
+  painter.begin(&widgetImage);
+  foreach(QGLWidget* glWidget, widget->findChildren<QGLWidget*>())
+    {
+    QRect subWidgetRect = QRect(glWidget->mapTo(widget, QPoint(0,0)), glWidget->size());
+    if (!rectangle.intersects(subWidgetRect))
+      {
+      continue;
+      }
+    QImage subImage = glWidget->grabFrameBuffer();
+    painter.drawImage(subWidgetRect, subImage);
+    }
+  painter.end();
+  return widgetImage;
+}
+
+//----------------------------------------------------------------------------
 QImage ctk::kwIconToQImage(const unsigned char *data, int width, int height, int pixelSize, unsigned int bufferLength, int options)
 {
   Q_UNUSED(options); // not yet supported

+ 7 - 0
Libs/Widgets/ctkWidgetsUtils.h

@@ -36,6 +36,13 @@ QString CTK_WIDGETS_EXPORT base64HTMLImageTagSrc(const QImage& image);
 
 ///
 /// \ingroup Widgets
+/// Grab the contents of a QWidget and all its children.
+/// Handle correctly the case of QGLWidgets.
+/// \sa QWidget::grabWidget
+QImage CTK_WIDGETS_EXPORT grabWidget(QWidget* widget, QRect rectangle = QRect());
+
+///
+/// \ingroup Widgets
 /// Convert an KWidget encoded image into a QImage
 /// The data can be base64 encoded and/or zlib compressed.
 QImage CTK_WIDGETS_EXPORT kwIconToQImage(const unsigned char *data, int width, int height, int pixelSize, unsigned int bufferLength, int options = 0);