diff --git a/JKQtPlotterBuildAllExamples.pro b/JKQtPlotterBuildAllExamples.pro index fdf930ae26..f1352b5621 100644 --- a/JKQtPlotterBuildAllExamples.pro +++ b/JKQtPlotterBuildAllExamples.pro @@ -13,6 +13,7 @@ SUBDIRS += jkqtplotterlib \ jkqtplotter_simpletest_barchart \ jkqtplotter_simpletest \ jkqtplotter_simpletest_speed \ + jkqtplotter_simpletest_rgbimageplot_qt \ jkqtplot_test #jkqtplotter_simpletest_imageplot_nodatastore \ #jkqtplotter_simpletest_rgbimageplot_opencv \ @@ -72,3 +73,6 @@ jkqtplotter_simpletest_symbols_and_styles.depends = jkqtplotterlib jkqtplotter_simpletest_speed.subdir = test/jkqtplotter_simpletest_speed jkqtplotter_simpletest_speed.depends = jkqtplotterlib + +jkqtplotter_simpletest_rgbimageplot_qt.subdir = test/jkqtplotter_simpletest_rgbimageplot_qt +jkqtplotter_simpletest_rgbimageplot_qt.depends = jkqtplotterlib diff --git a/README.md b/README.md index 9560464b36..9e2298c80a 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int | Screenshot | Description | Notes | |:-------------:| ------------- | ------------- | +| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_qt_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/jkqtplotter_simpletest_rgbimageplot_qt) | [`QImage` as a Graph](https://github.com/jkriege2/JKQtPlotter/tree/master/test/jkqtplotter_simpletest_rgbimageplot_qt) | `JKQTPImage`
`QImage` drawn onto a plot with arbitrary scaling) | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_imageplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/jkqtplotter_simpletest_imageplot) | [Basic 1-channel Raw C Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/test/jkqtplotter_simpletest_imageplot) | `JKQTPColumnMathImage`
image data copied from C-style row-major array into a single column of the internal datastore
Describes several options of the image plotting classes (different ways of color coding, what to do with data above/below the limits etc.) | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_imageplot_modifier_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/jkqtplotter_simpletest_imageplot_modifier) | [Modifier-Feature of Image Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/test/jkqtplotter_simpletest_imageplot_modifier) | `JKQTPColumnMathImage`
image data copied from C-style row-major array into a single column of the internal datastore
Image is modified by a second image to display two data dimensions at the same time | | [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_imageplot_nodatastore_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/test/jkqtplotter_simpletest_imageplot_nodatastore) | [Basic 1-channel Raw C Image Plot
without the internal datastore](https://github.com/jkriege2/JKQtPlotter/tree/master/test/jkqtplotter_simpletest_imageplot_nodatastore) | `JKQTPMathImage`
image data in a C-style row-major array, not using internal datastore | diff --git a/lib/jkqtplotter/jkqtpimageelements.cpp b/lib/jkqtplotter/jkqtpimageelements.cpp index 8c9b04968b..7cb3d6e015 100644 --- a/lib/jkqtplotter/jkqtpimageelements.cpp +++ b/lib/jkqtplotter/jkqtpimageelements.cpp @@ -155,33 +155,52 @@ void JKQTPImageBase::plotImage(JKQTPEnhancedPainter& painter, QImage& image, dou JKQTPImage::JKQTPImage(JKQtBasePlotter *parent): - JKQTPImageBase(parent) + JKQTPImageBase(parent), image_owned(false) { this->image=nullptr; createImageActions(); } JKQTPImage::JKQTPImage(double x, double y, double width, double height, QImage* image, JKQtBasePlotter* parent): - JKQTPImageBase(x, y, width, height, parent) + JKQTPImageBase(x, y, width, height, parent), image_owned(false) { this->image=image; createImageActions(); } JKQTPImage::JKQTPImage(JKQtPlotter *parent): - JKQTPImageBase(parent) + JKQTPImageBase(parent), image_owned(false) { this->image=nullptr; createImageActions(); } JKQTPImage::JKQTPImage(double x, double y, double width, double height, QImage* image, JKQtPlotter* parent): - JKQTPImageBase(x, y, width, height, parent) + JKQTPImageBase(x, y, width, height, parent), image_owned(false) { this->image=image; createImageActions(); } +JKQTPImage::JKQTPImage(double x, double y, double width, double height, const QImage &image, JKQtBasePlotter *parent): + JKQTPImageBase(x, y, width, height, parent), image_owned(true) +{ + this->image=new QImage(image); + createImageActions(); +} + +JKQTPImage::JKQTPImage(double x, double y, double width, double height, const QImage &image, JKQtPlotter *parent): + JKQTPImageBase(x, y, width, height, parent), image_owned(true) +{ + this->image=new QImage(image); + createImageActions(); +} + +JKQTPImage::~JKQTPImage() +{ + clear_image(); +} + void JKQTPImage::draw(JKQTPEnhancedPainter& painter) { if (image) plotImage(painter, *image, x, y, width, height); @@ -192,6 +211,31 @@ void JKQTPImage::drawKeyMarker(JKQTPEnhancedPainter &painter, QRectF &rect) painter.drawImage(rect, QPixmap(":/JKQTPlotter/jkqtp_plot_image.png").toImage()); } +void JKQTPImage::set_image(const QImage &image) +{ + clear_image(); + this->image=new QImage(image); + image_owned=true; + createImageActions(); +} + +void JKQTPImage::set_image(QImage *image) +{ + clear_image(); + this->image=image; + image_owned=false; + createImageActions(); +} + +void JKQTPImage::clear_image() +{ + if (image_owned && image!=nullptr) { + delete image; + } + image=nullptr; + image_owned=false; +} + void JKQTPImage::createImageActions() { actSaveImage=new QAction(tr("Save JKQTPImage ..."), this); diff --git a/lib/jkqtplotter/jkqtpimageelements.h b/lib/jkqtplotter/jkqtpimageelements.h index c938ec45ab..464da4fee4 100644 --- a/lib/jkqtplotter/jkqtpimageelements.h +++ b/lib/jkqtplotter/jkqtpimageelements.h @@ -240,10 +240,16 @@ class LIB_EXPORT JKQTPImage: public JKQTPImageBase { JKQTPImage(JKQtBasePlotter* parent=nullptr); /** \brief class constructor */ JKQTPImage(JKQtPlotter* parent); - /** \brief class constructor */ + /** \brief class constructor, which points to an external image (not owned by this object!!!) */ JKQTPImage(double x, double y, double width, double height, QImage* image, JKQtBasePlotter* parent=nullptr); - /** \brief class constructor */ + /** \brief class constructor, which points to an external image (not owned by this object!!!) */ JKQTPImage(double x, double y, double width, double height, QImage* image, JKQtPlotter* parent); + /** \brief class constructor, which generates an internal image object, by copying \a image */ + JKQTPImage(double x, double y, double width, double height, const QImage& image, JKQtBasePlotter* parent=nullptr); + /** \brief class constructor, which generates an internal image object, by copying \a image */ + JKQTPImage(double x, double y, double width, double height, const QImage& image, JKQtPlotter* parent); + + virtual ~JKQTPImage(); /** \brief plots the graph to the plotter object specified as parent */ virtual void draw(JKQTPEnhancedPainter& painter); @@ -251,12 +257,21 @@ class LIB_EXPORT JKQTPImage: public JKQTPImageBase { /** \brief plots a key marker inside the specified rectangle \a rect */ virtual void drawKeyMarker(JKQTPEnhancedPainter& painter, QRectF& rect); + /** \brief copy an external image into an internally owned copy */ + virtual void set_image(const QImage& image); + /** \brief set an external image to be plotted, the image will NOT BE OWNED by the graph-object */ + virtual void set_image(QImage* image); - JKQTPGET_SET_MACRO(QImage*, image) + /** \brief deletes the internal image */ + void clear_image(); + + JKQTPGET_MACRO(QImage*, image) protected: - /** \brief the image to be plotted */ + /** \brief the image to be plotted. This is freed by the destructor, iff \a image_owned is set to \c true (.e.g by QImage-copy-constructors) */ QImage* image; + /** \brief indicates that the image \a image is owned by this object (i.e. freed, when the object is destroyed) */ + bool image_owned; void createImageActions(); diff --git a/screenshots/jkqtplotter_simpletest_rgbimageplot_qt.png b/screenshots/jkqtplotter_simpletest_rgbimageplot_qt.png new file mode 100644 index 0000000000..f633c21239 Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_rgbimageplot_qt.png differ diff --git a/screenshots/jkqtplotter_simpletest_rgbimageplot_qt_small.png b/screenshots/jkqtplotter_simpletest_rgbimageplot_qt_small.png new file mode 100644 index 0000000000..0dc79dfa7a Binary files /dev/null and b/screenshots/jkqtplotter_simpletest_rgbimageplot_qt_small.png differ diff --git a/test/jkqtplotter_simpletest_rgbimageplot_qt/README.md b/test/jkqtplotter_simpletest_rgbimageplot_qt/README.md new file mode 100644 index 0000000000..1f28976f27 --- /dev/null +++ b/test/jkqtplotter_simpletest_rgbimageplot_qt/README.md @@ -0,0 +1,35 @@ +[Back to JKQTPlotter main page](https://github.com/jkriege2/JKQtPlotter/) + +# JKQtPlotter + +## Simple RGB image plot, showing a 3-channel OpenCV cv::Mat +This project (see `./test/jkqtplotter_simpletest_rgbimageplot_qt/`) simply creates a JKQtPlotter widget (as a new window) and adds an image plot with an image taken from a QImage object. + +The source code of the main application is (see `./test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.cpp`). the main parts are: +```c++ + // 2. now we open a BMP-file and load it into an OpenCV cv::Mat + QImage image(":/example.bmp"); + + // 3. create a graph (JKQTPImage) with a pointer to the QImage-object, generated above + JKQTPImage* graph=new JKQTPImage(&plot); + graph->set_title(""); + // copy the image into the graph (optionally you could also give a pointer to a QImage, + // but then you need to ensure that the QImage is available as long as the JKQTPImage + // instace lives) + graph->set_image(image); + // where does the image start in the plot, given in plot-axis-coordinates (bottom-left corner) + graph->set_x(0); + graph->set_y(0); + // width/height of the image in plot coordinates + graph->set_width(image.width()); + graph->set_height(image.height()); + + // 4. add the graphs to the plot, so it is actually displayed + plot.addGraph(graph); +``` +The result looks like this: + +![jkqtplotter_simpletest_imageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_qt.png) + + +[Back to JKQTPlotter main page](https://github.com/jkriege2/JKQtPlotter/) diff --git a/test/jkqtplotter_simpletest_rgbimageplot_qt/example.bmp b/test/jkqtplotter_simpletest_rgbimageplot_qt/example.bmp new file mode 100644 index 0000000000..b4535acc52 Binary files /dev/null and b/test/jkqtplotter_simpletest_rgbimageplot_qt/example.bmp differ diff --git a/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.cpp b/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.cpp new file mode 100644 index 0000000000..e8800044ef --- /dev/null +++ b/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.cpp @@ -0,0 +1,65 @@ +#include +#include +#include "jkqtplotter/jkqtplotter.h" +#include "jkqtplotter/jkqtpimageelements.h" + + + +int main(int argc, char* argv[]) +{ + QApplication app(argc, argv); + + JKQtPlotter plot; + + + // 1. create a plotter window and get a pointer to the internal datastore (for convenience) + plot.get_plotter()->set_useAntiAliasingForGraphs(true); // nicer (but slower) plotting + plot.get_plotter()->set_useAntiAliasingForSystem(true); // nicer (but slower) plotting + plot.get_plotter()->set_useAntiAliasingForText(true); // nicer (but slower) text rendering + JKQTPdatastore* ds=plot.getDatastore(); + + + // 2. now we open a BMP-file and load it into an OpenCV cv::Mat + QImage image(":/example.bmp"); + + + + + // 3. create a graph (JKQTPImage) with a pointer to the QImage-object, generated above + JKQTPImage* graph=new JKQTPImage(&plot); + graph->set_title(""); + // copy the image into the graph (optionally you could also give a pointer to a QImage, + // but then you need to ensure that the QImage is available as long as the JKQTPImage + // instace lives) + graph->set_image(image); + // where does the image start in the plot, given in plot-axis-coordinates (bottom-left corner) + graph->set_x(0); + graph->set_y(0); + // width/height of the image in plot coordinates + graph->set_width(image.width()); + graph->set_height(image.height()); + + + + // 5. add the graphs to the plot, so it is actually displayed + plot.addGraph(graph); + + // 6. set axis labels + plot.get_xAxis()->set_axisLabel("x [pixels]"); + plot.get_yAxis()->set_axisLabel("y [pixels]"); + + // 7. fix axis aspect ratio to width/height, so pixels are square + plot.get_plotter()->set_maintainAspectRatio(true); + plot.get_plotter()->set_aspectRatio(double(image.width())/double(image.height())); + + // 8. autoscale the plot so the graph is contained + plot.zoomToFit(); + + // show plotter and make it a decent size + plot.show(); + plot.resize(800,600); + plot.setWindowTitle("JKQTPImage"); + + + return app.exec(); +} diff --git a/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.pro b/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.pro new file mode 100644 index 0000000000..352cc4d8b8 --- /dev/null +++ b/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.pro @@ -0,0 +1,23 @@ +# source code for this simple demo +SOURCES += jkqtplotter_simpletest_rgbimageplot_qt.cpp + +RESOURCES += jkqtplotter_simpletest_rgbimageplot_qt.qrc + + +# configure Qt +CONFIG += qt +QT += core gui xml svg +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport + +# output executable name +TARGET = jkqtplotter_simpletest_rgbimageplot_qt + +# include JKQtPlotter source code +DEPENDPATH += . ../../lib +INCLUDEPATH += ../../lib +CONFIG (debug, debug|release):LIBS += -L../../lib/debug -ljkqtplotterlib +CONFIG (release):LIBS += -L../../lib/release -ljkqtplotterlib + +# here you can activate some debug options +#DEFINES += SHOW_JKQTPLOTTER_DEBUG +#DEFINES += JKQTBP_AUTOTIMER diff --git a/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.qrc b/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.qrc new file mode 100644 index 0000000000..b9ddd376c1 --- /dev/null +++ b/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.qrc @@ -0,0 +1,5 @@ + + + example.bmp + + diff --git a/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt_and_lib.pro b/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt_and_lib.pro new file mode 100644 index 0000000000..9f56bb9f7e --- /dev/null +++ b/test/jkqtplotter_simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt_and_lib.pro @@ -0,0 +1,8 @@ +TEMPLATE = subdirs + +SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_rgbimageplot_qt + +jkqtplotterlib.file = ../../lib/jkqtplotterlib.pro + +jkqtplotter_simpletest_rgbimageplot_qt.file=$$PWD/jkqtplotter_simpletest_rgbimageplot_qt.pro +jkqtplotter_simpletest_rgbimageplot_qt.depends = jkqtplotterlib