mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 10:01:38 +08:00
f2004a6f66
IMPROVED/REWORKED: legend/key positioning as combination of 3 values, e.g. \c JKQTPKeyOutsideTop|JKQTPKeyTop|JKQTPKeyRight or \c JKQTPKeyInside|JKQTPKeyTopJKQTPKeyRight
1121 lines
42 KiB
C++
1121 lines
42 KiB
C++
/*
|
|
Copyright (c) 2008-2022 Jan W. Krieger (jan@jkrieger.de)
|
|
|
|
|
|
|
|
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
|
|
the Free Software Foundation, either version 2.1 of the License, or
|
|
(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/>.
|
|
*/
|
|
|
|
|
|
#include "jkqtplotter/graphs/jkqtpimage.h"
|
|
#include "jkqtplotter/jkqtpbaseplotter.h"
|
|
#include "jkqtplotter/jkqtpimagetools.h"
|
|
#include "jkqtplotter/jkqtptools.h"
|
|
#include "jkqtcommon/jkqtpenhancedpainter.h"
|
|
#include "jkqtplotter/jkqtplotter.h"
|
|
#include <QDebug>
|
|
#include <QImageWriter>
|
|
#include <QFileDialog>
|
|
#include <QFileInfo>
|
|
#include <QApplication>
|
|
#include <QClipboard>
|
|
|
|
|
|
JKQTPImageBase::JKQTPImageBase(double x, double y, double width, double height, JKQTBasePlotter* parent):
|
|
JKQTPGraph(parent)
|
|
{
|
|
title="";
|
|
this->width=width;
|
|
this->height=height;
|
|
this->x=x;
|
|
this->y=y;
|
|
}
|
|
|
|
JKQTPImageBase::JKQTPImageBase(JKQTBasePlotter *parent):
|
|
JKQTPGraph(parent)
|
|
{
|
|
title="";
|
|
this->width=0;
|
|
this->height=0;
|
|
this->x=0;
|
|
this->y=0;
|
|
}
|
|
|
|
JKQTPImageBase::JKQTPImageBase(double x, double y, double width, double height, JKQTPlotter* parent):
|
|
JKQTPImageBase(x, y, width, height, parent->getPlotter())
|
|
{
|
|
}
|
|
|
|
JKQTPImageBase::JKQTPImageBase(JKQTPlotter *parent):
|
|
JKQTPImageBase(parent->getPlotter())
|
|
{
|
|
}
|
|
|
|
void JKQTPImageBase::drawKeyMarker(JKQTPEnhancedPainter& /*painter*/, const QRectF& /*rect*/) {
|
|
|
|
}
|
|
|
|
bool JKQTPImageBase::getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) {
|
|
minx=x;
|
|
maxx=x+width;
|
|
smallestGreaterZero=0;
|
|
if (x>10.0*DBL_MIN) smallestGreaterZero=x;
|
|
return true;
|
|
}
|
|
|
|
bool JKQTPImageBase::getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) {
|
|
miny=y;
|
|
maxy=y+height;
|
|
smallestGreaterZero=0;
|
|
if (y>10.0*DBL_MIN) smallestGreaterZero=y;
|
|
return true;
|
|
}
|
|
|
|
QColor JKQTPImageBase::getKeyLabelColor() const {
|
|
return QColor("black");
|
|
}
|
|
|
|
void JKQTPImageBase::setX(double __value)
|
|
{
|
|
this->x = __value;
|
|
}
|
|
|
|
double JKQTPImageBase::getX() const
|
|
{
|
|
return this->x;
|
|
}
|
|
|
|
void JKQTPImageBase::setY(double __value)
|
|
{
|
|
this->y = __value;
|
|
}
|
|
|
|
double JKQTPImageBase::getY() const
|
|
{
|
|
return this->y;
|
|
}
|
|
|
|
void JKQTPImageBase::setWidth(double __value)
|
|
{
|
|
this->width = __value;
|
|
}
|
|
|
|
double JKQTPImageBase::getWidth() const
|
|
{
|
|
return this->width;
|
|
}
|
|
|
|
void JKQTPImageBase::setHeight(double __value)
|
|
{
|
|
this->height = __value;
|
|
}
|
|
|
|
double JKQTPImageBase::getHeight() const
|
|
{
|
|
return this->height;
|
|
}
|
|
|
|
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)) {
|
|
return;
|
|
}
|
|
painter.save(); auto __finalpaint=JKQTPFinally([&painter]() {painter.restore();});
|
|
|
|
// determine full shown plot rectangle in pixel coordinates
|
|
const double xmin=parent->getXMin();
|
|
const double xmax=parent->getXMax();
|
|
const double ymin=parent->getYMin();
|
|
const double ymax=parent->getYMax();
|
|
QPointF pix_plot_topleft=transform(xmin,ymax);
|
|
QPointF pix_plot_bottomright=transform(xmax,ymin);
|
|
QRectF pix_plotrectangle(pix_plot_topleft, pix_plot_bottomright);
|
|
|
|
// these flags say, whether to mirror the image in one or the other direction, before plotting
|
|
bool mirrx=false;
|
|
bool mirry=false;
|
|
|
|
// determine pixel coordinates of image (x..x+width / y..y+width)
|
|
QPointF pix_topelft=transform(x,y+height);
|
|
QPointF pix_bottomright=transform(x+width,y);
|
|
if (pix_topelft.x()>pix_bottomright.x()) {
|
|
double tmp=pix_topelft.x();
|
|
pix_topelft.setX(pix_bottomright.x());
|
|
pix_bottomright.setX(tmp);
|
|
tmp=pix_plot_topleft.x();
|
|
pix_plot_topleft.setX(pix_plot_bottomright.x());
|
|
pix_plot_bottomright.setX(tmp);
|
|
mirrx=true;
|
|
}
|
|
if (pix_topelft.y()>pix_bottomright.y()) {
|
|
double tmp=pix_topelft.y();
|
|
pix_topelft.setY(pix_bottomright.y());
|
|
pix_bottomright.setY(tmp);
|
|
tmp=pix_plot_topleft.y();
|
|
pix_plot_topleft.setY(pix_plot_bottomright.y());
|
|
pix_plot_bottomright.setY(tmp);
|
|
mirry=true;
|
|
}
|
|
const QRectF pix_imagerect(pix_topelft, pix_bottomright);
|
|
|
|
|
|
|
|
if (image.width()>0 && image.height()>0 && !image.isNull()) {
|
|
// now we determine, whether to directly draw the image (if its size is smaller than twice the plot rectangle,
|
|
// or not ...
|
|
if (pix_imagerect.width()<2.0*pix_plotrectangle.width() && pix_imagerect.height()<2.0*pix_plotrectangle.height()) {
|
|
//painter.drawImage(QRectF(p1.x(), p2.y(), fabs(p2.x()-p1.x()), fabs(p2.y()-p1.y())), image);
|
|
painter.drawImage(QPointF(pix_topelft.x(), pix_topelft.y()), image.mirrored(mirrx, mirry).scaled(QSize(fabs(pix_bottomright.x()-pix_topelft.x()), fabs(pix_bottomright.y()-pix_topelft.y())), Qt::IgnoreAspectRatio, Qt::FastTransformation));
|
|
//qDebug()<<"\nimage.size = "<<image.size() <<" SIMPLE!";
|
|
} else {
|
|
// ... if the image is much larger than the plot rectangle, we cut a potion from the image, before plotting
|
|
const double pixwidth=fabs(pix_bottomright.x()-pix_topelft.x())/static_cast<double>(image.width());
|
|
const double pixheight=fabs(pix_bottomright.y()-pix_topelft.y())/static_cast<double>(image.height());
|
|
//qDebug()<<"\nimage.size = "<<image.size();
|
|
//qDebug()<<"size = "<<QSizeF(width, height);
|
|
//qDebug()<<"pixsize = "<<QSizeF(pixwidth, pixheight);
|
|
//qDebug()<<"p1 = "<<p1<< " p2 = "<<p2;
|
|
//qDebug()<<"pp1 = "<<pp1<<" pp2 = "<<pp2;
|
|
QPointF ps1(floor((pix_plot_topleft.x()-pix_topelft.x())/pixwidth), floor((pix_plot_topleft.y()-pix_topelft.y())/pixheight));
|
|
QPointF ps2=ps1+QPointF(ceil(fabs(pix_plot_bottomright.x()-pix_plot_topleft.x())/pixwidth), ceil(fabs(pix_plot_bottomright.y()-pix_plot_topleft.y())/pixheight));
|
|
if (ps1.x()<0) ps1.setX(0);
|
|
if (ps1.y()<0) ps1.setY(0);
|
|
if (ps2.x()>image.width()) ps2.setX(image.width());
|
|
if (ps2.y()>image.height()) ps2.setY(image.height());
|
|
const QRectF source(ps1, ps2);
|
|
const QRectF target(pix_topelft.x()+ps1.x()*pixwidth, pix_topelft.y()+ps1.y()*pixheight, source.width()*pixwidth, source.height()*pixheight);
|
|
//qDebug()<<"source = "<<source;
|
|
//qDebug()<<"target = "<<target;
|
|
painter.drawImage(target, image.mirrored(mirrx, mirry), source);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JKQTPImage::JKQTPImage(JKQTBasePlotter *parent):
|
|
JKQTPImageBase(parent), image_owned(false)
|
|
{
|
|
this->image=nullptr;
|
|
createImageActions();
|
|
}
|
|
|
|
JKQTPImage::JKQTPImage(double x, double y, double width, double height, QImage* image, JKQTBasePlotter* parent):
|
|
JKQTPImageBase(x, y, width, height, parent), image_owned(false)
|
|
{
|
|
this->image=image;
|
|
createImageActions();
|
|
}
|
|
|
|
JKQTPImage::JKQTPImage(JKQTPlotter *parent):
|
|
JKQTPImageBase(parent), image_owned(false)
|
|
{
|
|
this->image=nullptr;
|
|
createImageActions();
|
|
}
|
|
|
|
JKQTPImage::JKQTPImage(double x, double y, double width, double height, QImage* image, JKQTPlotter* parent):
|
|
JKQTPImageBase(x, y, width, height, parent), image_owned(false)
|
|
{
|
|
this->image=image;
|
|
createImageActions();
|
|
}
|
|
|
|
JKQTPImage::JKQTPImage(double x, double y, double width, double height, const QImage &image, JKQTBasePlotter *parent):
|
|
JKQTPImageBase(x, y, width, height, parent), image_owned(true)
|
|
{
|
|
this->image=new QImage(image);
|
|
createImageActions();
|
|
}
|
|
|
|
JKQTPImage::JKQTPImage(double x, double y, double width, double height, const QImage &image, JKQTPlotter *parent):
|
|
JKQTPImageBase(x, y, width, height, parent), image_owned(true)
|
|
{
|
|
this->image=new QImage(image);
|
|
createImageActions();
|
|
}
|
|
|
|
JKQTPImage::~JKQTPImage()
|
|
{
|
|
clear_image();
|
|
}
|
|
|
|
|
|
void JKQTPImage::draw(JKQTPEnhancedPainter& painter) {
|
|
if (image) plotImage(painter, *image, x, y, width, height);
|
|
}
|
|
|
|
void JKQTPImage::drawKeyMarker(JKQTPEnhancedPainter &painter, const QRectF &rect)
|
|
{
|
|
painter.drawImage(rect, QPixmap(":/JKQTPlotter/jkqtp_plot_image.png").toImage());
|
|
}
|
|
|
|
void JKQTPImage::setImage(const QImage &image)
|
|
{
|
|
clear_image();
|
|
this->image=new QImage(image.mirrored(false, true));
|
|
image_owned=true;
|
|
createImageActions();
|
|
}
|
|
|
|
void JKQTPImage::setImage(QImage *image)
|
|
{
|
|
clear_image();
|
|
this->image=image;
|
|
image_owned=false;
|
|
createImageActions();
|
|
}
|
|
|
|
void JKQTPImage::clear_image()
|
|
{
|
|
if (image_owned && image!=nullptr) {
|
|
delete image;
|
|
}
|
|
image=nullptr;
|
|
image_owned=false;
|
|
}
|
|
|
|
void JKQTPImage::createImageActions()
|
|
{
|
|
actSaveImage=new QAction(tr("Save JKQTPImage ..."), this);
|
|
connect(actSaveImage, SIGNAL(triggered()), this, SLOT(saveImagePlotAsImage()));
|
|
actCopyImage=new QAction(tr("Copy JKQTPImage ..."), this);
|
|
connect(actCopyImage, SIGNAL(triggered()), this, SLOT(copyImagePlotAsImage()));
|
|
|
|
}
|
|
|
|
void JKQTPImage::setParent(JKQTBasePlotter *parent)
|
|
{
|
|
if (this->parent) {
|
|
this->parent->deregisterAdditionalAction(actSaveImage);
|
|
this->parent->deregisterAdditionalAction(actCopyImage);
|
|
}
|
|
JKQTPImageBase::setParent(parent);
|
|
if (parent) {
|
|
parent->registerAdditionalAction(tr("Save Image Plot Images ..."), actSaveImage);
|
|
parent->registerAdditionalAction(tr("Copy Image Plot Images ..."), actCopyImage);
|
|
}
|
|
actSaveImage->setEnabled(parent);
|
|
actCopyImage->setEnabled(parent);
|
|
}
|
|
|
|
void JKQTPImage::setTitle(const QString &title)
|
|
{
|
|
JKQTPImageBase::setTitle(title);
|
|
QString t=title;
|
|
if (t.isEmpty()) t="JKQTPImage";
|
|
actSaveImage->setText(tr("Save %1 ...").arg(t));
|
|
actCopyImage->setText(tr("Copy %1 ...").arg(t));
|
|
}
|
|
|
|
void JKQTPImage::saveImagePlotAsImage(const QString &filename, const QByteArray &outputFormat)
|
|
{
|
|
if (parent && image) {
|
|
parent->loadUserSettings();
|
|
QString currentSaveDirectory=parent->getCurrentSaveDirectory();
|
|
QString currentFileFormat=parent->getCurrentFileFormat();
|
|
QString fn=filename;
|
|
QStringList filt;
|
|
QList<QByteArray> writerformats=QImageWriter::supportedImageFormats();
|
|
for (int i=0; i<writerformats.size(); i++) {
|
|
filt<<QString("%1 Image (*.%2)").arg(QString(writerformats[i]).toUpper()).arg(QString(writerformats[i].toLower()));
|
|
}
|
|
QString selFormat;
|
|
if (fn.isEmpty()) {
|
|
selFormat=currentFileFormat;
|
|
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Image Plot As Image ..."),
|
|
currentSaveDirectory,
|
|
filt.join(";;"), &selFormat);
|
|
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
|
}
|
|
|
|
parent->setCurrentFileFormat(currentFileFormat);
|
|
parent->setCurrentSaveDirectory(currentSaveDirectory);
|
|
parent->saveUserSettings();
|
|
if (!fn.isEmpty()) {
|
|
int filtID=filt.indexOf(selFormat);
|
|
QString form="NONE";
|
|
if (filtID>=0 && filtID<writerformats.size()) {
|
|
form=writerformats[filtID];
|
|
}
|
|
if (outputFormat.size()>0) {
|
|
form =outputFormat;
|
|
}
|
|
|
|
if (form=="NONE") image->save(fn);
|
|
else image->save(fn, form.toLatin1().data());
|
|
}
|
|
}
|
|
}
|
|
|
|
void JKQTPImage::copyImagePlotAsImage()
|
|
{
|
|
QClipboard* clip=QApplication::clipboard();
|
|
if (clip && image) {
|
|
clip->setPixmap(QPixmap::fromImage(*image));
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
JKQTPMathImageBase::JKQTPMathImageBase(double x, double y, double width, double height, JKQTPMathImageDataType datatype, const void* data, int Nx, int Ny, JKQTBasePlotter* parent):
|
|
JKQTPImageBase(x, y, width, height, parent)
|
|
{
|
|
this->data=data;
|
|
this->datatype=datatype;
|
|
this->Nx=Nx;
|
|
this->Ny=Ny;
|
|
dataModifier=nullptr;
|
|
datatypeModifier=JKQTPMathImageDataType::DoubleArray;
|
|
}
|
|
|
|
|
|
JKQTPMathImageBase::JKQTPMathImageBase(double x, double y, double width, double height, JKQTPMathImageDataType datatype, const void* data, int Nx, int Ny, JKQTPlotter* parent):
|
|
JKQTPImageBase(x, y, width, height, parent)
|
|
{
|
|
this->data=data;
|
|
this->datatype=datatype;
|
|
this->Nx=Nx;
|
|
this->Ny=Ny;
|
|
dataModifier=nullptr;
|
|
datatypeModifier=JKQTPMathImageDataType::DoubleArray;
|
|
}
|
|
void JKQTPMathImageBase::drawKeyMarker(JKQTPEnhancedPainter &/*painter*/, const QRectF &/*rect*/)
|
|
{
|
|
|
|
}
|
|
|
|
void JKQTPMathImageBase::setNx(int __value)
|
|
{
|
|
this->Nx = __value;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setNx(size_t __value)
|
|
{
|
|
this->Nx = static_cast<int>(__value);
|
|
}
|
|
|
|
int JKQTPMathImageBase::getNx() const
|
|
{
|
|
return this->Nx;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setNy(int __value)
|
|
{
|
|
this->Ny = __value;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setNy(size_t __value)
|
|
{
|
|
this->Ny = static_cast<int>(__value);
|
|
}
|
|
|
|
int JKQTPMathImageBase::getNy() const
|
|
{
|
|
return this->Ny;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setData(const void *__value)
|
|
{
|
|
this->data = __value;
|
|
}
|
|
|
|
const void *JKQTPMathImageBase::getData() const
|
|
{
|
|
return this->data;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setDatatype(JKQTPMathImageDataType __value)
|
|
{
|
|
this->datatype = __value;
|
|
}
|
|
|
|
JKQTPMathImageDataType JKQTPMathImageBase::getDatatype() const
|
|
{
|
|
return this->datatype;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setDataModifier(const void *__value)
|
|
{
|
|
this->dataModifier = __value;
|
|
}
|
|
|
|
const void *JKQTPMathImageBase::getDataModifier() const
|
|
{
|
|
return this->dataModifier;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setDatatypeModifier(JKQTPMathImageDataType __value)
|
|
{
|
|
this->datatypeModifier = __value;
|
|
}
|
|
|
|
JKQTPMathImageDataType JKQTPMathImageBase::getDatatypeModifier() const
|
|
{
|
|
return this->datatypeModifier;
|
|
}
|
|
|
|
|
|
|
|
|
|
JKQTPMathImageBase::JKQTPMathImageBase(JKQTBasePlotter *parent):
|
|
JKQTPImageBase(parent)
|
|
{
|
|
this->data=nullptr;
|
|
this->Nx=0;
|
|
this->Ny=0;
|
|
this->datatype=JKQTPMathImageDataType::DoubleArray;
|
|
dataModifier=nullptr;
|
|
datatypeModifier=JKQTPMathImageDataType::DoubleArray;
|
|
}
|
|
|
|
JKQTPMathImageBase::JKQTPMathImageBase(double x, double y, double width, double height, JKQTBasePlotter *parent):
|
|
JKQTPImageBase(x,y,width,height,parent)
|
|
{
|
|
this->data=nullptr;
|
|
this->Nx=0;
|
|
this->Ny=0;
|
|
this->datatype=JKQTPMathImageDataType::DoubleArray;
|
|
dataModifier=nullptr;
|
|
datatypeModifier=JKQTPMathImageDataType::DoubleArray;
|
|
}
|
|
|
|
JKQTPMathImageBase::JKQTPMathImageBase(JKQTPlotter *parent):
|
|
JKQTPImageBase(parent)
|
|
{
|
|
this->data=nullptr;
|
|
this->Nx=0;
|
|
this->Ny=0;
|
|
this->datatype=JKQTPMathImageDataType::DoubleArray;
|
|
dataModifier=nullptr;
|
|
datatypeModifier=JKQTPMathImageDataType::DoubleArray;
|
|
}
|
|
|
|
JKQTPMathImageBase::JKQTPMathImageBase(double x, double y, double width, double height, JKQTPlotter *parent):
|
|
JKQTPImageBase(x,y,width,height,parent)
|
|
{
|
|
this->data=nullptr;
|
|
this->Nx=0;
|
|
this->Ny=0;
|
|
this->datatype=JKQTPMathImageDataType::DoubleArray;
|
|
dataModifier=nullptr;
|
|
datatypeModifier=JKQTPMathImageDataType::DoubleArray;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setData(const void *data, int Nx, int Ny, JKQTPMathImageDataType datatype) {
|
|
this->data=data;
|
|
this->datatype=datatype;
|
|
this->Nx=Nx;
|
|
this->Ny=Ny;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setData(const void* data, int Nx, int Ny) {
|
|
this->data=data;
|
|
this->Nx=Nx;
|
|
this->Ny=Ny;
|
|
}
|
|
|
|
void JKQTPMathImageBase::setDataModifier(const void *data, JKQTPMathImageDataType datatype)
|
|
{
|
|
this->dataModifier=data;
|
|
this->datatypeModifier=datatype;
|
|
}
|
|
|
|
|
|
void JKQTPMathImageBase::getDataMinMax(double& imin, double& imax) {
|
|
ensureImageData();
|
|
imin=imax=0;
|
|
if (!data) return;
|
|
switch(datatype) {
|
|
case JKQTPMathImageDataType::DoubleArray:
|
|
imin= JKQTPImagePlot_getImageMin<double>(static_cast<const double*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<double>(static_cast<const double*>(data), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::FloatArray:
|
|
imin= JKQTPImagePlot_getImageMin<float>(static_cast<const float*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<float>(static_cast<const float*>(data), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt8Array:
|
|
imin= JKQTPImagePlot_getImageMin<uint8_t>(static_cast<const uint8_t*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<uint8_t>(static_cast<const uint8_t*>(data), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt16Array:
|
|
imin= JKQTPImagePlot_getImageMin<uint16_t>(static_cast<const uint16_t*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<uint16_t>(static_cast<const uint16_t*>(data), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt32Array:
|
|
imin= JKQTPImagePlot_getImageMin<uint32_t>(static_cast<const uint32_t*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<uint32_t>(static_cast<const uint32_t*>(data), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt64Array:
|
|
imin= JKQTPImagePlot_getImageMin<uint64_t>(static_cast<const uint64_t*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<uint64_t>(static_cast<const uint64_t*>(data), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int8Array:
|
|
imin= JKQTPImagePlot_getImageMin<int8_t>(static_cast<const int8_t*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<int8_t>(static_cast<const int8_t*>(data), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int16Array:
|
|
imin= JKQTPImagePlot_getImageMin<int16_t>(static_cast<const int16_t*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<int16_t>(static_cast<const int16_t*>(data), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int32Array:
|
|
imin= JKQTPImagePlot_getImageMin<int32_t>(static_cast<const int32_t*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<int32_t>(static_cast<const int32_t*>(data), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int64Array:
|
|
imin= JKQTPImagePlot_getImageMin<int64_t>(static_cast<const int64_t*>(data), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<int64_t>(static_cast<const int64_t*>(data), Nx, Ny);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void JKQTPMathImageBase::getModifierMinMax(double &imin, double &imax)
|
|
{
|
|
ensureImageData();
|
|
imin=imax=0;
|
|
if (!dataModifier) return;
|
|
switch(datatypeModifier) {
|
|
case JKQTPMathImageDataType::DoubleArray:
|
|
imin= JKQTPImagePlot_getImageMin<double>(static_cast<const double*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<double>(static_cast<const double*>(dataModifier), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::FloatArray:
|
|
imin= JKQTPImagePlot_getImageMin<float>(static_cast<const float*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<float>(static_cast<const float*>(dataModifier), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt8Array:
|
|
imin= JKQTPImagePlot_getImageMin<uint8_t>(static_cast<const uint8_t*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<uint8_t>(static_cast<const uint8_t*>(dataModifier), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt16Array:
|
|
imin= JKQTPImagePlot_getImageMin<uint16_t>(static_cast<const uint16_t*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<uint16_t>(static_cast<const uint16_t*>(dataModifier), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt32Array:
|
|
imin= JKQTPImagePlot_getImageMin<uint32_t>(static_cast<const uint32_t*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<uint32_t>(static_cast<const uint32_t*>(dataModifier), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt64Array:
|
|
imin= JKQTPImagePlot_getImageMin<uint64_t>(static_cast<const uint64_t*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<uint64_t>(static_cast<const uint64_t*>(dataModifier), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int8Array:
|
|
imin= JKQTPImagePlot_getImageMin<int8_t>(static_cast<const int8_t*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<int8_t>(static_cast<const int8_t*>(dataModifier), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int16Array:
|
|
imin= JKQTPImagePlot_getImageMin<int16_t>(static_cast<const int16_t*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<int16_t>(static_cast<const int16_t*>(dataModifier), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int32Array:
|
|
imin= JKQTPImagePlot_getImageMin<int32_t>(static_cast<const int32_t*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<int32_t>(static_cast<const int32_t*>(dataModifier), Nx, Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int64Array:
|
|
imin= JKQTPImagePlot_getImageMin<int64_t>(static_cast<const int64_t*>(dataModifier), Nx, Ny);
|
|
imax= JKQTPImagePlot_getImageMax<int64_t>(static_cast<const int64_t*>(dataModifier), Nx, Ny);
|
|
break;
|
|
}
|
|
}
|
|
|
|
QVector<double> JKQTPMathImageBase::getDataAsDoubleVector() const
|
|
{
|
|
switch(datatype) {
|
|
case JKQTPMathImageDataType::DoubleArray:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const double*>(data), Nx*Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::FloatArray:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const float*>(data), Nx*Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt8Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const uint8_t*>(data), Nx*Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt16Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const uint16_t*>(data), Nx*Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt32Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const uint32_t*>(data), Nx*Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::UInt64Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const uint64_t*>(data), Nx*Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int8Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const int8_t*>(data), Nx*Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int16Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const int16_t*>(data), Nx*Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int32Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const int32_t*>(data), Nx*Ny);
|
|
break;
|
|
case JKQTPMathImageDataType::Int64Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const int64_t*>(data), Nx*Ny);
|
|
break;
|
|
}
|
|
QVector<double> res;
|
|
return res;
|
|
}
|
|
|
|
QVector<double> JKQTPMathImageBase::getDataModifierAsDoubleVector() const
|
|
{
|
|
switch(datatypeModifier) {
|
|
case JKQTPMathImageDataType::DoubleArray:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const double*>(dataModifier), Nx*Ny);
|
|
case JKQTPMathImageDataType::FloatArray:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const float*>(dataModifier), Nx*Ny);
|
|
case JKQTPMathImageDataType::UInt8Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const uint8_t*>(dataModifier), Nx*Ny);
|
|
case JKQTPMathImageDataType::UInt16Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const uint16_t*>(dataModifier), Nx*Ny);
|
|
case JKQTPMathImageDataType::UInt32Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const uint32_t*>(dataModifier), Nx*Ny);
|
|
case JKQTPMathImageDataType::UInt64Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const uint64_t*>(dataModifier), Nx*Ny);
|
|
case JKQTPMathImageDataType::Int8Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const int8_t*>(dataModifier), Nx*Ny);
|
|
case JKQTPMathImageDataType::Int16Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const int16_t*>(dataModifier), Nx*Ny);
|
|
case JKQTPMathImageDataType::Int32Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const int32_t*>(dataModifier), Nx*Ny);
|
|
case JKQTPMathImageDataType::Int64Array:
|
|
return JKQTPImagePlot_arrayToDVector(static_cast<const int64_t*>(dataModifier), Nx*Ny);
|
|
}
|
|
QVector<double> res;
|
|
return res;
|
|
}
|
|
|
|
void JKQTPMathImageBase::ensureImageData()
|
|
{
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void JKQTPMathImage::initJKQTPMathImage() {
|
|
actSaveImage=new QAction(tr("Save JKQTPMathImage ..."), this);
|
|
connect(actSaveImage, SIGNAL(triggered()), this, SLOT(saveImagePlotAsImage()));
|
|
actCopyImage=new QAction(tr("Copy JKQTPMathImage ..."), this);
|
|
connect(actCopyImage, SIGNAL(triggered()), this, SLOT(copyImagePlotAsImage()));
|
|
actSavePalette=new QAction(tr("Save JKQTPMathImage Palette/Colorbar ..."), this);
|
|
connect(actSavePalette, SIGNAL(triggered()), this, SLOT(saveColorbarPlotAsImage()));
|
|
actCopyPalette=new QAction(tr("Copy JKQTPMathImage Palette/Colorbar ..."), this);
|
|
connect(actCopyPalette, SIGNAL(triggered()), this, SLOT(copyColorbarPlotAsImage()));
|
|
|
|
|
|
|
|
this->palette=JKQTPMathImageGRAY;
|
|
this->autoModifierRange=true;
|
|
}
|
|
|
|
JKQTPMathImage::JKQTPMathImage(double x, double y, double width, double height, JKQTPMathImageDataType datatype, const void* data, int Nx, int Ny, JKQTPMathImageColorPalette palette, JKQTBasePlotter* parent):
|
|
JKQTPMathImageBase(x, y, width, height, datatype, data, Nx, Ny, parent),
|
|
JKQTPColorPaletteWithModifierStyleAndToolsMixin(parent)
|
|
{
|
|
initJKQTPMathImage();
|
|
this->palette=palette;
|
|
}
|
|
|
|
JKQTPMathImage::JKQTPMathImage(JKQTBasePlotter *parent):
|
|
JKQTPMathImageBase(0, 0, 1, 1, JKQTPMathImageDataType::UInt8Array, nullptr, 0, 0, parent),
|
|
JKQTPColorPaletteWithModifierStyleAndToolsMixin(parent)
|
|
{
|
|
initJKQTPMathImage();
|
|
if (parent) this->palette=parent->getCurrentPlotterStyle().graphsStyle.defaultPalette;
|
|
}
|
|
|
|
|
|
|
|
JKQTPMathImage::JKQTPMathImage(double x, double y, double width, double height, JKQTPMathImageDataType datatype, const void *data, int Nx, int Ny, JKQTPMathImageColorPalette palette, JKQTPlotter* parent):
|
|
JKQTPMathImage(x, y, width, height, datatype, data, Nx, Ny, palette, parent->getPlotter())
|
|
{
|
|
}
|
|
|
|
JKQTPMathImage::JKQTPMathImage(JKQTPlotter *parent):
|
|
JKQTPMathImage(parent->getPlotter())
|
|
{
|
|
}
|
|
|
|
void JKQTPMathImage::setParent(JKQTBasePlotter* parent) {
|
|
if (this->parent) {
|
|
this->parent->deregisterAdditionalAction(actSaveImage);
|
|
this->parent->deregisterAdditionalAction(actCopyImage);
|
|
this->parent->deregisterAdditionalAction(actSavePalette);
|
|
this->parent->deregisterAdditionalAction(actCopyPalette);
|
|
}
|
|
JKQTPMathImageBase::setParent(parent);
|
|
|
|
cbSetParent(parent);
|
|
|
|
if (parent) {
|
|
parent->registerAdditionalAction(tr("Save Image Plot Images ..."), actSaveImage);
|
|
parent->registerAdditionalAction(tr("Copy Image Plot Images ..."), actCopyImage);
|
|
parent->registerAdditionalAction(tr("Save Image Plot Palettes ..."), actSavePalette);
|
|
parent->registerAdditionalAction(tr("Copy Image Plot Palettes ..."), actCopyPalette);
|
|
}
|
|
actSaveImage->setEnabled(parent);
|
|
actCopyImage->setEnabled(parent);
|
|
actSavePalette->setEnabled(parent);
|
|
actCopyPalette->setEnabled(parent);
|
|
}
|
|
|
|
void JKQTPMathImage::setTitle(const QString &title)
|
|
{
|
|
JKQTPMathImageBase::setTitle(title);
|
|
QString t=title;
|
|
if (t.isEmpty()) t="JKQTPMathImage";
|
|
actSaveImage->setText(tr("Save %1 ...").arg(t));
|
|
actCopyImage->setText(tr("Copy %1 ...").arg(t));
|
|
}
|
|
|
|
void JKQTPMathImage::saveImagePlotAsImage(const QString &filename, const QByteArray &outputFormat)
|
|
{
|
|
if (parent) {
|
|
parent->loadUserSettings();
|
|
QString currentSaveDirectory=parent->getCurrentSaveDirectory();
|
|
QString currentFileFormat=parent->getCurrentFileFormat();
|
|
QString fn=filename;
|
|
QStringList filt;
|
|
QList<QByteArray> writerformats=QImageWriter::supportedImageFormats();
|
|
for (int i=0; i<writerformats.size(); i++) {
|
|
filt<<QString("%1 Image (*.%2)").arg(QString(writerformats[i]).toUpper()).arg(QString(writerformats[i].toLower()));
|
|
}
|
|
QString selFormat;
|
|
if (fn.isEmpty()) {
|
|
selFormat=currentFileFormat;
|
|
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Image Plot As Image ..."),
|
|
currentSaveDirectory,
|
|
filt.join(";;"), &selFormat);
|
|
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
|
}
|
|
|
|
parent->setCurrentFileFormat(currentFileFormat);
|
|
parent->setCurrentSaveDirectory(currentSaveDirectory);
|
|
parent->saveUserSettings();
|
|
if (!fn.isEmpty()) {
|
|
int filtID=filt.indexOf(selFormat);
|
|
QString form="NONE";
|
|
if (filtID>=0 && filtID<writerformats.size()) {
|
|
form=writerformats[filtID];
|
|
}
|
|
if (outputFormat.size()>0) {
|
|
form =outputFormat;
|
|
}
|
|
|
|
QImage image=drawImage();
|
|
|
|
if (form=="NONE") image.save(fn);
|
|
else image.save(fn, form.toLatin1().data());
|
|
}
|
|
}
|
|
}
|
|
|
|
void JKQTPMathImage::copyImagePlotAsImage()
|
|
{
|
|
QClipboard* clip=QApplication::clipboard();
|
|
if (clip) {
|
|
clip->setPixmap(QPixmap::fromImage(drawImage()));
|
|
}
|
|
}
|
|
|
|
void JKQTPMathImage::saveColorbarPlotAsImage(const QString &filename, const QByteArray &outputFormat)
|
|
{
|
|
if (parent) {
|
|
parent->loadUserSettings();
|
|
QString currentSaveDirectory=parent->getCurrentSaveDirectory();
|
|
QString currentFileFormat=parent->getCurrentFileFormat();
|
|
QString fn=filename;
|
|
QStringList filt;
|
|
QList<QByteArray> writerformats=QImageWriter::supportedImageFormats();
|
|
for (int i=0; i<writerformats.size(); i++) {
|
|
filt<<QString("%1 Image (*.%2)").arg(QString(writerformats[i]).toUpper()).arg(QString(writerformats[i].toLower()));
|
|
}
|
|
QString selFormat;
|
|
if (fn.isEmpty()) {
|
|
selFormat=currentFileFormat;
|
|
fn = QFileDialog::getSaveFileName(nullptr, tr("Save Palette Plot As Image ..."),
|
|
currentSaveDirectory,
|
|
filt.join(";;"), &selFormat);
|
|
if (!fn.isEmpty()) currentSaveDirectory=QFileInfo(fn).absolutePath();
|
|
}
|
|
|
|
parent->setCurrentFileFormat(currentFileFormat);
|
|
parent->setCurrentSaveDirectory(currentSaveDirectory);
|
|
parent->saveUserSettings();
|
|
if (!fn.isEmpty()) {
|
|
int filtID=filt.indexOf(selFormat);
|
|
QString form="NONE";
|
|
if (filtID>=0 && filtID<writerformats.size()) {
|
|
form=writerformats[filtID];
|
|
}
|
|
if (outputFormat.size()>0) {
|
|
form =outputFormat;
|
|
}
|
|
|
|
QImage image=drawOutsidePalette(200);
|
|
|
|
if (form=="NONE") image.save(fn);
|
|
else image.save(fn, form.toLatin1().data());
|
|
}
|
|
}
|
|
}
|
|
|
|
void JKQTPMathImage::copyColorbarPlotAsImage()
|
|
{
|
|
QClipboard* clip=QApplication::clipboard();
|
|
if (clip) {
|
|
clip->setPixmap(QPixmap::fromImage(drawOutsidePalette(20)));
|
|
}
|
|
}
|
|
|
|
void JKQTPMathImage::draw(JKQTPEnhancedPainter& painter) {
|
|
ensureImageData();
|
|
if (!data) return;
|
|
QImage img=drawImage();
|
|
plotImage(painter, img, x, y, width, height);
|
|
}
|
|
|
|
|
|
|
|
void JKQTPMathImage::getOutsideSize(JKQTPEnhancedPainter& painter, int& leftSpace, int& rightSpace, int& topSpace, int& bottomSpace) {
|
|
JKQTPMathImageBase::getOutsideSize(painter, leftSpace, rightSpace, topSpace, bottomSpace);
|
|
cbGetOutsideSize(painter, leftSpace, rightSpace, topSpace, bottomSpace);
|
|
}
|
|
|
|
void JKQTPMathImage::drawOutside(JKQTPEnhancedPainter& painter, QRect leftSpace, QRect rightSpace, QRect topSpace, QRect bottomSpace) {
|
|
JKQTPMathImageBase::drawOutside(painter, leftSpace, rightSpace, topSpace, bottomSpace);
|
|
if (showColorBar) cbDrawOutside(painter, leftSpace, rightSpace, topSpace, bottomSpace);
|
|
}
|
|
|
|
QImage JKQTPMathImage::drawOutsidePalette(uint8_t steps)
|
|
{
|
|
|
|
uint8_t h=1;
|
|
if (modifierMode!=JKQTPMathImageModifierMode::ModifyNone) {
|
|
h=50;
|
|
}
|
|
std::vector<double> d(steps*h, 0.0);
|
|
std::vector<double> dd(steps*h, 0.0);
|
|
for (uint8_t i=0; i<steps; i++) {
|
|
for (uint8_t j=0; j<h; j++) {
|
|
d[i*h+j]=i;
|
|
dd[i*h+j]=j;
|
|
//qDebug()<<"x="<<j<<", y="<<i<<": d="<<d[i*h+j]<<" dd="<<dd[i*h+j];
|
|
}
|
|
}
|
|
|
|
QImage b(h,200, QImage::Format_ARGB32);
|
|
JKQTPImageTools::array2image<double>(d.data(),h,steps, b, palette, 0, steps-1);
|
|
//b.save("c:/temp/b1.png");
|
|
if (modifierMode!=JKQTPMathImageModifierMode::ModifyNone) {
|
|
modifyImage(b, dd.data(), JKQTPMathImageDataType::DoubleArray, h,steps, 0, h-1);
|
|
//b.save("c:/temp/b2.png");
|
|
}
|
|
return b;
|
|
}
|
|
|
|
void JKQTPMathImage::getDataMinMax(double& imin, double& imax) {
|
|
ensureImageData();
|
|
if (autoImageRange) {
|
|
JKQTPMathImageBase::getDataMinMax(imin, imax);
|
|
} else {
|
|
imin=imageMin;
|
|
imax=imageMax;
|
|
}
|
|
}
|
|
|
|
void JKQTPMathImage::getModifierMinMax(double &imin, double &imax)
|
|
{
|
|
ensureImageData();
|
|
if (autoModifierRange) {
|
|
JKQTPMathImageBase::getModifierMinMax(imin, imax);
|
|
} else {
|
|
imin=modifierMin;
|
|
imax=modifierMax;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void JKQTPMathImage::drawKeyMarker(JKQTPEnhancedPainter &painter, const QRectF &rect)
|
|
{
|
|
painter.drawImage(rect, getPaletteKeyImage(palette, 32,32));
|
|
}
|
|
|
|
void JKQTPMathImage::cbGetDataMinMax(double &imin, double &imax)
|
|
{
|
|
getDataMinMax(imin, imax);
|
|
}
|
|
|
|
void JKQTPMathImage::cbGetModifierDataMinMax(double &imin, double &imax)
|
|
{
|
|
getModifierMinMax(imin, imax);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
QImage JKQTPMathImage::drawImage() {
|
|
if (!data) return QImage();
|
|
QImage img(Nx, Ny, QImage::Format_ARGB32);
|
|
getDataMinMax(internalDataMin, internalDataMax);
|
|
getModifierMinMax(internalModifierMin, internalModifierMax);
|
|
switch(datatype) {
|
|
case JKQTPMathImageDataType::DoubleArray: JKQTPImageTools::array2image<double>(static_cast<const double*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
case JKQTPMathImageDataType::FloatArray: JKQTPImageTools::array2image<float>(static_cast<const float*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
case JKQTPMathImageDataType::UInt8Array: JKQTPImageTools::array2image<uint8_t>(static_cast<const uint8_t*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
case JKQTPMathImageDataType::UInt16Array: JKQTPImageTools::array2image<uint16_t>(static_cast<const uint16_t*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
case JKQTPMathImageDataType::UInt32Array: JKQTPImageTools::array2image<uint32_t>(static_cast<const uint32_t*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
case JKQTPMathImageDataType::UInt64Array: JKQTPImageTools::array2image<uint64_t>(static_cast<const uint64_t*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
case JKQTPMathImageDataType::Int8Array: JKQTPImageTools::array2image<int8_t>(static_cast<const int8_t*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
case JKQTPMathImageDataType::Int16Array: JKQTPImageTools::array2image<int16_t>(static_cast<const int16_t*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
case JKQTPMathImageDataType::Int32Array: JKQTPImageTools::array2image<int32_t>(static_cast<const int32_t*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
case JKQTPMathImageDataType::Int64Array: JKQTPImageTools::array2image<int64_t>(static_cast<const int64_t*>(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break;
|
|
}
|
|
modifyImage(img, dataModifier, datatypeModifier, Nx, Ny, internalModifierMin, internalModifierMax);
|
|
return img;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
JKQTPColumnMathImage::JKQTPColumnMathImage(JKQTBasePlotter *parent):
|
|
JKQTPMathImage(parent)
|
|
{
|
|
this->modifierColumn=-1;
|
|
this->imageColumn=-1;
|
|
this->datatype=JKQTPMathImageDataType::DoubleArray;
|
|
}
|
|
|
|
JKQTPColumnMathImage::JKQTPColumnMathImage(double x, double y, double width, double height, JKQTBasePlotter *parent):
|
|
JKQTPMathImage(x,y,width,height,JKQTPMathImageDataType::DoubleArray,nullptr,0,0,JKQTPMathImageGRAY,parent)
|
|
{
|
|
this->modifierColumn=-1;
|
|
this->imageColumn=-1;
|
|
this->datatype=JKQTPMathImageDataType::DoubleArray;
|
|
}
|
|
|
|
JKQTPColumnMathImage::JKQTPColumnMathImage(double x, double y, double width, double height, int imageColumn, JKQTPMathImageColorPalette palette, JKQTBasePlotter *parent):
|
|
JKQTPMathImage(x,y,width,height,JKQTPMathImageDataType::DoubleArray,nullptr,0,0,palette,parent)
|
|
{
|
|
this->modifierColumn=-1;
|
|
this->imageColumn=imageColumn;
|
|
if (parent && imageColumn>=0 && parent->getDatastore()) {
|
|
Nx= static_cast<int>(parent->getDatastore()->getColumnImageWidth(imageColumn));
|
|
Ny= static_cast<int>(parent->getDatastore()->getColumnImageHeight(imageColumn));
|
|
}
|
|
this->datatype=JKQTPMathImageDataType::DoubleArray;
|
|
}
|
|
|
|
JKQTPColumnMathImage::JKQTPColumnMathImage(JKQTPlotter *parent):
|
|
JKQTPColumnMathImage(parent->getPlotter())
|
|
{
|
|
}
|
|
|
|
JKQTPColumnMathImage::JKQTPColumnMathImage(double x, double y, double width, double height, JKQTPlotter *parent):
|
|
JKQTPColumnMathImage(x,y,width,height,parent->getPlotter())
|
|
{
|
|
}
|
|
|
|
JKQTPColumnMathImage::JKQTPColumnMathImage(double x, double y, double width, double height, int imageColumn, JKQTPMathImageColorPalette palette, JKQTPlotter *parent):
|
|
JKQTPColumnMathImage(x,y,width,height,imageColumn,palette,parent->getPlotter())
|
|
{
|
|
}
|
|
|
|
JKQTPColumnMathImage::JKQTPColumnMathImage(double x, double y, double width, double height, int imageColumn, JKQTPlotter *parent):
|
|
JKQTPColumnMathImage(x,y,width,height,imageColumn,JKQTPMathImageGRAY,parent->getPlotter())
|
|
{
|
|
}
|
|
|
|
void JKQTPColumnMathImage::setImageColumn(size_t __value)
|
|
{
|
|
setImageColumn(static_cast<int>(__value));
|
|
}
|
|
|
|
void JKQTPColumnMathImage::setModifierColumn(size_t __value)
|
|
{
|
|
setModifierColumn(static_cast<int>(__value));
|
|
}
|
|
void JKQTPColumnMathImage::setImageColumn(int __value)
|
|
{
|
|
this->imageColumn = __value;
|
|
if (parent && __value>=0 && parent->getDatastore()) {
|
|
setNx(parent->getDatastore()->getColumnImageWidth(__value));
|
|
setNy(parent->getDatastore()->getColumnImageHeight(__value));
|
|
}
|
|
}
|
|
|
|
int JKQTPColumnMathImage::getImageColumn() const
|
|
{
|
|
return this->imageColumn;
|
|
}
|
|
|
|
void JKQTPColumnMathImage::setModifierColumn(int __value)
|
|
{
|
|
this->modifierColumn = __value;
|
|
if (parent && __value>=0 && parent->getDatastore()) {
|
|
setNx(parent->getDatastore()->getColumnImageWidth(__value));
|
|
setNy(parent->getDatastore()->getColumnImageHeight(__value));
|
|
}
|
|
}
|
|
|
|
int JKQTPColumnMathImage::getModifierColumn() const
|
|
{
|
|
return this->modifierColumn;
|
|
}
|
|
bool JKQTPColumnMathImage::usesColumn(int c) const
|
|
{
|
|
return (c==imageColumn)||(c==modifierColumn);
|
|
}
|
|
|
|
|
|
void JKQTPColumnMathImage::ensureImageData()
|
|
{
|
|
|
|
if (this->Nx==0 || imageColumn<0 || !parent->getDatastore()->getColumnPointer(imageColumn,0)) {
|
|
this->Ny=0;
|
|
this->data=nullptr;
|
|
this->datatype=JKQTPMathImageDataType::DoubleArray;
|
|
} else {
|
|
this->datatype=JKQTPMathImageDataType::DoubleArray;
|
|
this->data=parent->getDatastore()->getColumnPointer(imageColumn,0);
|
|
this->Ny= static_cast<int>(parent->getDatastore()->getRows(imageColumn)/this->Nx);
|
|
}
|
|
if (this->Nx==0 || modifierColumn<0 || !parent->getDatastore()->getColumnPointer(modifierColumn,0)) {
|
|
this->dataModifier=nullptr;
|
|
} else {
|
|
this->datatypeModifier=JKQTPMathImageDataType::DoubleArray;
|
|
this->dataModifier=parent->getDatastore()->getColumnPointer(modifierColumn,0);
|
|
}
|
|
}
|
|
|