21#ifndef JKQTPBASICIMAGETOOLS_H
22#define JKQTPBASICIMAGETOOLS_H
31#include <QReadWriteLock>
34#include "jkqtcommon/jkqtcommon_imexport.h"
35#include "jkqtcommon/jkqtpmathtools.h"
36#include "jkqtcommon/jkqttools.h"
60 case 0:
return qRed(rgb);
61 case 1:
return qGreen(rgb);
62 case 2:
return qBlue(rgb);
63 case 3:
return qAlpha(rgb);
74 case 0: rgb= qRgba(val, qGreen(rgb), qBlue(rgb), qAlpha(rgb));
break;
75 case 1: rgb= qRgba(qRed(rgb), val, qBlue(rgb), qAlpha(rgb));
break;
76 case 2: rgb= qRgba(qRed(rgb), qGreen(rgb), val, qAlpha(rgb));
break;
77 case 3: rgb= qRgba(qRed(rgb), qGreen(rgb), qBlue(rgb), val);
break;
482 static inline void 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 LUTType& lutUser=
LUTType())
484 if (!dbl_in || width<=0 || height<=0)
487 const int NPixels= jkqtp_bounded<int>(width*height);
488 double min = *dbl_in;
489 double max = *dbl_in;
492 for (
int i=1; i<NPixels; ++i)
495 if (!(std::isnan(
static_cast<long double>(v)) || std::isinf(
static_cast<long double>(v)))) {
516 double logB=log10(logBase);
517 dbl1=QVector<T>(jkqtp_bounded<int>(NPixels), 0);
518 for (
int i=0; i<NPixels; i++) {
519 dbl1[i]=log10(dbl_in[i])/logB;
525 double delta=max-min;
531 img = QImage(width, height, QImage::Format_ARGB32);
533 img.fill(lut_used[0]);
535 const int lutSize=lut_used.size();
538 for (
int j=0; j<height; ++j) {
539 QRgb* line=
reinterpret_cast<QRgb*
>(img.scanLine(height-1-j));
540 for (
int i=0; i<width; ++i) {
541 double val=dbl[j*width+i];
542 if (std::isnan(val)) {
543 line[i]=nanColor.rgba();
544 }
else if (std::isinf(val)) {
545 line[i]=infColor.rgba();
547 const int v =
static_cast<int>((val-min)/delta*
static_cast<double>(lutSize));
548 const int vv = qBound<int>(0, v, lutSize-1);
549 line[i]=lut_used[vv];
551 line[i]=minFailColor.rgba();
553 line[i]=maxFailColor.rgba();
555 line[i]=QColor(Qt::transparent).rgba();
557 line[i]=QColor(Qt::transparent).rgba();
589 static inline void array2image(
const T* dbl_in,
int width,
int height, QImage &img,
const LUTType& lutUser,
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)
591 array2image(dbl_in, width, height, img,
JKQTPMathImageUSER_PALETTE, minColor, maxColor, paletteMinFail, paletteMaxFail, minFailColor, maxFailColor, nanColor, infColor, logScale, logBase, lutUser);
647 LUTData(
const QString& _lut,
const QString& _name,
const QString& _nameT);
648 LUTData(
const QString& _name,
const QString& _nameT);
719 if (!input || N<=0)
return QVector<double>();
720 QVector<double> out(N, 0.0);
721 for (
int i=0; i<N; i++) {
732 if (!input || N<=0)
return QVector<double>();
733 QVector<double> out(N, 0.0);
734 for (
int i=0; i<N; i++) {
735 if (input[i]) out[i]=1.0;
747 if (!dbl || width<=0 || height<=0)
753 for (
int i=1; i<width*height; ++i)
756 if (!(std::isnan(
static_cast<long double>(v)) || std::isinf(
static_cast<long double>(v)))) {
778 if (!dbl || width<=0 || height<=0)
784 for (
int i=1; i<width*height; ++i)
787 if (!(std::isnan(
static_cast<long double>(v)) || std::isinf(
static_cast<long double>(v)))) {
821 if (!dbl_in || width<=0 || height<=0)
824 double min = *dbl_in;
825 double max = *dbl_in;
828 for (
int i=1; i<width*height; ++i)
831 if (std::isfinite(
static_cast<long double>(v))) {
852 double logB=log10(logBase);
853 dbllog.resize(
static_cast<size_t>(width)*
static_cast<size_t>(height));
855 for (
int i=0; i<width*height; i++) {
856 dbllog[i]=log10(dbl_in[i])/logB;
862 double delta=max-min;
868 for (
int j=0; j<height; ++j) {
869 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
870 for (
int i=0; i<width; ++i) {
871 int v = trunc(
double(dbl[j*width+i]-min)*255.0/delta);
872 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
873 const QRgb l=line[i];
875 line[i]=qRgb(v,qGreen(l),qBlue(l));
878 }
else if (channel==1) {
879 for (
int j=0; j<height; ++j) {
880 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
881 for (
int i=0; i<width; ++i) {
882 int v = (dbl[j*width+i]-min)*255/delta;
883 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
884 const QRgb l=line[i];
886 line[i]=qRgb(qRed(l),v,qBlue(l));
889 }
else if (channel==2) {
890 for (
int j=0; j<height; ++j) {
891 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
892 for (
int i=0; i<width; ++i) {
893 int v = (dbl[j*width+i]-min)*255/delta;
894 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
895 const QRgb l=line[i];
897 line[i]=qRgb(qRed(l),qGreen(l),v);
900 }
else if (channel==3) {
901 for (
int j=0; j<height; ++j) {
902 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
903 for (
int i=0; i<width; ++i) {
904 int v = (dbl[j*width+i]-min)*255/delta;
905 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
906 const QRgb l=line[i];
908 line[i]=qRgba(qRed(l),qGreen(l),qBlue(l), v);
915 for (
int j=0; j<height; ++j) {
916 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
917 for (
int i=0; i<width; ++i) {
918 int v = trunc(
double(dbl[j*width+i]-min)*255.0/delta);
919 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
920 const QRgb l=line[i];
922 line[i]=QColor::fromCmyk(v,QColor(l).magenta(),QColor(l).yellow(),QColor(l).black()).rgba();
925 }
else if (channel==1) {
926 for (
int j=0; j<height; ++j) {
927 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
928 for (
int i=0; i<width; ++i) {
929 int v = (dbl[j*width+i]-min)*255/delta;
930 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
931 const QRgb l=line[i];
933 line[i]=QColor::fromCmyk(QColor(l).cyan(),v,QColor(l).yellow(),QColor(l).black()).rgba();
936 }
else if (channel==2) {
937 for (
int j=0; j<height; ++j) {
938 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
939 for (
int i=0; i<width; ++i) {
940 int v = (dbl[j*width+i]-min)*255/delta;
941 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
942 const QRgb l=line[i];
944 line[i]=QColor::fromCmyk(QColor(l).cyan(),QColor(l).magenta(),v,QColor(l).black()).rgba();
950 for (
int j=0; j<height; ++j) {
951 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
952 for (
int i=0; i<width; ++i) {
953 int v = trunc(
double(dbl[j*width+i]-min)*220.0/delta);
954 v = (v < 0) ? 0 : ( (v > 360) ? 360 : v);
955 QColor l=QColor::fromRgb(line[i]);
957 l.setHsv(v, l.saturation(), l.value());
962 }
else if (channel==1) {
963 for (
int j=0; j<height; ++j) {
964 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
965 for (
int i=0; i<width; ++i) {
966 int v = (dbl[j*width+i]-min)*255/delta;
967 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
968 QColor l=QColor::fromRgb(line[i]);
970 l.setHsv(l.hue(), v, l.value());
975 }
else if (channel==2) {
976 for (
int j=0; j<height; ++j) {
977 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
978 for (
int i=0; i<width; ++i) {
979 int v = (dbl[j*width+i]-min)*255/delta;
980 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
981 QColor l=QColor::fromRgb(line[i]);
983 l.setHsv(l.hue(), l.saturation(), v);
992 for (
int j=0; j<height; ++j) {
993 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
994 for (
int i=0; i<width; ++i) {
995 int v = trunc(
double(dbl[j*width+i]-min)*255.0/delta);
996 v = (v < 0) ? 0 : ( (v > 360) ? 360 : v);
998 l.setHsl(v, l.saturation(), l.lightness());
1002 }
else if (channel==1) {
1003 for (
int j=0; j<height; ++j) {
1004 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
1005 for (
int i=0; i<width; ++i) {
1006 int v = (dbl[j*width+i]-min)*255/delta;
1007 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
1009 l.setHsl(l.hue(), v, l.lightness());
1013 }
else if (channel==2) {
1014 for (
int j=0; j<height; ++j) {
1015 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
1016 for (
int i=0; i<width; ++i) {
1017 int v = (dbl[j*width+i]-min)*255/delta;
1018 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
1020 l.setHsl(l.hue(), l.saturation(), v);
1028 for (
int j=0; j<height; ++j) {
1029 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
1030 for (
int i=0; i<width; ++i) {
1031 int v = (dbl[j*width+i]-min)*255/delta;
1032 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
1033 const QRgb l=line[i];
1034 line[i]=qRgba(qRed(l),qGreen(l),qBlue(l),v);
1037 }
else if (channel==4) {
1038 for (
int j=0; j<height; ++j) {
1039 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
1040 for (
int i=0; i<width; ++i) {
1041 int v = (dbl[j*width+i]-min)*255/delta;
1042 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
1043 QColor c=QColor::fromRgba(line[i]);
1044 c.setHsv(c.hue(), v, c.value(), c.alpha());
1048 }
else if (channel==5) {
1049 for (
int j=0; j<height; ++j) {
1050 QRgb* line=
reinterpret_cast<QRgb *
>(img.scanLine(height-1-j));
1051 for (
int i=0; i<width; ++i) {
1052 int v = (dbl[j*width+i]-min)*255/delta;
1053 v = (v < 0) ? 0 : ( (v > 255) ? 255 : v);
1054 QColor c=QColor::fromRgba(line[i]);
1055 c.setHsv(c.hue(), c.saturation(), v, c.alpha());
1165 return col | 0xFF000000;
1180#if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
1189 for(
const auto& v: args) {
1196 for(
const auto& v: args) {
1203 for(
const auto& v: args) {
1204 push_back(v.first, v.second);
1207 template <
typename InputIterator, JKQTPIsInputIteratorTrait<InputIterator> = true>
1212 using ListType::push_back;
1214 if (size()==0) push_back(ListType::value_type(0.0, rgb));
1215 else if (size()==1) push_back(ListType::value_type(at(0).first+1.0, rgb));
1217 double mi=0,ma=0, delta=0;
1218 getMinMaxPosition(mi,ma,&delta);
1219 push_back(ListType::value_type(ma+delta, rgb));
1223 push_back(ListType::value_type(pos, rgb));
1225 using ListType::operator<<;
1231 push_back(color.rgb());
1234 push_back(ListType::value_type(pos, color.rgb()));
1242 const auto ma=getMaxPosition();
1243 for (
auto& c: *
this) {
1257 for (
const auto& c: *
this) {
1262 mi=qMin<int>(mi, c.first);
1271 for (
const auto& c: *
this) {
1276 ma=qMax<int>(ma, c.first);
1285 for (
const auto& c: *
this) {
1290 ma=qMax<int>(ma, c.first);
1291 mi=qMin<int>(mi, c.first);
1295 if (size()<=1) *avgDelta=1;
1296 else *avgDelta=(ma-mi)/
static_cast<double>(size()-1);
for building palettes from list of colors and position values, using JKQTPBuildColorPaletteLUTLinInte...
Definition jkqtpbasicimagetools.h:1175
JKQTPPaletteList & operator<<(QColor color)
Definition jkqtpbasicimagetools.h:1236
QList< parameter_type > ListType
Definition jkqtpbasicimagetools.h:1178
JKQTPPaletteList & operator<<(QRgb rgb)
Definition jkqtpbasicimagetools.h:1226
void sort()
sorty by position
Definition jkqtpbasicimagetools.h:1249
double getMinPosition() const
returns the minimum value of the double-component
Definition jkqtpbasicimagetools.h:1254
void push_back(QRgb rgb)
Definition jkqtpbasicimagetools.h:1213
void getMinMaxPosition(double &mi, double &ma, double *avgDelta=nullptr) const
returns the minimum and maximum value of the double-component, as well as the avg....
Definition jkqtpbasicimagetools.h:1282
JKQTPPaletteList(qsizetype size)
Definition jkqtpbasicimagetools.h:1181
double getMaxPosition() const
returns the maximum value of the double-component
Definition jkqtpbasicimagetools.h:1268
JKQTPPaletteList(std::initializer_list< QPair< double, QColor > > args)
Definition jkqtpbasicimagetools.h:1200
JKQTPPaletteList(std::initializer_list< QColor > args)
Definition jkqtpbasicimagetools.h:1193
JKQTPPaletteList(ListType &&other)
Definition jkqtpbasicimagetools.h:1209
JKQTPPaletteList(const ListType &other)
Definition jkqtpbasicimagetools.h:1210
JKQTPPaletteList()
Definition jkqtpbasicimagetools.h:1179
void reverse()
reverse colors
Definition jkqtpbasicimagetools.h:1241
JKQTPPaletteList(std::initializer_list< QPair< double, QRgb > > args)
Definition jkqtpbasicimagetools.h:1185
JKQTPPaletteList(std::initializer_list< QRgb > args)
Definition jkqtpbasicimagetools.h:1186
JKQTPPaletteList(qsizetype size, parameter_type value)
Definition jkqtpbasicimagetools.h:1182
QPair< double, QRgb > parameter_type
Definition jkqtpbasicimagetools.h:1177
void push_back(QColor color)
Definition jkqtpbasicimagetools.h:1230
void push_back(double pos, QRgb rgb)
Definition jkqtpbasicimagetools.h:1222
void push_back(double pos, QColor color)
Definition jkqtpbasicimagetools.h:1233
JKQTPPaletteList(InputIterator first, InputIterator last)
Definition jkqtpbasicimagetools.h:1208
for building palettes from linear segments of single colors using JKQTPBuildColorPaletteLUTLinSegment...
Definition jkqtpbasicimagetools.h:1074
uint8_t colval_startnext
color-channel-value that starts the next segment (ignored for the last entry in a table)
Definition jkqtpbasicimagetools.h:1083
uint8_t colval_endprevious
color-channel-value that ends the prevoius segment (ignored for the first entry in a table)
Definition jkqtpbasicimagetools.h:1081
JKQTPColorPaletteSingleColorLinSegment()
double position
scalar position of the element on the value axis
Definition jkqtpbasicimagetools.h:1079
static JKQTPColorPaletteSingleColorLinSegment makeDbl_0_1(double p, double y1, double y2)
JKQTPColorPaletteSingleColorLinSegment(double p, uint8_t y1, uint8_t y2)