2015-07-11 18:56:02 +08:00
/*
2019-01-12 23:01:55 +08:00
Copyright ( c ) 2008 - 2019 Jan W . Krieger ( < jan @ jkrieger . de > )
2015-07-11 18:56:02 +08:00
2015-07-12 22:34:27 +08:00
2015-07-11 18:56:02 +08:00
This software is free software : you can redistribute it and / or modify
it under the terms of the GNU Lesser General Public License ( LGPL ) as published by
2019-02-08 00:24:46 +08:00
the Free Software Foundation , either version 2.1 of the License , or
2015-07-11 18:56:02 +08:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Lesser General Public License ( LGPL ) for more details .
You should have received a copy of the GNU Lesser General Public License ( LGPL )
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# ifndef JKQTPIMAGETOOLS_H
# define JKQTPIMAGETOOLS_H
# include <QIcon>
# include <QDebug>
# include <QImage>
# include <QStringList>
2019-05-18 19:22:46 +08:00
# include "jkqtcommon/jkqtp_imexport.h"
2015-07-11 18:56:02 +08:00
# include <cmath>
# include <cfloat>
# include <stdint.h>
# include <QColor>
2019-05-18 19:22:46 +08:00
# include "jkqtcommon/jkqtptools.h"
2015-07-11 18:56:02 +08:00
# ifndef NO_JKQTPLOTTER
2019-05-18 19:22:46 +08:00
# include "jkqtcommon/jkqtptools.h"
2015-07-11 18:56:02 +08:00
2019-01-20 17:49:29 +08:00
class JKQTPVerticalIndependentAxis ; // forward
class JKQTPHorizontalIndependentAxis ; // forward
class JKQTBasePlotter ; // forward
2015-07-11 18:56:02 +08:00
# endif
2019-02-08 00:24:46 +08:00
/*! \brief tool structure that summarizes several static properties
\ ingroup jkqtptools_qt
\ internal
*/
struct JKQTP_LIB_EXPORT JKQTPImageTools {
/*! \brief Width of the Palette-Icons, generated e.g. by JKQTPMathImageGetPaletteIcon()
\ ingroup jkqtptools_qt */
static const int PALETTE_ICON_WIDTH ;
/*! \brief Height of the Palette-Icons, generated e.g. by JKQTPMathImageGetPaletteIcon()
\ ingroup jkqtptools_qt */
static const int PALETTE_IMAGEICON_HEIGHT ;
/*! \brief size of the lookup tables used by JKQTFPimagePlot_array2image()
\ ingroup jkqtplotter_imagelots_tools
*/
static const int LUTSIZE ;
} ;
2018-12-19 00:13:18 +08:00
2015-07-11 18:56:02 +08:00
/*! \brief available palettes for coloring an image
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
*/
enum JKQTPMathImageColorPalette {
2019-01-12 23:01:55 +08:00
JKQTPMathImageGRAY = 0 , /*!< \image html palettes/palette_gray.png */
JKQTPMathImageINVERTEDGRAY , /*!< \image html palettes/palette_invgray.png */
JKQTPMathImageRED , /*!< \image html palettes/palette_red.png */
JKQTPMathImageINVERTEDRED , /*!< \image html palettes/palette_invred.png */
JKQTPMathImageGREEN , /*!< \image html palettes/palette_green.png */
JKQTPMathImageINVERTEDGREEN , /*!< \image html palettes/palette_invgreen.png */
JKQTPMathImageBLUE , /*!< \image html palettes/palette_blue.png */
JKQTPMathImageINVERTEDBLUE , /*!< \image html palettes/palette_invblue.png */
JKQTPMathImageCYAN , /*!< \image html palettes/palette_cyan.png */
JKQTPMathImageINVERTED_CYAN , /*!< \image html palettes/palette_invcyan.png */
JKQTPMathImageYELLOW , /*!< \image html palettes/palette_yellow.png */
JKQTPMathImageINVERTED_YELLOW , /*!< \image html palettes/palette_invyellow.png */
2019-01-16 04:28:07 +08:00
JKQTPMathImageMAGENTA , /*!< \image html palettes/palette_magenta.png */
2019-01-12 23:01:55 +08:00
JKQTPMathImageINVERTED_MAGENTA , /*!< \image html palettes/palette_invmagenta.png */
JKQTPMathImageMATLAB , /*!< \image html palettes/palette_Matlab.png */
JKQTPMathImageINVERTED_MATLAB , /*!< \image html palettes/palette_invMatlab.png */
JKQTPMathImageRYGB , /*!< \image html palettes/palette_RYGB.png */
JKQTPMathImageINVERTED_RYGB , /*!< \image html palettes/palette_invRYGB.png */
JKQTPMathImageHSV , /*!< \image html palettes/palette_HSV.png */
JKQTPMathImageINVERTED_HSV , /*!< \image html palettes/palette_invHSV.png */
JKQTPMathImageRAINBOW , /*!< \image html palettes/palette_rainbow.png */
JKQTPMathImageINVERTED_RAINBOW , /*!< \image html palettes/palette_invrainbow.png */
JKQTPMathImageHOT , /*!< \image html palettes/palette_AFMhot.png */
JKQTPMathImageINVERTED_HOT , /*!< \image html palettes/palette_invAFMhot.png */
JKQTPMathImageOCEAN , /*!< \image html palettes/palette_ocean.png */
JKQTPMathImageINVERTED_OCEAN , /*!< \image html palettes/palette_invocean.png */
JKQTPMathImageTRAFFICLIGHT , /*!< \image html palettes/palette_trafficlight.png */
JKQTPMathImageINVERTED_TRAFFICLIGHT , /*!< \image html palettes/palette_invtrafficlight.png */
JKQTPMathImageBLUEMAGENTAYELLOW , /*!< \image html palettes/palette_BlMaYe.png */
JKQTPMathImageINVERTED_BLUEMAGENTAYELLOW , /*!< \image html palettes/palette_YeMaBl.png */
JKQTPMathImageBLUEYELLOW , /*!< \image html palettes/palette_BlYe.png */
JKQTPMathImageINVERTED_BLUEYELLOW , /*!< \image html palettes/palette_YeBl.png */
JKQTPMathImageBLUEWHITERED , /*!< \image html palettes/palette_bluewhitered.png */
JKQTPMathImageREDWHITEBLUE , /*!< \image html palettes/palette_redwhiteblue.png */
JKQTPMathImageBLACKBLUEREDYELLOW , /*!< \image html palettes/palette_BBlRdYe.png */
JKQTPMathImageGREENREDVIOLET , /*!< \image html palettes/palette_GnRdVi.png */
2019-01-16 04:28:07 +08:00
JKQTPMathImageBLACKBLUEWHITEYELLOWWHITE , /*!< \image html palettes/palette_BWprint.png */
JKQTPMathImageWHITEYELLOWWHITEBLUEBLACK , /*!< \image html palettes/palette_invBWprint.png */
2019-01-12 23:01:55 +08:00
JKQTPMathImageBR_GR , /*!< \image html palettes/palette_BrBG.png */
JKQTPMathImagePU_OR , /*!< \image html palettes/palette_PuOr.png */
JKQTPMathImageGN_BU , /*!< \image html palettes/palette_greenblue.png */
JKQTPMathImageBU_GN , /*!< \image html palettes/palette_bluegreen.png */
JKQTPMathImageYL_GN_BU , /*!< \image html palettes/palette_YeGnBu.png */
JKQTPMathImageBR_GR_STEP , /*!< \image html palettes/palette_stepsBrBG.png */
JKQTPMathImagePU_OR_STEP , /*!< \image html palettes/palette_stepsPuOr.png */
JKQTPMathImageGN_BU_STEP , /*!< \image html palettes/palette_stepsGnBl.png */
JKQTPMathImageBU_GN_STEP , /*!< \image html palettes/palette_stepsBlGn.png */
JKQTPMathImageYL_GN_BU_STEP , /*!< \image html palettes/palette_stepsYeGnBu.png */
JKQTPMathImageCYANWHITE , /*!< \image html palettes/palette_cyanwhite.png */
JKQTPMathImageINVERTED_CYANWHITE , /*!< \image html palettes/palette_whitecyan.png */
JKQTPMathImageYELLOWWHITE , /*!< \image html palettes/palette_yellowwhite.png */
JKQTPMathImageINVERTED_YELLOWWHITE , /*!< \image html palettes/palette_whiteyellow.png */
JKQTPMathImageMAGENTAWHITE , /*!< \image html palettes/palette_magentawhite.png */
JKQTPMathImageINVERTED_MAGENTAWHITE , /*!< \image html palettes/palette_whitemagenta.png */
JKQTPMathImageBlueGreenRed , /*!< \image html palettes/palette_bluegreenred.png */
JKQTPMathImageRedGreenBlue , /*!< \image html palettes/palette_redgreenblue.png */
2015-07-11 18:56:02 +08:00
JKQTPMathImagePREDEFINED_PALETTES_COUNT ,
JKQTPMathImageUSER_PALETTE = 65000 ,
JKQTPMathImageALPHA = JKQTPMathImageUSER_PALETTE - 2 ,
JKQTPMathImageINVERTED_ALPHA = JKQTPMathImageUSER_PALETTE - 1
} ;
2019-02-08 00:24:46 +08:00
/*! \brief convert the palette \a p to a string
\ ingroup jkqtplotter_imagelots_tools
\ see String2JKQTPMathImageColorPalette ( )
*/
QString JKQTPMathImageColorPalette2String ( JKQTPMathImageColorPalette p ) ;
2015-07-11 18:56:02 +08:00
2019-02-08 00:24:46 +08:00
/*! \brief convert the palette name \a p to JKQTPMathImageColorPalette (compatible with String2JKQTPMathImageColorPalette() )
\ ingroup jkqtplotter_imagelots_tools
\ see JKQTPMathImageColorPalette2String ( )
*/
JKQTPMathImageColorPalette String2JKQTPMathImageColorPalette ( const QString & p ) ;
2015-07-11 18:56:02 +08:00
/*! \brief modes available for image pixels that are above/below the pixel value range
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
*/
enum JKQTPMathImageColorRangeFailAction {
JKQTPMathImageLastPaletteColor = 0 , /*!< set to last color in the palette */
JKQTPMathImageGivenColor = 1 , /*!< set to the provided min/max color */
JKQTPMathImageTransparent = 2 /*!< set transparent */
} ;
/*! \brief modes available for RGB images
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2019-02-10 05:17:01 +08:00
\ see Examples : \ ref JKQTPlotterRGBImagePlot
2015-07-11 18:56:02 +08:00
*/
enum JKQTPRGBMathImageRGBMode {
2019-02-10 05:17:01 +08:00
JKQTPRGBMathImageModeRGBMode = 0 , /*!< image channels are mapped to the R, G and B channel (red-green-blue) */
JKQTPRGBMathImageModeHSVMode = 1 , /*!< image channels are mapped to the H, S and V channel (hue-saturation-value) */
JKQTPRGBMathImageModeHSLMode = 2 , /*!< image channels are mapped to the H, S and L channel (bue-saturation-luminance) */
JKQTPRGBMathImageModeCMYMode = 3 /*!< image channels are mapped to the C, M and Y channel (subtractive color model!!!) */
2015-07-11 18:56:02 +08:00
} ;
/*! \brief returns a vector containing all elements of the given array
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
*/
template < class T >
2019-01-20 17:49:29 +08:00
inline QVector < T > JKQTPImagePlot_arrayToVector ( const T * input , int N ) {
2015-07-11 18:56:02 +08:00
if ( ! input | | N < = 0 ) return QVector < double > ( ) ;
T dummy ;
QVector < T > out ( N , dummy ) ;
memcpy ( out . data ( ) , input , N * sizeof ( T ) ) ;
return out ;
}
/*! \brief returns a vector containing all elements of the given array as doubles
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
*/
template < class T >
2019-01-20 17:49:29 +08:00
inline QVector < double > JKQTPImagePlot_arrayToDVector ( const T * input , int N ) {
2015-07-11 18:56:02 +08:00
if ( ! input | | N < = 0 ) return QVector < double > ( ) ;
QVector < double > out ( N , 0.0 ) ;
for ( int i = 0 ; i < N ; i + + ) {
out [ i ] = input [ i ] ;
}
return out ;
}
/*! \brief returns a vector containing all elements of the given boolean array as doubles (true=1, false=0)
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
*/
2019-01-20 17:49:29 +08:00
inline QVector < double > JKQTPImagePlot_BarrayToDVector ( const bool * input , int N ) {
2015-07-11 18:56:02 +08:00
if ( ! input | | N < = 0 ) return QVector < double > ( ) ;
QVector < double > out ( N , 0.0 ) ;
for ( int i = 0 ; i < N ; i + + ) {
if ( input [ i ] ) out [ i ] = 1.0 ;
}
return out ;
}
/*! \brief fin the minimum pixel value in the given image \a dbl with width \a width and height \a height
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
*/
template < class T >
2019-01-20 17:49:29 +08:00
inline double JKQTPImagePlot_getImageMin ( T * dbl , int width , int height )
2015-07-11 18:56:02 +08:00
{
if ( ! dbl | | width < = 0 | | height < = 0 )
return 0 ;
double min = 0 ;
double max = 0 ;
bool first = true ;
for ( int i = 1 ; i < width * height ; + + i )
{
2018-12-16 21:59:39 +08:00
T v = dbl [ i ] ;
2018-12-06 01:33:32 +08:00
if ( ! ( std : : isnan ( static_cast < long double > ( v ) ) | | std : : isinf ( static_cast < long double > ( v ) ) ) ) {
2015-07-11 18:56:02 +08:00
if ( first ) {
min = max = v ;
first = false ;
} else {
if ( v < min )
min = v ;
else if ( v > max )
max = v ;
}
}
}
return min ;
} ;
/*! \brief fin the maximum pixel value in the given image \a dbl with width \a width and height \a height
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
*/
template < class T >
2019-01-20 17:49:29 +08:00
inline double JKQTPImagePlot_getImageMax ( T * dbl , int width , int height )
2015-07-11 18:56:02 +08:00
{
if ( ! dbl | | width < = 0 | | height < = 0 )
return 0 ;
double min = 0 ;
double max = 0 ;
bool first = true ;
for ( int i = 1 ; i < width * height ; + + i )
{
2018-12-16 21:59:39 +08:00
T v = dbl [ i ] ;
2018-12-06 01:33:32 +08:00
if ( ! ( std : : isnan ( static_cast < long double > ( v ) ) | | std : : isinf ( static_cast < long double > ( v ) ) ) ) {
2015-07-11 18:56:02 +08:00
if ( first ) {
min = max = v ;
first = false ;
} else {
if ( v < min )
min = v ;
else if ( v > max )
max = v ;
}
}
}
return max ;
} ;
/*! \brief convert a 2D image (as 1D array) into a QImage and puts the image values into one color channel (set by \a channel).The other color channels are not changed! So a repeated call to this function for the SAME QImage will
result in a step - by - step buildup of an image .
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
\ note All calls ( except channel > = 3 , i . e . alpha ) set alpha to 255. Only the call
with channel = = 3 ( alpha ) sets alpha to the desired value . Calls with channel = = 4 ( saturation ) , channel = = 5 ( value )
leave alpha as it is .
*/
template < class T >
2019-01-26 20:00:40 +08:00
inline void JKQTPImagePlot_array2RGBimage ( T * dbl_in , int width , int height , QImage & img , int channel , double minColor , double maxColor , JKQTPRGBMathImageRGBMode rgbMode = JKQTPRGBMathImageModeRGBMode , bool logScale = false , double logBase = 10.0 )
2015-07-11 18:56:02 +08:00
{
if ( ! dbl_in | | width < = 0 | | height < = 0 )
return ;
double min = * dbl_in ;
double max = * dbl_in ;
bool first = true ;
if ( minColor = = maxColor ) {
for ( int i = 1 ; i < width * height ; + + i )
{
2018-12-16 21:59:39 +08:00
T v = dbl_in [ i ] ;
2018-12-06 01:33:32 +08:00
if ( std : : isfinite ( static_cast < long double > ( v ) ) ) {
2015-07-11 18:56:02 +08:00
if ( first ) {
min = max = v ;
first = false ;
} else {
if ( v < min )
min = v ;
else if ( v > max )
max = v ;
}
}
}
} else {
min = minColor ;
max = maxColor ;
}
T * dbl = dbl_in ;
if ( logScale ) {
double logB = log10 ( logBase ) ;
dbl = ( T * ) malloc ( width * height * sizeof ( T ) ) ;
//memcpy(dbl, dbl_in, width*height*sizeof(T));
for ( int i = 0 ; i < width * height ; i + + ) {
dbl [ i ] = log10 ( dbl_in [ i ] ) / logB ;
}
min = log10 ( min ) / logB ;
max = log10 ( max ) / logB ;
}
double delta = max - min ;
if ( min ! = max ) {
if ( rgbMode = = JKQTPRGBMathImageModeRGBMode ) {
//qDebug()<<"RGBMode";
if ( channel = = 0 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = trunc ( double ( dbl [ j * width + i ] - min ) * 255.0 / delta ) ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
2018-12-16 21:59:39 +08:00
const QRgb l = line [ i ] ;
2015-07-11 18:56:02 +08:00
//if (j==5) qDebug()<<"r: "<<v<<qGreen(l)<<qBlue(l)<<qAlpha(255);
line [ i ] = qRgb ( v , qGreen ( l ) , qBlue ( l ) ) ;
}
}
} else if ( channel = = 1 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
2018-12-16 21:59:39 +08:00
const QRgb l = line [ i ] ;
2015-07-11 18:56:02 +08:00
//if (j==5) qDebug()<<"g: "<<qRed(l)<<v<<qBlue(l)<<qAlpha(255);
line [ i ] = qRgb ( qRed ( l ) , v , qBlue ( l ) ) ;
}
}
} else if ( channel = = 2 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
2018-12-16 21:59:39 +08:00
const QRgb l = line [ i ] ;
2015-07-11 18:56:02 +08:00
//if (j==5) qDebug()<<"b: "<<qRed(l)<<qGreen(l)<<v<<qAlpha(255);
line [ i ] = qRgb ( qRed ( l ) , qGreen ( l ) , v ) ;
}
}
2019-01-26 20:00:40 +08:00
} else if ( channel = = 3 ) {
for ( int j = 0 ; j < height ; + + j ) {
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
for ( int i = 0 ; i < width ; + + i ) {
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
const QRgb l = line [ i ] ;
//if (j==5) qDebug()<<"b: "<<qRed(l)<<qGreen(l)<<v<<qAlpha(255);
line [ i ] = qRgba ( qRed ( l ) , qGreen ( l ) , qBlue ( l ) , v ) ;
}
}
2015-07-11 18:56:02 +08:00
}
} else if ( rgbMode = = JKQTPRGBMathImageModeCMYMode ) {
//qDebug()<<"RGBMode";
if ( channel = = 0 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = trunc ( double ( dbl [ j * width + i ] - min ) * 255.0 / delta ) ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
2018-12-16 21:59:39 +08:00
const QRgb l = line [ i ] ;
2015-07-11 18:56:02 +08:00
//if (j==5) qDebug()<<"r: "<<v<<qGreen(l)<<qBlue(l)<<qAlpha(255);
line [ i ] = QColor : : fromCmyk ( v , QColor ( l ) . magenta ( ) , QColor ( l ) . yellow ( ) , QColor ( l ) . black ( ) ) . rgba ( ) ;
}
}
} else if ( channel = = 1 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
2018-12-16 21:59:39 +08:00
const QRgb l = line [ i ] ;
2015-07-11 18:56:02 +08:00
//if (j==5) qDebug()<<"g: "<<qRed(l)<<v<<qBlue(l)<<qAlpha(255);
line [ i ] = QColor : : fromCmyk ( QColor ( l ) . cyan ( ) , v , QColor ( l ) . yellow ( ) , QColor ( l ) . black ( ) ) . rgba ( ) ;
}
}
} else if ( channel = = 2 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
2018-12-16 21:59:39 +08:00
const QRgb l = line [ i ] ;
2015-07-11 18:56:02 +08:00
//if (j==5) qDebug()<<"b: "<<qRed(l)<<qGreen(l)<<v<<qAlpha(255);
line [ i ] = QColor : : fromCmyk ( QColor ( l ) . cyan ( ) , QColor ( l ) . magenta ( ) , v , QColor ( l ) . black ( ) ) . rgba ( ) ;
}
}
}
} else if ( rgbMode = = JKQTPRGBMathImageModeHSVMode ) {
if ( channel = = 0 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = trunc ( double ( dbl [ j * width + i ] - min ) * 220.0 / delta ) ;
v = ( v < 0 ) ? 0 : ( ( v > 360 ) ? 360 : v ) ;
QColor l = QColor : : fromRgb ( line [ i ] ) ;
//if (i<10 && j==5) qDebug()<<"hi: "<<l.name()<<dbl[j*width+i]<<min<<max;
l . setHsv ( v , l . saturation ( ) , l . value ( ) ) ;
//if (i<10 && j==5) qDebug()<<"ho: "<<l.name();
line [ i ] = l . rgb ( ) ;
}
}
} else if ( channel = = 1 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
QColor l = QColor : : fromRgb ( line [ i ] ) ;
//if (i<10 && j==5) qDebug()<<"si: "<<l.name()<<dbl[j*width+i]<<min<<max;
l . setHsv ( l . hue ( ) , v , l . value ( ) ) ;
//if (i<10 && j==5) qDebug()<<"so: "<<l.name();
line [ i ] = l . rgb ( ) ;
}
}
} else if ( channel = = 2 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
QColor l = QColor : : fromRgb ( line [ i ] ) ;
//if (i<10 && j==5) qDebug()<<"vi: "<<l.name()<<dbl[j*width+i]<<min<<max;
l . setHsv ( l . hue ( ) , l . saturation ( ) , v ) ;
//if (i<10 && j==5) qDebug()<<"vo: "<<l.name();
line [ i ] = l . rgb ( ) ;
}
}
}
} else if ( rgbMode = = JKQTPRGBMathImageModeHSLMode ) {
if ( channel = = 0 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = trunc ( double ( dbl [ j * width + i ] - min ) * 255.0 / delta ) ;
v = ( v < 0 ) ? 0 : ( ( v > 360 ) ? 360 : v ) ;
QColor l = line [ i ] ;
l . setHsl ( v , l . saturation ( ) , l . lightness ( ) ) ;
line [ i ] = l . rgb ( ) ;
}
}
} else if ( channel = = 1 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
QColor l = line [ i ] ;
l . setHsl ( l . hue ( ) , v , l . lightness ( ) ) ;
line [ i ] = l . rgb ( ) ;
}
}
} else if ( channel = = 2 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
QColor l = line [ i ] ;
l . setHsl ( l . hue ( ) , l . saturation ( ) , v ) ;
line [ i ] = l . rgb ( ) ;
}
}
}
}
if ( channel = = 3 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
2018-12-16 21:59:39 +08:00
const QRgb l = line [ i ] ;
2015-07-11 18:56:02 +08:00
line [ i ] = qRgba ( qRed ( l ) , qGreen ( l ) , qBlue ( l ) , v ) ;
}
}
} else if ( channel = = 4 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
QColor c = QColor : : fromRgba ( line [ i ] ) ;
c . setHsv ( c . hue ( ) , v , c . value ( ) , c . alpha ( ) ) ;
line [ i ] = c . rgba ( ) ;
}
}
} else if ( channel = = 5 ) {
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
2019-01-26 20:00:40 +08:00
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
2018-12-16 21:59:39 +08:00
for ( int i = 0 ; i < width ; + + i ) {
2015-07-11 18:56:02 +08:00
int v = ( dbl [ j * width + i ] - min ) * 255 / delta ;
v = ( v < 0 ) ? 0 : ( ( v > 255 ) ? 255 : v ) ;
QColor c = QColor : : fromRgba ( line [ i ] ) ;
c . setHsv ( c . hue ( ) , c . saturation ( ) , v , c . alpha ( ) ) ;
line [ i ] = c . rgba ( ) ;
}
}
}
}
if ( logScale ) free ( dbl ) ;
}
2019-01-13 01:53:16 +08:00
/*! \brief Generate a QList with \a N entries of the value \a defaultValue
\ ingroup jkqtptools_qt */
2015-07-11 18:56:02 +08:00
template < typename T >
2019-01-20 17:49:29 +08:00
inline QList < T > JKQTPImagePlot_makeQList ( const T & defaultVal , int N = 1 ) {
2015-07-11 18:56:02 +08:00
QList < T > l ;
for ( int i = 0 ; i < N ; i + + ) l < < defaultVal ;
return l ;
}
2019-01-13 01:53:16 +08:00
/*! \brief build a linearly interpolated palette in \a lut with \a N entries that are provided in \a items
\ ingroup jkqtplotter_imagelots_tools
The entries in \ a items are sorted by the first ( double ) argument and the full range is distributed
over 0 . . . lut_size . Values in the LUT in between are generated by linear interpolations
\ a lut needs to have \ c lut_size ) entries
*/
2019-02-08 00:24:46 +08:00
void JKQTP_LIB_EXPORT JKQTPImagePlot_buildDefinedPaletteLinInterpolate ( int * lut , QList < QPair < double , QRgb > > items , int lut_size = JKQTPImageTools : : LUTSIZE ) ;
2015-07-11 18:56:02 +08:00
2019-01-13 01:53:16 +08:00
/*! \brief build a linearly interpolated palette in \a lut with \a N entries that are provided as (double, QRgb) value pairss in the variable arguments
\ ingroup jkqtplotter_imagelots_tools
The entries in \ a items are sorted by the first ( double ) argument and the full range is distributed
over 0 . . . lut_size . Values in the LUT in between are generated by linear interpolations
\ a lut needs to have \ c lut_size ) entries
*/
2019-02-03 21:04:48 +08:00
void JKQTP_LIB_EXPORT JKQTPImagePlot_buildDefinedPaletteLinInterpolate ( int * lut , int N , . . . ) ;
2015-07-11 18:56:02 +08:00
2019-01-13 01:53:16 +08:00
/*! \brief build a palette in \a lut with \a N entries that are provided in \a items
\ ingroup jkqtplotter_imagelots_tools
The entries in \ a items are sorted by the first ( double ) argument and the full range is distributed
2019-02-08 00:24:46 +08:00
over 0 . . . JKQTPImageTools : : LUTSIZE .
2019-01-13 01:53:16 +08:00
2019-02-08 00:24:46 +08:00
\ a lut needs to have \ c JKQTPImageTools : : LUTSIZE ) entries
2019-01-13 01:53:16 +08:00
*/
2019-02-03 21:04:48 +08:00
void JKQTP_LIB_EXPORT JKQTPImagePlot_buildDefinedPalette ( int * lut , QList < QPair < double , QRgb > > items ) ;
2015-07-11 18:56:02 +08:00
2019-01-13 01:53:16 +08:00
/*! \brief build a palette in \a lut with \a N entries that are provided as as (double, QRgb) value pairss in the variable arguments
\ ingroup jkqtplotter_imagelots_tools
*/
2019-02-03 21:04:48 +08:00
void JKQTP_LIB_EXPORT JKQTPImagePlot_buildDefinedPalette ( int * lut , int N , . . . ) ;
2015-07-11 18:56:02 +08:00
2019-01-13 01:53:16 +08:00
/*! \brief return a list of all globally available LUTs
\ ingroup jkqtplotter_imagelots_tools */
2019-02-03 21:04:48 +08:00
QStringList JKQTP_LIB_EXPORT JKQTPImagePlot_getPredefinedPalettes ( ) ;
2015-07-11 18:56:02 +08:00
2019-01-13 01:53:16 +08:00
/*! \brief create a LUT for a given JKQTPMathImageColorPalette, store it in \a lutstore and return it
\ ingroup jkqtplotter_imagelots_tools
2019-02-08 00:24:46 +08:00
\ internal
*/
2019-02-03 21:04:48 +08:00
JKQTP_LIB_EXPORT int * JKQTPImagePlot_getCreateLUT ( QList < int * > & lutstore , JKQTPMathImageColorPalette palette ) ;
2019-01-13 01:53:16 +08:00
/*! \brief frees a list of LUTs
\ ingroup jkqtplotter_imagelots_tools
2019-02-08 00:24:46 +08:00
\ internal
*/
2019-02-03 21:04:48 +08:00
void JKQTP_LIB_EXPORT JKQTPImagePlot_freeLUTs ( QList < int * > & lutstore ) ;
2015-07-11 18:56:02 +08:00
2019-01-13 01:53:16 +08:00
/*! \brief internal global storage object for lookup-tables
\ ingroup jkqtplotter_imagelots_tools
2019-02-08 00:24:46 +08:00
\ internal
*/
2019-02-03 21:04:48 +08:00
extern JKQTP_LIB_EXPORT QList < int * > global_jkqtpimagetools_lutstore ;
2015-07-11 18:56:02 +08:00
/*! \brief convert a 2D image (as 1D array) into a QImage with given palette (see JKQTFPColorPalette)
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
This method uses lookup tables which are saved as static variables to convert the 2 D array into
an image . The luts are only created once , and stored then , so mor CPU time is saved . The precompiler define
2019-02-08 00:24:46 +08:00
JKQTPImageTools : : LUTSIZE sets the size of the LUTs . Note that if you don ' t use a specific color palette ,
2015-07-11 18:56:02 +08:00
the according LUT won ' t be calculated and stored !
2019-01-13 01:53:16 +08:00
\ param dbl_in pointer to a 1 D array of template type \ c T representing the image to plot . This array has to be of size \ a width * \ a height
2015-07-11 18:56:02 +08:00
\ param width width of the array in \ a dbl
\ param height height of the array in \ a dbl
2019-05-18 02:46:52 +08:00
\ param [ out ] img the QImage object to draw to ( should be initialized as \ c QImage : : Format_ARGB32 )
2015-07-11 18:56:02 +08:00
\ param palette the color palette to use for the display
\ param minColor lower boundary of color range in \ a dbl pixels , if \ a minColor = = \ a maxColor then this function will extract the image min and image max .
\ param maxColor upper boundary of color range in \ a dbl pixels , if \ a minColor = = \ a maxColor then this function will extract the image min and image max .
\ param paletteMinFail specifies what shell happen , when a value in \ a dbl is below \ a minColor
\ param paletteMaxFail specifies what shell happen , when a value in \ a dbl is above \ a maxColor
\ param minFailColor color to use for pixels that are below \ a minColor for some settings of \ a paletteMinFail
\ param maxFailColor color to use for pixels that are below \ a maxColor for some settings of \ a paletteMaxFail
\ param nanColor color to use for pixels that are not - a - number
\ param infColor color to use for pixels that are infinity
2019-05-18 02:46:52 +08:00
\ param logScale create a log - scaled image
\ param logBase base for the logarithm used when \ c logScale = = true
\ param lutUser user define LUT
\ param lutUserSize size of the LUT in lutUser
2015-07-11 18:56:02 +08:00
*/
template < class T >
2019-01-26 20:00:40 +08:00
inline void JKQTPImagePlot_array2image ( const T * dbl_in , int width , int height , QImage & img , JKQTPMathImageColorPalette palette , double minColor , double maxColor , JKQTPMathImageColorRangeFailAction paletteMinFail = JKQTPMathImageLastPaletteColor , JKQTPMathImageColorRangeFailAction paletteMaxFail = JKQTPMathImageLastPaletteColor , QColor minFailColor = QColor ( " black " ) , QColor maxFailColor = QColor ( " black " ) , QColor nanColor = QColor ( " black " ) , QColor infColor = QColor ( " black " ) , bool logScale = false , double logBase = 10.0 , const int * lutUser = 0 , int lutUserSize = 0 )
2015-07-11 18:56:02 +08:00
{
if ( ! dbl_in | | width < = 0 | | height < = 0 )
return ;
double min = * dbl_in ;
double max = * dbl_in ;
if ( minColor = = maxColor ) {
bool first = true ;
for ( int i = 1 ; i < width * height ; + + i )
{
2018-12-16 21:59:39 +08:00
T v = dbl_in [ i ] ;
2018-12-06 01:33:32 +08:00
if ( ! ( std : : isnan ( static_cast < long double > ( v ) ) | | std : : isinf ( static_cast < long double > ( v ) ) ) ) {
2015-07-11 18:56:02 +08:00
if ( first ) {
min = max = v ;
first = false ;
} else {
if ( v < min )
min = v ;
else if ( v > max )
max = v ;
}
}
}
} else {
min = minColor ;
max = maxColor ;
}
2018-12-16 21:59:39 +08:00
const T * dbl = dbl_in ;
T * dbl1 = nullptr ;
2015-07-11 18:56:02 +08:00
if ( logScale ) {
double logB = log10 ( logBase ) ;
2018-12-16 21:59:39 +08:00
dbl1 = ( T * ) malloc ( width * height * sizeof ( T ) ) ;
2015-07-11 18:56:02 +08:00
//memcpy(dbl, dbl_in, width*height*sizeof(T));
for ( int i = 0 ; i < width * height ; i + + ) {
2018-12-16 21:59:39 +08:00
dbl1 [ i ] = log10 ( dbl_in [ i ] ) / logB ;
2015-07-11 18:56:02 +08:00
}
2018-12-16 21:59:39 +08:00
dbl = dbl1 ;
2015-07-11 18:56:02 +08:00
min = log10 ( min ) / logB ;
max = log10 ( max ) / logB ;
}
double delta = max - min ;
2018-12-16 21:59:39 +08:00
const int * lut_used = nullptr ;
2019-02-08 00:24:46 +08:00
int lutSize = JKQTPImageTools : : LUTSIZE ;
2019-01-20 17:49:29 +08:00
if ( global_jkqtpimagetools_lutstore . size ( ) < = 0 ) global_jkqtpimagetools_lutstore = JKQTPImagePlot_makeQList < int * > ( nullptr , JKQTPImagePlot_getPredefinedPalettes ( ) . size ( ) + 2 ) ;
2015-07-11 18:56:02 +08:00
img = QImage ( width , height , QImage : : Format_ARGB32 ) ;
if ( min = = max )
img . fill ( 0 ) ;
else
{
if ( palette = = JKQTPMathImageUSER_PALETTE ) {
lut_used = lutUser ;
lutSize = lutUserSize ;
//qDebug()<<"user palette "<<lutUser<<lutUserSize;
} else {
2019-01-20 17:49:29 +08:00
lut_used = JKQTPImagePlot_getCreateLUT ( global_jkqtpimagetools_lutstore , palette ) ;
2015-07-11 18:56:02 +08:00
}
2018-11-18 18:59:30 +08:00
if ( lut_used ! = nullptr & & lutSize > 0 ) {
2018-12-16 21:59:39 +08:00
const unsigned int * lut_usedui = reinterpret_cast < const unsigned int * > ( lut_used ) ;
2015-07-11 18:56:02 +08:00
// LUT found: collor the image accordingly
2018-12-16 21:59:39 +08:00
for ( int j = 0 ; j < height ; + + j ) {
QRgb * line = reinterpret_cast < QRgb * > ( img . scanLine ( height - 1 - j ) ) ;
for ( int i = 0 ; i < width ; + + i ) {
double val = dbl [ j * width + i ] ;
2015-07-11 18:56:02 +08:00
if ( std : : isnan ( val ) ) {
line [ i ] = nanColor . rgba ( ) ;
} else if ( std : : isinf ( val ) ) {
line [ i ] = infColor . rgba ( ) ;
} else {
2018-12-16 21:59:39 +08:00
const int v = static_cast < int > ( ( val - min ) / delta * static_cast < double > ( lutSize ) ) ;
const int vv = ( v < 0 ) ? 0 : ( ( v > lutSize ) ? ( lutSize ) : v ) ;
line [ i ] = lut_usedui [ vv ] ;
2015-07-11 18:56:02 +08:00
if ( ( v < 0 ) & & ( paletteMinFail = = JKQTPMathImageGivenColor ) ) {
line [ i ] = minFailColor . rgba ( ) ;
} else if ( ( v > lutSize ) & & ( paletteMaxFail = = JKQTPMathImageGivenColor ) ) {
line [ i ] = maxFailColor . rgba ( ) ;
} else if ( ( v < 0 ) & & ( paletteMinFail = = JKQTPMathImageTransparent ) ) {
line [ i ] = QColor ( Qt : : transparent ) . rgba ( ) ;
} else if ( ( v > lutSize ) & & ( paletteMaxFail = = JKQTPMathImageTransparent ) ) {
line [ i ] = QColor ( Qt : : transparent ) . rgba ( ) ;
}
}
}
}
} else {
// no LUT found: paint a black image!
img . fill ( 0 ) ;
}
}
2018-12-16 21:59:39 +08:00
if ( dbl1 ) free ( dbl1 ) ;
2015-07-11 18:56:02 +08:00
} ;
2019-01-13 01:53:16 +08:00
/*! \brief convert a 2D image (as 1D array) into a QImage with given palette (see JKQTFPColorPalette)
\ ingroup jkqtplotter_imagelots_tools
This method uses lookup tables which are saved as static variables to convert the 2 D array into
an image . The luts are only created once , and stored then , so mor CPU time is saved . The precompiler define
2019-02-08 00:24:46 +08:00
JKQTPImageTools : : LUTSIZE sets the size of the LUTs . Note that if you don ' t use a specific color palette ,
2019-01-13 01:53:16 +08:00
the according LUT won ' t be calculated and stored !
\ param dbl_in pointer to a 1 D array of template type \ c T representing the image to plot . This array has to be of size \ a width * \ a height
\ param width width of the array in \ a dbl
\ param height height of the array in \ a dbl
\ param [ out ] im the QImage object to draw to ( should be initialized as \ c QImage : : Format_ARGB32 )
\ param lutUser user - defined lookup - table
2019-02-08 00:24:46 +08:00
\ param lutUserSize number of entries in \ a lutUser
2019-01-13 01:53:16 +08:00
\ param minColor lower boundary of color range in \ a dbl pixels , if \ a minColor = = \ a maxColor then this function will extract the image min and image max .
\ param maxColor upper boundary of color range in \ a dbl pixels , if \ a minColor = = \ a maxColor then this function will extract the image min and image max .
\ param paletteMinFail specifies what shell happen , when a value in \ a dbl is below \ a minColor
\ param paletteMaxFail specifies what shell happen , when a value in \ a dbl is above \ a maxColor
\ param minFailColor color to use for pixels that are below \ a minColor for some settings of \ a paletteMinFail
\ param maxFailColor color to use for pixels that are below \ a maxColor for some settings of \ a paletteMaxFail
\ param nanColor color to use for pixels that are not - a - number
\ param infColor color to use for pixels that are infinity
2019-05-18 02:46:52 +08:00
\ param logScale create a log - scaled image
\ param logBase base for the logarithm used when \ c logScale = = true
2019-01-13 01:53:16 +08:00
*/
2015-07-11 18:56:02 +08:00
template < class T >
2019-01-26 20:00:40 +08:00
inline void JKQTPImagePlot_array2image ( const T * dbl_in , int width , int height , QImage & img , const int * lutUser , int lutUserSize , double minColor , double maxColor , JKQTPMathImageColorRangeFailAction paletteMinFail = JKQTPMathImageLastPaletteColor , JKQTPMathImageColorRangeFailAction paletteMaxFail = JKQTPMathImageLastPaletteColor , QColor minFailColor = QColor ( " black " ) , QColor maxFailColor = QColor ( " black " ) , QColor nanColor = QColor ( " black " ) , QColor infColor = QColor ( " black " ) , bool logScale = false , double logBase = 10.0 )
2015-07-11 18:56:02 +08:00
{
2019-01-20 17:49:29 +08:00
JKQTPImagePlot_array2image ( dbl_in , width , height , img , JKQTPMathImageUSER_PALETTE , minColor , maxColor , paletteMinFail , paletteMaxFail , minFailColor , maxFailColor , nanColor , infColor , logScale , logBase , lutUser , lutUserSize ) ;
2015-07-11 18:56:02 +08:00
}
2019-01-20 17:49:29 +08:00
/*! \brief generates a QImage with width \a width and height 1 for the i-th color palette (\a i is based on the list returned by JKQTPImagePlot_getPredefinedPalettes() )
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools */
2019-02-03 21:04:48 +08:00
QImage JKQTP_LIB_EXPORT JKQTPMathImageGetPaletteImage ( int i , int width ) ;
2019-01-20 17:49:29 +08:00
/*! \brief generates a QImage with width \a width and height \a height for the i-th color palette (\a i is based on the list returned by JKQTPImagePlot_getPredefinedPalettes() )
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools */
2019-02-03 21:04:48 +08:00
QImage JKQTP_LIB_EXPORT JKQTPMathImageGetPaletteImage ( int i , int width , int height ) ;
2019-01-13 01:53:16 +08:00
/*! \brief generates a QImage with width \a width and height 1 for a specific JKQTPMathImageColorPalette
\ ingroup jkqtplotter_imagelots_tools */
2019-02-03 21:04:48 +08:00
QImage JKQTP_LIB_EXPORT JKQTPMathImageGetPaletteImage ( JKQTPMathImageColorPalette palette , int width ) ;
2019-01-13 01:53:16 +08:00
/*! \brief generates a QImage with width \a width and height \a height for a specific JKQTPMathImageColorPalette
\ ingroup jkqtplotter_imagelots_tools */
2019-02-03 21:04:48 +08:00
QImage JKQTP_LIB_EXPORT JKQTPMathImageGetPaletteImage ( JKQTPMathImageColorPalette palette , int width , int height ) ;
2019-01-13 01:53:16 +08:00
/*! \brief generates a QImage with width \a width and height 1 for a lookup-table \a lut with \a lut_size entries
\ ingroup jkqtplotter_imagelots_tools */
2019-02-03 21:04:48 +08:00
QImage JKQTP_LIB_EXPORT JKQTPMathImageGetPaletteImage ( int * lut , int lut_size , int width ) ;
2019-01-13 01:53:16 +08:00
/*! \brief generates a QImage with width \a width and height \a height for a lookup-table \a lut with \a lut_size entries
\ ingroup jkqtplotter_imagelots_tools */
2019-02-03 21:04:48 +08:00
QImage JKQTP_LIB_EXPORT JKQTPMathImageGetAlphaPaletteImage ( int * lut , int lut_size , int width , int height ) ;
2015-07-11 18:56:02 +08:00
2019-01-20 17:49:29 +08:00
/*! \brief generates a QIcon for the i-th color palette (\a i is based on the list returned by JKQTPImagePlot_getPredefinedPalettes() )
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools */
2019-02-03 21:04:48 +08:00
QIcon JKQTP_LIB_EXPORT JKQTPMathImageGetPaletteIcon ( int i ) ;
2015-07-11 18:56:02 +08:00
2019-01-13 01:53:16 +08:00
/*! \brief generates a QIcon for a specific JKQTPMathImageColorPalette
\ ingroup jkqtplotter_imagelots_tools */
2019-02-03 21:04:48 +08:00
QIcon JKQTP_LIB_EXPORT JKQTPMathImageGetPaletteIcon ( JKQTPMathImageColorPalette palette ) ;
2015-07-11 18:56:02 +08:00
# ifndef NO_JKQTPLOTTER
/*! \brief if a class is derived from this class, it may use color bars
2019-01-13 01:53:16 +08:00
\ ingroup jkqtplotter_imagelots_tools
2015-07-11 18:56:02 +08:00
*/
2019-02-03 21:04:48 +08:00
class JKQTP_LIB_EXPORT JKQTPColorPaletteTools {
2015-07-11 18:56:02 +08:00
public :
2019-01-20 17:49:29 +08:00
JKQTPColorPaletteTools ( JKQTBasePlotter * parent ) ;
2015-07-11 18:56:02 +08:00
virtual ~ JKQTPColorPaletteTools ( ) ;
/*! \brief get list with all available palettes */
static QStringList getPalettes ( ) ;
/*! \brief get list with all available palettes */
static int getPalettesCount ( ) ;
/*! \brief get QIcon representing the given palette */
static QIcon getPaletteIcon ( int i ) ;
/*! \brief get QIcon representing the given palette */
static QIcon getPaletteIcon ( JKQTPMathImageColorPalette palette ) ;
/*! \brief get QIcon representing the given palette */
static QImage getPaletteImage ( int i , int width ) ;
/*! \brief get QIcon representing the given palette */
static QImage getPaletteImage ( JKQTPMathImageColorPalette palette , int width ) ;
/*! \brief get QIcon representing the given palette */
static QIcon getPaletteKeyIcon ( int i ) ;
/*! \brief get QIcon representing the given palette */
static QIcon getPaletteKeyIcon ( JKQTPMathImageColorPalette palette ) ;
/*! \brief get QIcon representing the given palette */
static QImage getPaletteKeyImage ( int i , int width , int height ) ;
/*! \brief get QIcon representing the given palette */
static QImage getPaletteKeyImage ( JKQTPMathImageColorPalette palette , int width , int height ) ;
2019-01-26 20:00:40 +08:00
void setPalette ( int pal ) ;
2015-07-11 18:56:02 +08:00
/*! \brief if the graph plots outside the actual plot field of view (e.g. color bars, scale bars, ...)
\ note If you want to draw outside , then you ' ll also have to implement drawOutside ( )
*/
void cbGetOutsideSize ( JKQTPEnhancedPainter & painter , int & leftSpace , int & rightSpace , int & topSpace , int & bottomSpace ) ;
/*! \brief plots outside the actual plot field of view (e.g. color bars, scale bars, ...)
\ note If you want to draw outside , then you ' ll also have to implement getOutsideSize ( ) , so enough space is reserved
The four value supplied tell the method where to draw ( inside one of the rectangles ) .
*/
void cbDrawOutside ( JKQTPEnhancedPainter & painter , QRect leftSpace , QRect rightSpace , QRect topSpace , QRect bottomSpace ) ;
2019-01-20 17:49:29 +08:00
void cbSetParent ( JKQTBasePlotter * parent ) ;
2015-07-11 18:56:02 +08:00
/** \brief determine min/max data value of the image */
virtual void cbGetDataMinMax ( double & imin , double & imax ) = 0 ;
virtual double getInternalDataMin ( ) const ;
virtual double getInternalDataMax ( ) const ;
protected :
2019-01-20 17:49:29 +08:00
JKQTBasePlotter * cbParent ;
2015-07-11 18:56:02 +08:00
/** \brief top color bar visible */
bool colorBarTopVisible ;
/** \brief right color bar visible */
bool colorBarRightVisible ;
/** \brief name of the image displayed above color bar (may contain LaTeX markup!) */
QString imageName ;
/** \brief font name when displaying imageName */
QString imageNameFontName ;
/** \brief font size in points when displaying imageName */
double imageNameFontSize ;
/** \brief palette for plotting an image */
JKQTPMathImageColorPalette palette ;
/** \brief indicate whether to display a color bar */
bool showColorBar ;
/** \brief width of the color bar */
int colorBarWidth ;
/** \brief height of the color bar, as multiple of plotHeight */
double colorBarRelativeHeight ;
/** \brief indicates whether to estimate min/max of the image automatically */
bool autoImageRange ;
/** \brief image value range minimum */
double imageMin ;
/** \brief image value range maximum */
double imageMax ;
/** \brief offset between outside space border and color bar */
int colorBarOffset ;
/** \brief which action to take if a color is below \a imageMin and \a autoImageRange \c ==false */
JKQTPMathImageColorRangeFailAction rangeMinFailAction ;
/** \brief which action to take if a color is above \a imageMax and \a autoImageRange \c ==false */
JKQTPMathImageColorRangeFailAction rangeMaxFailAction ;
/** \brief color to use for some settings of \a rangeMinFailAction */
QColor rangeMinFailColor ;
/** \brief color to use for some settings of \a rangeMaxFailAction */
QColor rangeMaxFailColor ;
/** \brief color to use for a not-a-number value */
QColor nanColor ;
/** \brief color to use for an infinity value */
QColor infColor ;
/** \brief object used for color bar axes
*
* \ note this axis has some kind of a special role . It is used to format color bar axes
*/
2019-01-20 17:49:29 +08:00
JKQTPVerticalIndependentAxis * colorBarRightAxis ;
JKQTPHorizontalIndependentAxis * colorBarTopAxis ;
2015-07-11 18:56:02 +08:00
public :
2019-05-19 04:41:38 +08:00
/*! \copydoc palette */
2019-01-26 20:00:40 +08:00
inline virtual void setPalette ( const JKQTPMathImageColorPalette & __value )
2019-01-10 04:23:24 +08:00
{
this - > palette = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc palette */
2019-01-26 20:00:40 +08:00
inline virtual JKQTPMathImageColorPalette getPalette ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > palette ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc rangeMinFailAction */
2019-01-26 20:00:40 +08:00
inline virtual void setRangeMinFailAction ( const JKQTPMathImageColorRangeFailAction & __value )
2019-01-10 04:23:24 +08:00
{
this - > rangeMinFailAction = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc rangeMinFailAction */
2019-01-26 20:00:40 +08:00
inline virtual JKQTPMathImageColorRangeFailAction getActionRangeMinFail ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > rangeMinFailAction ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc rangeMaxFailAction */
2019-01-26 20:00:40 +08:00
inline virtual void setRangeMaxFailAction ( const JKQTPMathImageColorRangeFailAction & __value )
2019-01-10 04:23:24 +08:00
{
this - > rangeMaxFailAction = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc rangeMaxFailAction */
2019-01-26 20:00:40 +08:00
inline virtual JKQTPMathImageColorRangeFailAction getActionRangeMaxFail ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > rangeMaxFailAction ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc rangeMinFailColor */
2019-01-26 20:00:40 +08:00
inline virtual void setRangeMinFailColor ( const QColor & __value )
2019-01-10 04:23:24 +08:00
{
this - > rangeMinFailColor = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc rangeMinFailColor */
2019-01-26 20:00:40 +08:00
inline virtual QColor getRangeMinFailColor ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > rangeMinFailColor ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc rangeMaxFailColor */
2019-01-26 20:00:40 +08:00
inline virtual void setRangeMaxFailColor ( const QColor & __value )
2019-01-10 04:23:24 +08:00
{
this - > rangeMaxFailColor = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc rangeMaxFailColor */
2019-01-26 20:00:40 +08:00
inline virtual QColor getRangeMaxFailColor ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > rangeMaxFailColor ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc nanColor */
2019-01-26 20:00:40 +08:00
inline virtual void setNanColor ( const QColor & __value )
2019-01-10 04:23:24 +08:00
{
this - > nanColor = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc nanColor */
2019-01-26 20:00:40 +08:00
inline virtual QColor getNanColor ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > nanColor ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc infColor */
2019-01-26 20:00:40 +08:00
inline virtual void setInfColor ( const QColor & __value )
2019-01-10 04:23:24 +08:00
{
this - > infColor = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc infColor */
2019-01-26 20:00:40 +08:00
inline virtual QColor getInfColor ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > infColor ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc showColorBar */
2019-01-26 03:16:04 +08:00
inline virtual void setShowColorBar ( bool __value )
2019-01-10 04:23:24 +08:00
{
this - > showColorBar = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc showColorBar */
2019-01-26 03:16:04 +08:00
inline virtual bool getShowColorBar ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > showColorBar ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarWidth */
2019-01-26 20:00:40 +08:00
inline virtual void setColorBarWidth ( int __value )
2019-01-10 04:23:24 +08:00
{
this - > colorBarWidth = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarWidth */
2019-01-26 20:00:40 +08:00
inline virtual int getColorBarWidth ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > colorBarWidth ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarOffset */
2019-01-26 20:00:40 +08:00
inline virtual void setColorBarOffset ( int __value )
2019-01-10 04:23:24 +08:00
{
this - > colorBarOffset = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarOffset */
2019-01-26 20:00:40 +08:00
inline virtual int getColorBarOffset ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > colorBarOffset ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarRelativeHeight */
2019-01-26 20:00:40 +08:00
inline virtual void setColorBarRelativeHeight ( double __value )
2019-01-10 04:23:24 +08:00
{
this - > colorBarRelativeHeight = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarRelativeHeight */
2019-01-26 20:00:40 +08:00
inline virtual double getColorBarRelativeHeight ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > colorBarRelativeHeight ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageMin */
2019-01-26 20:00:40 +08:00
inline virtual void setImageMin ( double __value )
2019-01-10 04:23:24 +08:00
{
this - > imageMin = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageMin */
2019-01-26 20:00:40 +08:00
inline virtual double getImageMin ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > imageMin ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageMax */
2019-01-26 20:00:40 +08:00
inline virtual void setImageMax ( double __value )
2019-01-10 04:23:24 +08:00
{
this - > imageMax = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageMax */
2019-01-26 20:00:40 +08:00
inline virtual double getImageMax ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > imageMax ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc autoImageRange */
2019-01-26 20:00:40 +08:00
inline virtual void setAutoImageRange ( bool __value )
2019-01-10 04:23:24 +08:00
{
this - > autoImageRange = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc autoImageRange */
2019-01-26 20:00:40 +08:00
inline virtual bool getAutoImageRange ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > autoImageRange ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageName */
2019-01-26 20:00:40 +08:00
inline virtual void setImageName ( const QString & __value )
2019-01-10 04:23:24 +08:00
{
this - > imageName = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageName */
2019-01-26 20:00:40 +08:00
inline virtual QString getImageName ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > imageName ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageNameFontName */
2019-01-26 20:00:40 +08:00
inline virtual void setImageNameFontName ( const QString & __value )
2019-01-10 04:23:24 +08:00
{
this - > imageNameFontName = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageNameFontName */
2019-01-26 20:00:40 +08:00
inline virtual QString getImageNameFontName ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > imageNameFontName ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageNameFontSize */
2019-01-26 20:00:40 +08:00
inline virtual void setImageNameFontSize ( double __value )
2019-01-10 04:23:24 +08:00
{
this - > imageNameFontSize = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc imageNameFontSize */
2019-01-26 20:00:40 +08:00
inline virtual double getImageNameFontSize ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > imageNameFontSize ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarRightAxis */
2019-02-08 00:24:46 +08:00
inline JKQTPVerticalIndependentAxis * getColorBarRightAxis ( ) {
2019-01-10 04:23:24 +08:00
return this - > colorBarRightAxis ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarTopAxis */
2019-02-08 00:24:46 +08:00
inline JKQTPHorizontalIndependentAxis * getColorBarTopAxis ( ) {
2019-01-10 04:23:24 +08:00
return this - > colorBarTopAxis ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarRightAxis */
2019-02-08 00:24:46 +08:00
inline const JKQTPVerticalIndependentAxis * getColorBarRightAxis ( ) const {
return this - > colorBarRightAxis ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarTopAxis */
2019-02-08 00:24:46 +08:00
inline const JKQTPHorizontalIndependentAxis * getColorBarTopAxis ( ) const {
return this - > colorBarTopAxis ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarTopVisible */
2019-01-26 20:00:40 +08:00
inline virtual void setColorBarTopVisible ( bool __value )
2019-01-10 04:23:24 +08:00
{
this - > colorBarTopVisible = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarTopVisible */
2019-01-26 20:00:40 +08:00
inline virtual bool getColorBarTopVisible ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > colorBarTopVisible ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarRightVisible */
2019-01-26 20:00:40 +08:00
inline virtual void setColorBarRightVisible ( bool __value )
2019-01-10 04:23:24 +08:00
{
this - > colorBarRightVisible = __value ;
}
2019-05-19 04:41:38 +08:00
/*! \copydoc colorBarRightVisible */
2019-01-26 20:00:40 +08:00
inline virtual bool getColorBarRightVisible ( ) const
2019-01-10 04:23:24 +08:00
{
return this - > colorBarRightVisible ;
}
2015-07-11 18:56:02 +08:00
} ;
# endif
# endif // JKQTPIMAGETOOLS_H