6#include "fitsstretchui.h"
16const char kAutoToolTip[] =
"Automatically find stretch parameters";
60void FITSStretchUI::setupButtons()
67void FITSStretchUI::setupHistoPlot()
81void FITSStretchUI::onHistoDoubleClick(
QMouseEvent *event)
84 if (!m_View || !m_View->imageData() || !m_View->imageData()->isHistogramConstructed())
return;
85 const double histogramSize = m_View->imageData()->getHistogramBinCount();
91void FITSStretchUI::onHistoMouseMove(
QMouseEvent *event)
93 const auto image = m_View->imageData();
94 if (!image->isHistogramConstructed())
98 const int numPixels = image->width() * image->height();
106 for (
int c = 0; c < image->channels(); ++c)
113 tip.
append(
QString(
"<font color=\"%1\">").arg(c == 0 ?
"red" : (c == 1) ?
"lightgreen" :
"lightblue"));
115 if (image->getMax(c) > 1.1)
120 const int count = image->getHistogramFrequency(c)[
histoBin];
121 const double percentage = count * 100.0 / (double) numPixels;
124 tip.
append(
"</font><br/>");
131void FITSStretchUI::setupHistoSlider()
143 StretchParams params = m_View->getStretchParams();
147 params.grey_red.shadows = shadowValue;
153 m_View->setPreviewSampling(Options::stretchPreviewSampling());
154 m_View->setStretchParams(params);
155 m_View->setPreviewSampling(0);
165 StretchParams params = m_View->getStretchParams();
167 if (
highValue != params.grey_red.highlights)
169 params.grey_red.highlights = highValue;
170 m_View->setPreviewSampling(Options::stretchPreviewSampling());
171 m_View->setStretchParams(params);
172 m_View->setPreviewSampling(0);
179 StretchParams params = m_View->getStretchParams();
181 if (midValue != params.grey_red.midtones)
183 params.grey_red.midtones = midValue;
184 m_View->setPreviewSampling(Options::stretchPreviewSampling());
185 m_View->setStretchParams(params);
186 m_View->setPreviewSampling(0);
194 connect(
histoSlider, &ctk3Slider::released,
this, [ = ](
int minValue,
int midValue,
int maxValue)
196 StretchParams params = m_View->getStretchParams();
202 highValue != params.grey_red.highlights ||
208 m_View->setPreviewSampling(0);
209 m_View->setStretchParams(params);
215void FITSStretchUI::setStretchUIValues(
const StretchParams1Channel ¶ms)
248 autoButton->setChecked(m_View->getAutoStretch());
260void FITSStretchUI::setupConnections()
262 connect(m_View.
get(), &FITSView::mouseOverPixel,
this, [
this ](
int x,
int y)
264 if (pixelCursors.size() != m_View->imageData()->channels())
265 pixelCursors.fill(nullptr, m_View->imageData()->channels());
267 if (!m_View || !m_View->imageData() || !m_View->imageData()->isHistogramConstructed()) return;
268 auto image = m_View->imageData();
269 const int nChannels = m_View->imageData()->channels();
270 for (int c = 0; c < nChannels; ++c)
272 if (pixelCursors[c] != nullptr)
274 histoPlot->removeItem(pixelCursors[c]);
275 pixelCursors[c] = nullptr;
277 if (x < 0 || y < 0 || x >= m_View->imageData()->width() ||
278 y >= m_View->imageData()->height())
280 int32_t bin = image->histogramBin(x, y, c);
281 QColor color = Qt::darkGray;
283 color = c == 0 ? QColor(255, 10, 65) : ((c == 1) ? QColor(144, 238, 144, 225) : QColor(173, 216, 230, 175));
285 pixelCursors[c] = setCursor(bin, QPen(color, 2, Qt::SolidLine));
292 StretchParams params = m_View->getStretchParams();
295 m_View->setStretchParams(params);
302 StretchParams params = m_View->getStretchParams();
305 m_View->setStretchParams(params);
312 StretchParams params = m_View->getStretchParams();
313 params.grey_red.shadows =
shadowsVal->value();
315 m_View->setStretchParams(params);
323 m_View->setStretch(!m_View->isImageStretched());
331 if (!m_View->getAutoStretch())
332 m_View->setAutoStretchParams();
335 setStretchUIValues(m_View->getStretchParams().grey_red);
345 connect(m_View.get(), &FITSView::newStatus,
this, [ = ](
const QString & unused)
348 setStretchUIValues(m_View->getStretchParams().grey_red);
351 connect(m_View.get(), &FITSView::newStretch,
this, [ = ](
const StretchParams & params)
353 histoSlider->setMinimumValue(params.grey_red.shadows * HISTO_SLIDER_MAX);
354 histoSlider->setMaximumValue(params.grey_red.highlights * HISTO_SLIDER_MAX);
355 histoSlider->setMidValue(invertMidValueFcn(params.grey_red.midtones));
366 if (!data->isHistogramConstructed())
368 const double size = data->getHistogramBinCount();
369 return position * size;
378 const double top =
histoPlot->yAxis->range().upper;
379 const double bottom =
histoPlot->yAxis->range().lower;
380 line->start->
setCoords(position + .5, bottom);
381 line->end->
setCoords(position + .5, top);
385void FITSStretchUI::setCursors(
const StretchParams ¶ms)
389 auto data = m_View->imageData();
394void FITSStretchUI::removeCursors()
396 if (minCursor !=
nullptr)
400 if (maxCursor !=
nullptr)
405void FITSStretchUI::generateHistogram()
407 if (!m_View->imageData()->isHistogramConstructed())
408 m_View->imageData()->constructHistogram();
409 if (m_View->imageData()->isHistogramConstructed())
412 const int nChannels = m_View->imageData()->channels();
420 graph->setVisible(
true);
423 color = i == 0 ?
QColor(255, 0, 0) : ((i == 1) ?
QColor(0, 255, 0, 225) :
QColor(0, 0, 255, 175));
424 graph->setBrush(
QBrush(color));
425 graph->setPen(
QPen(color));
426 const QVector<double> &h = m_View->imageData()->getHistogramFrequency(i);
427 const int size = m_View->imageData()->getHistogramBinCount();
429 graph->addData(
j,
log1p(h[
j]));
432 histoPlot->xAxis->setRange(0, m_View->imageData()->getHistogramBinCount() + 1);
446 if (!m_View || !m_View->imageData() || !m_View->imageData()->isHistogramConstructed()) return;
447 const double histogramSize = m_View->imageData()->getHistogramBinCount();
448 double tLower = newRange.lower;
449 double tUpper = newRange.upper;
450 if (tLower < 0) tLower = 0;
451 if (tUpper > histogramSize + 1) tUpper = histogramSize + 1;
452 if (tLower != newRange.lower || tUpper != newRange.upper)
453 histoPlot->xAxis->setRange(tLower, tUpper);
457void FITSStretchUI::setStretchValues(
double shadows,
double midtones,
double highlights)
459 StretchParams params = m_View->getStretchParams();
460 params.grey_red.shadows = shadows;
461 params.grey_red.midtones = midtones;
462 params.grey_red.highlights = highlights;
464 m_View->setPreviewSampling(0);
465 m_View->setStretchParams(params);
Manages a single axis inside a QCustomPlot.
void rangeChanged(const QCPRange &newRange)
void setTickLabelColor(const QColor &color)
void setLabelColor(const QColor &color)
void setBasePen(const QPen &pen)
void setTickPen(const QPen &pen)
void setSubTickPen(const QPen &pen)
@ lsStepLeft
line is drawn as steps where the step height is the value of the left data point
void setZeroLinePen(const QPen &pen)
void setSubGridPen(const QPen &pen)
void setPen(const QPen &pen)
A line from one point to another.
void setPen(const QPen &pen)
void setCoords(double key, double value)
Represents the range an axis is encompassing.
void mouseMove(QMouseEvent *event)
void mouseDoubleClick(QMouseEvent *event)
void maximumPositionChanged(int max)
This signal is emitted when sliderDown is true and the slider moves.
void minimumPositionChanged(int min)
This signal is emitted when sliderDown is true and the slider moves.
void midPositionChanged(int max)
This signal is emitted when sliderDown is true and the slider moves.
void information(QWidget *parent, const QString &text, const QString &title=QString(), const QString &dontShowAgainName=QString(), Options options=Notify)
@ iRangeDrag
0x001 Axis ranges are draggable (see QCPAxisRect::setRangeDrag, QCPAxisRect::setRangeDragAxes)
@ iRangeZoom
0x002 Axis ranges are zoomable with the mouse wheel (see QCPAxisRect::setRangeZoom,...
QIcon fromTheme(const QString &name)
QMetaObject::Connection connect(const QObject *sender, PointerToMemberFunction signal, Functor functor)
QString & append(QChar ch)
QString arg(Args &&... args) const const
qsizetype size() const const
QFuture< ArgsType< Signal > > connect(Sender *sender, Signal signal)
void showText(const QPoint &pos, const QString &text, QWidget *w, const QRect &rect, int msecDisplayTime)