/* Copyright (c) 2008-2020 Jan W. Krieger 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 . */ #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 #include #include #include #include #include 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*/, 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.width()); const double pixheight=fabs(pix_bottomright.y()-pix_topelft.y())/static_cast(image.height()); //qDebug()<<"\nimage.size = "<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 writerformats=QImageWriter::supportedImageFormats(); for (int i=0; isetCurrentFileFormat(currentFileFormat); parent->setCurrentSaveDirectory(currentSaveDirectory); parent->saveUserSettings(); if (!fn.isEmpty()) { int filtID=filt.indexOf(selFormat); QString form="NONE"; if (filtID>=0 && filtID0) { 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*/, QRectF &/*rect*/) { } void JKQTPMathImageBase::setNx(int __value) { this->Nx = __value; } void JKQTPMathImageBase::setNx(size_t __value) { this->Nx = static_cast(__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(__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(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(data), Nx, Ny); break; case JKQTPMathImageDataType::FloatArray: imin= JKQTPImagePlot_getImageMin(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(data), Nx, Ny); break; case JKQTPMathImageDataType::UInt8Array: imin= JKQTPImagePlot_getImageMin(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(data), Nx, Ny); break; case JKQTPMathImageDataType::UInt16Array: imin= JKQTPImagePlot_getImageMin(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(data), Nx, Ny); break; case JKQTPMathImageDataType::UInt32Array: imin= JKQTPImagePlot_getImageMin(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(data), Nx, Ny); break; case JKQTPMathImageDataType::UInt64Array: imin= JKQTPImagePlot_getImageMin(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(data), Nx, Ny); break; case JKQTPMathImageDataType::Int8Array: imin= JKQTPImagePlot_getImageMin(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(data), Nx, Ny); break; case JKQTPMathImageDataType::Int16Array: imin= JKQTPImagePlot_getImageMin(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(data), Nx, Ny); break; case JKQTPMathImageDataType::Int32Array: imin= JKQTPImagePlot_getImageMin(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(data), Nx, Ny); break; case JKQTPMathImageDataType::Int64Array: imin= JKQTPImagePlot_getImageMin(static_cast(data), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(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(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; case JKQTPMathImageDataType::FloatArray: imin= JKQTPImagePlot_getImageMin(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; case JKQTPMathImageDataType::UInt8Array: imin= JKQTPImagePlot_getImageMin(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; case JKQTPMathImageDataType::UInt16Array: imin= JKQTPImagePlot_getImageMin(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; case JKQTPMathImageDataType::UInt32Array: imin= JKQTPImagePlot_getImageMin(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; case JKQTPMathImageDataType::UInt64Array: imin= JKQTPImagePlot_getImageMin(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; case JKQTPMathImageDataType::Int8Array: imin= JKQTPImagePlot_getImageMin(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; case JKQTPMathImageDataType::Int16Array: imin= JKQTPImagePlot_getImageMin(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; case JKQTPMathImageDataType::Int32Array: imin= JKQTPImagePlot_getImageMin(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; case JKQTPMathImageDataType::Int64Array: imin= JKQTPImagePlot_getImageMin(static_cast(dataModifier), Nx, Ny); imax= JKQTPImagePlot_getImageMax(static_cast(dataModifier), Nx, Ny); break; } } QVector JKQTPMathImageBase::getDataAsDoubleVector() const { switch(datatype) { case JKQTPMathImageDataType::DoubleArray: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; case JKQTPMathImageDataType::FloatArray: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; case JKQTPMathImageDataType::UInt8Array: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; case JKQTPMathImageDataType::UInt16Array: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; case JKQTPMathImageDataType::UInt32Array: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; case JKQTPMathImageDataType::UInt64Array: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; case JKQTPMathImageDataType::Int8Array: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; case JKQTPMathImageDataType::Int16Array: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; case JKQTPMathImageDataType::Int32Array: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; case JKQTPMathImageDataType::Int64Array: return JKQTPImagePlot_arrayToDVector(static_cast(data), Nx*Ny); break; } QVector res; return res; } QVector JKQTPMathImageBase::getDataModifierAsDoubleVector() const { switch(datatypeModifier) { case JKQTPMathImageDataType::DoubleArray: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); case JKQTPMathImageDataType::FloatArray: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); case JKQTPMathImageDataType::UInt8Array: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); case JKQTPMathImageDataType::UInt16Array: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); case JKQTPMathImageDataType::UInt32Array: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); case JKQTPMathImageDataType::UInt64Array: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); case JKQTPMathImageDataType::Int8Array: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); case JKQTPMathImageDataType::Int16Array: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); case JKQTPMathImageDataType::Int32Array: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); case JKQTPMathImageDataType::Int64Array: return JKQTPImagePlot_arrayToDVector(static_cast(dataModifier), Nx*Ny); } QVector 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 writerformats=QImageWriter::supportedImageFormats(); for (int i=0; isetCurrentFileFormat(currentFileFormat); parent->setCurrentSaveDirectory(currentSaveDirectory); parent->saveUserSettings(); if (!fn.isEmpty()) { int filtID=filt.indexOf(selFormat); QString form="NONE"; if (filtID>=0 && filtID0) { 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 writerformats=QImageWriter::supportedImageFormats(); for (int i=0; isetCurrentFileFormat(currentFileFormat); parent->setCurrentSaveDirectory(currentSaveDirectory); parent->saveUserSettings(); if (!fn.isEmpty()) { int filtID=filt.indexOf(selFormat); QString form="NONE"; if (filtID>=0 && filtID0) { 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 d(steps*h, 0.0); std::vector dd(steps*h, 0.0); for (uint8_t i=0; i(static_cast(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break; case JKQTPMathImageDataType::FloatArray: JKQTPImageTools::array2image(static_cast(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break; case JKQTPMathImageDataType::UInt8Array: JKQTPImageTools::array2image(static_cast(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break; case JKQTPMathImageDataType::UInt16Array: JKQTPImageTools::array2image(static_cast(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break; case JKQTPMathImageDataType::UInt32Array: JKQTPImageTools::array2image(static_cast(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break; case JKQTPMathImageDataType::UInt64Array: JKQTPImageTools::array2image(static_cast(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break; case JKQTPMathImageDataType::Int8Array: JKQTPImageTools::array2image(static_cast(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break; case JKQTPMathImageDataType::Int16Array: JKQTPImageTools::array2image(static_cast(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break; case JKQTPMathImageDataType::Int32Array: JKQTPImageTools::array2image(static_cast(data), Nx, Ny, img, palette, internalDataMin, internalDataMax, rangeMinFailAction, rangeMaxFailAction, rangeMinFailColor, rangeMaxFailColor, nanColor, infColor); break; case JKQTPMathImageDataType::Int64Array: JKQTPImageTools::array2image(static_cast(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(parent->getDatastore()->getColumnImageWidth(imageColumn)); Ny= static_cast(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(__value)); } void JKQTPColumnMathImage::setModifierColumn(size_t __value) { setModifierColumn(static_cast(__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(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); } }