diff --git a/.gitignore b/.gitignore
index 2cec06d9ac..fdf9c0376a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -92,3 +92,4 @@ moc_predefs.h
/doc/*.tmp
*.prl
Sicherungskopie_*
+/examples/simpletest_rgbimageplot_opencv/opencv
diff --git a/JKQtPlotterBuildAllExamples.pro b/JKQtPlotterBuildAllExamples.pro
index b711d68ce5..fa171c1678 100644
--- a/JKQtPlotterBuildAllExamples.pro
+++ b/JKQtPlotterBuildAllExamples.pro
@@ -64,6 +64,7 @@ addSimpleTest(symbols_and_errors)
addSimpleTest(symbols_and_styles)
addSimpleTest(filledgraphs)
addSimpleTest(speed)
+addSimpleTest(rgbimageplot)
addSimpleTest(rgbimageplot_qt)
addSimpleTest(impulsesplot)
addSimpleTest(paramscatterplot)
diff --git a/doc/dox/examples_and_tutorials.dox b/doc/dox/examples_and_tutorials.dox
index c68564d498..e5e2e59d65 100644
--- a/doc/dox/examples_and_tutorials.dox
+++ b/doc/dox/examples_and_tutorials.dox
@@ -85,7 +85,7 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
Screenshot
Description
Notes
\image html jkqtplotter_simpletest_rgbimageplot_qt_small.png
\subpage JKQTPlotterImagePlotQImageRGB
-
`JKQTPImage` `QImage` drawn onto a plot with arbitrary scaling)
+
`JKQTPImage` `QImage` drawn onto a plot with arbitrary scaling inverted coordinate axes
\image html jkqtplotter_simpletest_imageplot_small.png
\subpage JKQTPlotterImagePlot
`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.)
@@ -95,12 +95,15 @@ All test-projects are Qt-projects that use qmake to build. You can load them int
\image html jkqtplotter_simpletest_imageplot_nodatastore_small.png
\subpage JKQTPlotterImagePlotNoDatastore
`JKQTPMathImage` image data in a C-style row-major array, not using internal datastore
+
\image html jkqtplotter_simpletest_rgbimageplot_small.png
+
\subpage JKQTPlotterRGBImagePlot
+
`JKQTPColumnRGBMathImage` image data in a C-style row-major array, not using internal datastore RGB/CMY color compositing
\image html jkqtplotter_simpletest_imageplot_opencv_small.png
\subpage JKQTPlotterImagePlotOpenCV
`JKQTPColumnMathImage` image data copied from OpenCV cv::Mat-structure into a single column of the internal datastore
\image html jkqtplotter_simpletest_rgbimageplot_opencv_small.png
\subpage JKQTPlotterImagePlotRGBOpenCV
-
`JKQTPColumnRGBMathImage` image data copied from OpenCV cv::Mat-structure into three columns of the internal datastore
+
`JKQTPColumnRGBMathImage` image data copied from OpenCV cv::Mat-structure into three columns of the internal datastore inverted coordinate axes
diff --git a/doc/dox/whatsnew.dox b/doc/dox/whatsnew.dox
index cd8a6a7dd1..5834c6c14a 100644
--- a/doc/dox/whatsnew.dox
+++ b/doc/dox/whatsnew.dox
@@ -38,6 +38,7 @@ Changes, compared to \ref WHATSNEW_V2018_08 "v2018.08" include:
new: frames (plot viewport, key/legend ...) may be rounded off at the corners
new: diverse new styling options (default font name/size ...)
new: additionl options for styling coordinate axes
+
fixed: RGB-image plots now work properly with inverted axes (image is inverted, befor image was not shown at all)
Updates to JKQTMathText:
diff --git a/doc/images/jkqtplotter_inverted_yaxis.png b/doc/images/jkqtplotter_inverted_yaxis.png
new file mode 100644
index 0000000000..c1687bea52
Binary files /dev/null and b/doc/images/jkqtplotter_inverted_yaxis.png differ
diff --git a/examples/README.md b/examples/README.md
index 656abb5c55..c825dd6757 100644
--- a/examples/README.md
+++ b/examples/README.md
@@ -37,12 +37,13 @@ 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/examples/simpletest_rgbimageplot_qt) | [`QImage` as a Graph](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_qt) | `JKQTPImage` `QImage` drawn onto a plot with arbitrary scaling) |
+| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_qt_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_qt) | [`QImage` as a Graph](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_qt) | `JKQTPImage` `QImage` drawn onto a plot with arbitrary scaling inverted coordinate axes |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_imageplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot) | [Basic 1-channel Raw C Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/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/examples/simpletest_imageplot_modifier) | [Modifier-Feature of Image Plots](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/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/examples/simpletest_imageplot_nodatastore) | [Basic 1-channel Raw C Image Plot without the internal datastore](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_nodatastore) | `JKQTPMathImage` image data in a C-style row-major array, not using internal datastore |
+| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtplotter_simpletest_rgbimageplot) | [Simple 3-channel Math RGB/CMY Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/jkqtplotter_simpletest_rgbimageplot) | `JKQTPColumnRGBMathImage` image data in a C-style row-major array, not using internal datastore RGB/CMY color compositing |
| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_imageplot_opencv_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_opencv) | [1-channel OpenCV cv::Mat Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_opencv) | `JKQTPColumnMathImage` image data copied from OpenCV cv::Mat-structure into a single column of the internal datastore |
-| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_opencv_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_opencv) | [RGB OpenCV cv::Mat Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_opencv) | `JKQTPColumnRGBMathImage` image data copied from OpenCV cv::Mat-structure into three columns of the internal datastore |
+| [![](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_opencv_small.png)](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_opencv) | [RGB OpenCV cv::Mat Image Plot](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_rgbimageplot_opencv) | `JKQTPColumnRGBMathImage` image data copied from OpenCV cv::Mat-structure into three columns inverted coordinate axesof the internal datastore |
diff --git a/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.cpp b/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.cpp
index cf7a498e3e..aa568173c2 100644
--- a/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.cpp
+++ b/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.cpp
@@ -10,7 +10,7 @@
#include "jkqtplotter/jkqtpgraphs.h"
#include "jkqtplotter/jkqtpgraphsimage.h"
#include "jkqtplotter/jkqtpopencvinterface.h"
-#include
+#include
#ifndef M_PI
#define M_PI 3.14159265358979323846
diff --git a/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.pro b/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.pro
index 7a3c0da9b2..e3031fbf7e 100644
--- a/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.pro
+++ b/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.pro
@@ -9,23 +9,26 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
# output executable name
TARGET = jkqtplotter_simpletest_imageplot_opencv
-# add OpenCV-interface to JKQTPDatastore
-DEFINES += JKQTPLOTTER_OPENCV_INTERFACE
-
-
-
-
-
-
-
# link agains OpenCV-3.4.1
-INCLUDEPATH += $$PWD/OpenCV-3.4.1/include/
-LIBS += -L$$PWD/OpenCV-3.4.1/bin/ -llibopencv_core341
+#INCLUDEPATH += $$PWD/../../../OpenCV-3.4.1/include/
+#LIBS += -L$$PWD/../../../OpenCV-3.4.1/bin/ -llibopencv_core341 -llibopencv_imgcodecs341
+#opencvdlls.files=$$PWD/../../../OpenCV-3.4.1/bin/*.dll
+#opencvdlls.path=$$OUT_PWD
+
+# link agains OpenCV-4
+INCLUDEPATH += $$PWD/../../../OpenCV-4.0.1/include/
+LIBS += -L$$PWD/../../../OpenCV-4.0.1/x64/mingw/bin -L$$PWD/../../../OpenCV-4.0.1/x64/mingw/lib -llibopencv_core400.dll -llibopencv_imgcodecs400.dll
+opencvdlls.files=$$PWD/../../../OpenCV-4.0.1/x64/mingw/bin/*.dll
+opencvdlls.path=$$OUT_PWD
+
+INCLUDEPATH+=../../lib
CONFIG (debug, debug|release) {
LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
} else {
LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
}
-message("LIBS = $$LIBS")
\ No newline at end of file
+message("LIBS = $$LIBS")
+
+INSTALLS += opencvdlls
diff --git a/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv_and_lib.pro b/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv_and_lib.pro
new file mode 100644
index 0000000000..6ae6b5ad73
--- /dev/null
+++ b/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv_and_lib.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+
+SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_imageplot_opencv
+
+jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
+
+jkqtplotter_simpletest_imageplot_opencv.file=$$PWD/jkqtplotter_simpletest_imageplot_opencv.pro
+jkqtplotter_simpletest_imageplot_opencv.depends = jkqtplotterlib
diff --git a/examples/simpletest_rgbimageplot/README.md b/examples/simpletest_rgbimageplot/README.md
new file mode 100644
index 0000000000..8c3ef78e26
--- /dev/null
+++ b/examples/simpletest_rgbimageplot/README.md
@@ -0,0 +1,129 @@
+# Example (JKQTPlotter): Simple Math RGB/CMY Image Plot {#JKQTPlotterRGBImagePlot}
+This project (see `./examples/simpletest_imageplot/`) simply creates a JKQTPlotter widget (as a new window) and adds an image plot of a mathematical function (here the Airy disk). The function is calculated with different parameters and then the result for each parameter is mapped onto a separate color channel in the output. The image is stored as a simple C-array in row-major ordering and then copied into a single column of the internal datasdtore (JKQTPMathImage could be directly used without the internal datastore). This very simple interface can also be used to interface with many common image processing libraries, like CImg or OpenCV.
+
+The source code of the main application is (see [`jkqtplotter_simpletest_rgbimageplot.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot/jkqtplotter_simpletest_rgbimageplot.cpp):
+```.cpp
+#include
+#include
+#include "jkqtplotter/jkqtplotter.h"
+#include "jkqtplotter/jkqtpgraphsimagergb.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+
+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.getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
+ plot.getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
+ plot.getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
+ JKQTPDatastore* ds=plot.getDatastore();
+
+ // 2. now we create data for the charts (taken from https://commons.wikimedia.org/wiki/File:Energiemix_Deutschland.svg)
+ const int NX=100; // image dimension in x-direction [pixels]
+ const int NY=100; // image dimension in x-direction [pixels]
+ const double dx=1e-2; // size of a pixel in x-direction [micrometers]
+ const double dy=1e-2; // size of a pixel in x-direction [micrometers]
+ const double w=static_cast(NX)*dx;
+ const double h=static_cast(NY)*dy;
+ double airydisk1[NX*NY]; // row-major image
+ double airydisk2[NX*NY]; // row-major image
+
+ // 2.1 Parameters for airy disk plot (see https://en.wikipedia.org/wiki/Airy_disk)
+ double NA=1.1; // numerical aperture of lens
+ double wavelength1=540e-3; // wavelength of the light [micrometers]
+ double wavelength2=450e-3; // wavelength of the light [micrometers]
+
+ // 2.2 calculate image of airy disk in a row-major array
+ double x, y=-h/2.0;
+ for (int iy=0; iyaddCopiedImageAsColumn(airydisk1, NX, NY, "imagedata1");
+ size_t cAiryDisk2=ds->addCopiedImageAsColumn(airydisk2, NX, NY, "imagedata2");
+
+
+ // 4. create a graph (JKQTPColumnMathImage) with the column created above as data
+ // The data is color-coded with the color-palette JKQTPMathImageMATLAB
+ // the converted range of data is determined automatically because s etAutoImageRange(true)
+ JKQTPColumnRGBMathImage* graph=new JKQTPColumnRGBMathImage(&plot);
+ graph->setTitle("");
+ // image column with the data (R/G/B or C/M/Y ...)
+ graph->setImageGColumn(cAiryDisk1); // G/M channel
+ graph->setImageBColumn(cAiryDisk2); // B/Y channel
+ // set size of the data (the datastore does not contain this info, as it only manages 1D columns of data and this is used to assume a row-major ordering
+ graph->setNx(NX);
+ graph->setNy(NY);
+ // where does the image start in the plot, given in plot-axis-coordinates (bottom-left corner)
+ graph->setX(-w/2.0);
+ graph->setY(-h/2.0);
+ // width and height of the image in plot-axis-coordinates
+ graph->setWidth(w);
+ graph->setHeight(h);
+ // get coordinate axis of color-bar and set its label
+ graph->getColorBarRightAxisB()->setAxisLabel("blue light field strength [AU]");
+ graph->getColorBarRightAxisG()->setAxisLabel("green light field strength [AU]");
+ // determine min/max of data automatically and use it to set the range of the color-scale
+ graph->setAutoImageRange(true);
+
+
+ // 5. add the graphs to the plot, so it is actually displayed
+ plot.addGraph(graph);
+
+
+ // 6. set axis labels
+ plot.getXAxis()->setAxisLabel("x [{\\mu}m]");
+ plot.getYAxis()->setAxisLabel("y [{\\mu}m]");
+
+
+ // 7. fix axis and plot aspect ratio to 1
+ plot.getPlotter()->setMaintainAspectRatio(true);
+ plot.getPlotter()->setMaintainAxisAspectRatio(true);
+
+ // 8 autoscale the plot so the graph is contained
+ plot.zoomToFit();
+
+ // show plotter and make it a decent size
+ plot.show();
+ plot.resize(600,600);
+ plot.setWindowTitle("JKQTPColumnRGBMathImage");
+
+
+ return app.exec();
+}
+```
+The result looks like this:
+
+![jkqtplotter_simpletest_rgbimageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot.png)
+
+In the example above, we calculated two airy disks for two wavelengths and assigned them to the R and G color channel of the output image. Alternatively you can also assign them to the CMY-channels of the output image:
+```.cpp
+ // use (subtractive) CMY color model, not RGB
+ graph->setRgbMode(JKQTPRGBMathImageModeCMYMode);
+```
+
+The result will then look like this:
+
+![jkqtplotter_simpletest_rgbimageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_cmy.png)
+
+Note that the CMY-color model is a subtractive color model, whereas RGB is an additive model. Therefore CMY-color-scales range from CMY to white, whereas the RGB-scales range from RGB to black!
\ No newline at end of file
diff --git a/examples/simpletest_rgbimageplot/jkqtplotter_simpletest_rgbimageplot.cpp b/examples/simpletest_rgbimageplot/jkqtplotter_simpletest_rgbimageplot.cpp
new file mode 100644
index 0000000000..c5c3a03c05
--- /dev/null
+++ b/examples/simpletest_rgbimageplot/jkqtplotter_simpletest_rgbimageplot.cpp
@@ -0,0 +1,116 @@
+/** \example jkqtplotter_simpletest_rgbimageplot.cpp
+ * Shows how to plot colored math images with JKQTPlotter, where different images/matrices are assigned to different color channels
+ *
+ * \ref JKQTPlotterRGBImagePlot
+ */
+
+#include
+#include
+#include "jkqtplotter/jkqtplotter.h"
+#include "jkqtplotter/jkqtpgraphsimagergb.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+
+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.getPlotter()->setUseAntiAliasingForGraphs(true); // nicer (but slower) plotting
+ plot.getPlotter()->setUseAntiAliasingForSystem(true); // nicer (but slower) plotting
+ plot.getPlotter()->setUseAntiAliasingForText(true); // nicer (but slower) text rendering
+ JKQTPDatastore* ds=plot.getDatastore();
+
+ // 2. now we create data for the charts (taken from https://commons.wikimedia.org/wiki/File:Energiemix_Deutschland.svg)
+ const int NX=100; // image dimension in x-direction [pixels]
+ const int NY=100; // image dimension in x-direction [pixels]
+ const double dx=1e-2; // size of a pixel in x-direction [micrometers]
+ const double dy=1e-2; // size of a pixel in x-direction [micrometers]
+ const double w=static_cast(NX)*dx;
+ const double h=static_cast(NY)*dy;
+ double airydisk1[NX*NY]; // row-major image
+ double airydisk2[NX*NY]; // row-major image
+
+ // 2.1 Parameters for airy disk plot (see https://en.wikipedia.org/wiki/Airy_disk)
+ double NA=1.1; // numerical aperture of lens
+ double wavelength1=540e-3; // wavelength of the light [micrometers]
+ double wavelength2=450e-3; // wavelength of the light [micrometers]
+
+ // 2.2 calculate image of airy disk in a row-major array
+ double x, y=-h/2.0;
+ for (int iy=0; iyaddCopiedImageAsColumn(airydisk1, NX, NY, "imagedata1");
+ size_t cAiryDisk2=ds->addCopiedImageAsColumn(airydisk2, NX, NY, "imagedata2");
+
+
+ // 4. create a graph (JKQTPColumnMathImage) with the column created above as data
+ // The data is color-coded with the color-palette JKQTPMathImageMATLAB
+ // the converted range of data is determined automatically because s etAutoImageRange(true)
+ JKQTPColumnRGBMathImage* graph=new JKQTPColumnRGBMathImage(&plot);
+ graph->setTitle("");
+ // image column with the data (R/G/B or C/M/Y ...)
+ graph->setImageGColumn(cAiryDisk1); // G/M channel
+ graph->setImageBColumn(cAiryDisk2); // B/Y channel
+ // set size of the data (the datastore does not contain this info, as it only manages 1D columns of data and this is used to assume a row-major ordering
+ graph->setNx(NX);
+ graph->setNy(NY);
+ // where does the image start in the plot, given in plot-axis-coordinates (bottom-left corner)
+ graph->setX(-w/2.0);
+ graph->setY(-h/2.0);
+ // width and height of the image in plot-axis-coordinates
+ graph->setWidth(w);
+ graph->setHeight(h);
+ // get coordinate axis of color-bar and set its label
+ graph->getColorBarRightAxisB()->setAxisLabel("blue light field strength [AU]");
+ graph->getColorBarRightAxisG()->setAxisLabel("green light field strength [AU]");
+ // determine min/max of data automatically and use it to set the range of the color-scale
+ graph->setAutoImageRange(true);
+ // use (subtractive) CMY color model, not RGB
+ //graph->setRgbMode(JKQTPRGBMathImageModeCMYMode);
+
+
+ // 5. add the graphs to the plot, so it is actually displayed
+ plot.addGraph(graph);
+
+
+ // 6. set axis labels
+ plot.getXAxis()->setAxisLabel("x [{\\mu}m]");
+ plot.getYAxis()->setAxisLabel("y [{\\mu}m]");
+
+
+ // 7. fix axis and plot aspect ratio to 1
+ plot.getPlotter()->setMaintainAspectRatio(true);
+ plot.getPlotter()->setMaintainAxisAspectRatio(true);
+
+ // 8 autoscale the plot so the graph is contained
+ plot.zoomToFit();
+
+ // show plotter and make it a decent size
+ plot.show();
+ plot.resize(600,600);
+ plot.setWindowTitle("JKQTPColumnRGBMathImage");
+
+
+ return app.exec();
+}
diff --git a/examples/simpletest_rgbimageplot/jkqtplotter_simpletest_rgbimageplot.pro b/examples/simpletest_rgbimageplot/jkqtplotter_simpletest_rgbimageplot.pro
new file mode 100644
index 0000000000..adf5ad268b
--- /dev/null
+++ b/examples/simpletest_rgbimageplot/jkqtplotter_simpletest_rgbimageplot.pro
@@ -0,0 +1,25 @@
+# source code for this simple demo
+SOURCES = jkqtplotter_simpletest_rgbimageplot.cpp
+
+# configure Qt
+CONFIG += link_prl qt
+QT += core gui xml svg
+greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
+
+# output executable name
+TARGET = jkqtplotter_simpletest_rgbimageplot
+
+# include JKQTPlotter source code
+DEPENDPATH += ../../lib ../../staticlib/jkqtplotterlib
+INCLUDEPATH += ../../lib
+CONFIG (debug, debug|release) {
+ LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
+} else {
+ LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
+}
+message("LIBS = $$LIBS")
+
+
+
+
+
diff --git a/examples/simpletest_rgbimageplot/jkqtplotter_simpletest_rgbimageplot_and_lib.pro b/examples/simpletest_rgbimageplot/jkqtplotter_simpletest_rgbimageplot_and_lib.pro
new file mode 100644
index 0000000000..cdea571dac
--- /dev/null
+++ b/examples/simpletest_rgbimageplot/jkqtplotter_simpletest_rgbimageplot_and_lib.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+
+SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_rgbimageplot
+
+jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
+
+jkqtplotter_simpletest_rgbimageplot.file=$$PWD/jkqtplotter_simpletest_rgbimageplot.pro
+jkqtplotter_simpletest_rgbimageplot.depends = jkqtplotterlib
diff --git a/examples/simpletest_rgbimageplot_opencv/README.md b/examples/simpletest_rgbimageplot_opencv/README.md
index d6fb8f0087..281acb35bd 100644
--- a/examples/simpletest_rgbimageplot_opencv/README.md
+++ b/examples/simpletest_rgbimageplot_opencv/README.md
@@ -1,8 +1,8 @@
# Example (JKQTPlotter): Simple RGB image plot, showing a 3-channel OpenCV cv::Mat {#JKQTPlotterImagePlotRGBOpenCV}
-This project (see `./examples/simpletest_imageplot_opencv/`) simply creates a JKQTPlotter widget (as a new window) and adds a color-coded image plot of a mathematical function (here the Airy disk). The image is generated as an OpenCV cv::Mat image and then copied into a single column of the internal datasdtore (JKQTPMathImage could be directly used without the internal datastore).
-To copy the data a special OpenCV Interface function `JKQTPCopyCvMatToColumn()` is used, that copies the data from a cv::Mat directly into a column.
+This project (see `./examples/simpletest_imageplot_opencv/`) simply creates a JKQTPlotter widget (as a new window) and shows an RGB image read from a BMP-file. The image is generated as an [OpenCV](https://opencv.org/) [`cv::Mat`](https://docs.opencv.org/4.0.0/d3/d63/classcv_1_1Mat.html) image and then copied into a single column of the internal datasdtore (JKQTPMathImage could be directly used without the internal datastore).
+To copy the data a special OpenCV Interface function `JKQTPCopyCvMatToColumn()` is used, that copies the data from a (https://opencv.org/) [`cv::Mat`](https://docs.opencv.org/4.0.0/d3/d63/classcv_1_1Mat.html) directly into a column.
-The function `JKQTPCopyCvMatToColumn()` is available from the (non-default) header-only extension from `jkqtplotter/jkqtpopencvinterface.h`. This header provides facilities to interface JKQTPlotter with OPenCV.
+The function `JKQTPCopyCvMatToColumn()` is available from the (non-default) header-only extension from `jkqtplotter/jkqtpopencvinterface.h`. This header provides facilities to interface JKQTPlotter with OpenCV.
The source code of the main application is (see [`jkqtplotter_simpletest_imageplot_opencv.cpp`](https://github.com/jkriege2/JKQtPlotter/tree/master/examples/simpletest_imageplot_opencv/jkqtplotter_simpletest_imageplot_opencv.cpp):
```.cpp
@@ -99,4 +99,15 @@ The result looks like this:
The image is upside-down, because computer images use a coordinate system with 0 at the top-left (left-handed coordinate system) and the JKQTPlotter has its 0 at the bottom-left (right-handed coordinate system).
+You can modify the program above to display the image in the correct orientation, by adding the line
+```.cpp
+ // 5.1 invert y-axis, so image is oriented correctly
+ plot.getYAxis()->setInverted(true);
+```
+This will reorient the y-axis to point from top to bottom (for increasing positive coordinates):
+
+![jkqtplotter_simpletest_imageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_opencv_updisdedown.png)
+
+
+
diff --git a/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv.cpp b/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv.cpp
index cb672b554b..761f647e93 100644
--- a/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv.cpp
+++ b/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv.cpp
@@ -10,6 +10,7 @@
#include "jkqtplotter/jkqtpgraphs.h"
#include "jkqtplotter/jkqtpgraphsimagergb.h"
#include "jkqtplotter/jkqtpopencvinterface.h"
+#include
#include
@@ -30,6 +31,7 @@ int main(int argc, char* argv[])
// 2. now we open a BMP-file and load it into an OpenCV cv::Mat
cv::Mat picture = cv::imread("example.bmp");
+ qDebug()<setAxisLabel("x [pixels]");
plot.getYAxis()->setAxisLabel("y [pixels]");
+ // 6.1 invert y-axis, so image is oriented correctly
+ plot.getYAxis()->setInverted(true);
// 7. fix axis aspect ratio to width/height, so pixels are square
plot.getPlotter()->setMaintainAspectRatio(true);
diff --git a/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv.pro b/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv.pro
index 5616374517..77606a34cd 100644
--- a/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv.pro
+++ b/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv.pro
@@ -9,22 +9,29 @@ greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
# output executable name
TARGET = jkqtplotter_simpletest_rgbimageplot_opencv
-# add OpenCV-interface to JKQTPDatastore
-DEFINES += JKQTPLOTTER_OPENCV_INTERFACE
-
-
-
-
-
+exampleimg.files=$$PWD/example.bmp
+exampleimg.path=$$OUT_PWD
# link agains OpenCV-3.4.1
-INCLUDEPATH += $$PWD/OpenCV-3.4.1/include/
-LIBS += -L$$PWD/OpenCV-3.4.1/bin/ -llibopencv_core341 -llibopencv_imgcodecs341
+#INCLUDEPATH += $$PWD/../../../OpenCV-3.4.1/include/
+#LIBS += -L$$PWD/../../../OpenCV-3.4.1/bin/ -llibopencv_core341 -llibopencv_imgcodecs341
+#opencvdlls.files=$$PWD/../../../OpenCV-3.4.1/bin/*.dll
+#opencvdlls.path=$$OUT_PWD
+
+# link agains OpenCV-4
+INCLUDEPATH += $$PWD/../../../OpenCV-4.0.1/include/
+LIBS += -L$$PWD/../../../OpenCV-4.0.1/x64/mingw/bin -L$$PWD/../../../OpenCV-4.0.1/x64/mingw/lib -llibopencv_core400.dll -llibopencv_imgcodecs400.dll
+opencvdlls.files=$$PWD/../../../OpenCV-4.0.1/x64/mingw/bin/*.dll
+opencvdlls.path=$$OUT_PWD
+
+INCLUDEPATH+=../../lib
CONFIG (debug, debug|release) {
LIBS += -L../../staticlib/jkqtplotterlib/debug -ljkqtplotterlib_debug
} else {
LIBS += -L../../staticlib/jkqtplotterlib/release -ljkqtplotterlib
}
-message("LIBS = $$LIBS")
\ No newline at end of file
+message("LIBS = $$LIBS")
+
+INSTALLS += opencvdlls exampleimg
diff --git a/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv_and_lib.pro b/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv_and_lib.pro
new file mode 100644
index 0000000000..4460ec9487
--- /dev/null
+++ b/examples/simpletest_rgbimageplot_opencv/jkqtplotter_simpletest_rgbimageplot_opencv_and_lib.pro
@@ -0,0 +1,8 @@
+TEMPLATE = subdirs
+
+SUBDIRS += jkqtplotterlib jkqtplotter_simpletest_rgbimageplot_opencv
+
+jkqtplotterlib.file = ../../staticlib/jkqtplotterlib/jkqtplotterlib.pro
+
+jkqtplotter_simpletest_rgbimageplot_opencv.file=$$PWD/jkqtplotter_simpletest_rgbimageplot_opencv.pro
+jkqtplotter_simpletest_rgbimageplot_opencv.depends = jkqtplotterlib
diff --git a/examples/simpletest_rgbimageplot_qt/README.md b/examples/simpletest_rgbimageplot_qt/README.md
index 58bee82897..79999f083e 100644
--- a/examples/simpletest_rgbimageplot_qt/README.md
+++ b/examples/simpletest_rgbimageplot_qt/README.md
@@ -28,4 +28,16 @@ The result looks like this:
![jkqtplotter_simpletest_imageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_qt.png)
+The image is upside-down, because computer images use a coordinate system with 0 at the top-left (left-handed coordinate system) and the JKQTPlotter has its 0 at the bottom-left (right-handed coordinate system).
+
+You can modify the program above to display the image in the correct orientation, by adding the line
+```.cpp
+ // 6.1 invert y-axis, so image is oriented correctly
+ plot.getYAxis()->setInverted(true);
+```
+This will reorient the y-axis to point from top to bottom (for increasing positive coordinates):
+
+![jkqtplotter_simpletest_imageplot](https://raw.githubusercontent.com/jkriege2/JKQtPlotter/master/screenshots/jkqtplotter_simpletest_rgbimageplot_qt_updisdedown.png)
+
+
diff --git a/examples/simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.cpp b/examples/simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.cpp
index 7630e29772..2e8dfb8abc 100644
--- a/examples/simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.cpp
+++ b/examples/simpletest_rgbimageplot_qt/jkqtplotter_simpletest_rgbimageplot_qt.cpp
@@ -51,6 +51,8 @@ int main(int argc, char* argv[])
// 5. set axis labels
plot.getXAxis()->setAxisLabel("x [pixels]");
plot.getYAxis()->setAxisLabel("y [pixels]");
+ // 5.1 invert y-axis, so image is oriented correctly
+ plot.getYAxis()->setInverted(true);
// 6. fix axis aspect ratio to width/height, so pixels are square
plot.getPlotter()->setMaintainAspectRatio(true);
diff --git a/lib/jkqtplotter/jkqtpcoordinateaxes.h b/lib/jkqtplotter/jkqtpcoordinateaxes.h
index 084bf75ed6..74ff681560 100644
--- a/lib/jkqtplotter/jkqtpcoordinateaxes.h
+++ b/lib/jkqtplotter/jkqtpcoordinateaxes.h
@@ -105,6 +105,16 @@ class JKQTBasePlotter;
are implemented in p2x(). They can be used to show the system coordinates of the current mouse position.
+ \section jkqtplotter_coordinateaxes_inverted Inverted Coordinate Axes
+
+ In some cases it may be necessary to invert the direction of increasing coordinates on an axis. One such case is image analysis, as computer images usually
+ have coordinates starting with (0,0) at the top left and increasing to the right (x) and down (y). You can invert any axis by setting \c setInverted(true).
+
+ \image html jkqtplotter_inverted_yaxis.png
+
+ \see You can find example here: \ref JKQTPlotterImagePlotQImageRGB and \ref JKQTPlotterImagePlotRGBOpenCV
+
+
\section jkqtplotter_base_grids_baseelemenets Axis JKQTPCoordinateAxisStyle::Ticks and Grids
This section explains how this component draws the JKQTPCoordinateAxisStyle::ticks on coordinate axes and the grids that may be drawn below
@@ -708,7 +718,10 @@ class JKQTP_LIB_EXPORT JKQTPCoordinateAxis: public QObject {
* \see calcPlotScaling(), calcTickSpacing()
*/
double offset;
- /** \brief indicates whether the axis is to be inverted or not */
+ /** \brief indicates whether the axis is to be inverted or not
+ *
+ * \image html jkqtplotter_inverted_yaxis.png
+ */
bool inverted;
/** \brief calculated property: x position of the first tick (calculated by calcPlotScaling() ). Given in system coordinates, not pixel coordinates.
diff --git a/lib/jkqtplotter/jkqtpdatastorage.h b/lib/jkqtplotter/jkqtpdatastorage.h
index 6b05ac71a2..a9002cd414 100644
--- a/lib/jkqtplotter/jkqtpdatastorage.h
+++ b/lib/jkqtplotter/jkqtpdatastorage.h
@@ -34,9 +34,6 @@
#include
#include
#include
-#ifdef JKQTPLOTTER_OPENCV_INTERFACE
-# include
-#endif
#ifndef JKQTPDATASTORAGE_H
#define JKQTPDATASTORAGE_H
diff --git a/lib/jkqtplotter/jkqtpgraphsimage.cpp b/lib/jkqtplotter/jkqtpgraphsimage.cpp
index cb51502caf..908297f0cc 100644
--- a/lib/jkqtplotter/jkqtpgraphsimage.cpp
+++ b/lib/jkqtplotter/jkqtpgraphsimage.cpp
@@ -97,7 +97,7 @@ QColor JKQTPImageBase::getKeyLabelColor() {
}
void JKQTPImageBase::plotImage(JKQTPEnhancedPainter& painter, QImage& image, double x, double y, double width, double height) {
- if ((!JKQTPIsOKFloat(x))||(!JKQTPIsOKFloat(y))||(!JKQTPIsOKFloat(width))||(!JKQTPIsOKFloat(height))||(width<=0) || (height<=0) || image.isNull() || (image.width()<=0) || (image.height()<=0)) {
+ if ((!JKQTPIsOKFloat(x))||(!JKQTPIsOKFloat(y))||(!JKQTPIsOKFloat(width))||(!JKQTPIsOKFloat(height))||(width==0) || (height==0) || image.isNull() || (image.width()<=0) || (image.height()<=0)) {
return;
}
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
@@ -110,13 +110,37 @@ void JKQTPImageBase::plotImage(JKQTPEnhancedPainter& painter, QImage& image, dou
QPointF pp2=transform(xmax,ymin);
QRectF pr(pp1, pp2);
+ bool mirrx=false;
+ bool mirry=false;
+
QPointF p1=transform(x,y+height);
QPointF p2=transform(x+width,y);
+ if (p1.x()>p2.x()) {
+ double tmp=p1.x();
+ p1.setX(p2.x());
+ p2.setX(tmp);
+ tmp=pp1.x();
+ pp1.setX(pp2.x());
+ pp2.setX(tmp);
+ mirrx=true;
+ }
+ if (p1.y()>p2.y()) {
+ double tmp=p1.y();
+ p1.setY(p2.y());
+ p2.setY(tmp);
+ tmp=pp1.y();
+ pp1.setY(pp2.y());
+ pp2.setY(tmp);
+ mirry=true;
+ }
QRectF r(p1, p2);
+
+
+
if (image.width()>0 && image.height()>0 && !image.isNull()) {
if (r.width()<2*pr.width() && r.height()<2*pr.height()) {
//painter.drawImage(QRectF(p1.x(), p2.y(), fabs(p2.x()-p1.x()), fabs(p2.y()-p1.y())), image);
- painter.drawImage(QPoint(p1.x(), p1.y()), image.scaled(QSize(fabs(p2.x()-p1.x()), fabs(p2.y()-p1.y())), Qt::IgnoreAspectRatio, Qt::FastTransformation));
+ painter.drawImage(QPoint(p1.x(), p1.y()), image.mirrored(mirrx, mirry).scaled(QSize(fabs(p2.x()-p1.x()), fabs(p2.y()-p1.y())), Qt::IgnoreAspectRatio, Qt::FastTransformation));
//qDebug()<<"\nimage.size = "<(image.width());
@@ -136,7 +160,7 @@ void JKQTPImageBase::plotImage(JKQTPEnhancedPainter& painter, QImage& image, dou
QRectF target(p1.x()+ps1.x()*pixwidth, p1.y()+ps1.y()*pixheight, source.width()*pixwidth, source.height()*pixheight);
//qDebug()<<"source = "<