modify flipbook histogram
This commit is contained in:
parent
f8e8df4fa1
commit
8b5a413d51
9 changed files with 491 additions and 126 deletions
|
@ -66,7 +66,10 @@ public:
|
||||||
// per pli come sopra, ma ritorna il maincolor
|
// per pli come sopra, ma ritorna il maincolor
|
||||||
// per tzp e fullcolor ritorna il colore effettivo del pixel
|
// per tzp e fullcolor ritorna il colore effettivo del pixel
|
||||||
TPixel32 pickColor(const TPointD &point, double radius, double scale2) const;
|
TPixel32 pickColor(const TPointD &point, double radius, double scale2) const;
|
||||||
|
TPixel64 pickColor16(const TPointD &point, double radius,
|
||||||
|
double scale2) const;
|
||||||
TPixel32 pickAverageColor(const TRectD &rect) const;
|
TPixel32 pickAverageColor(const TRectD &rect) const;
|
||||||
|
TPixel64 pickAverageColor16(const TRectD &rect) const;
|
||||||
|
|
||||||
// ritorna il colore medio presente nell'area della finestra corrente openGL
|
// ritorna il colore medio presente nell'area della finestra corrente openGL
|
||||||
TPixel32 pickColor(const TRectD &area) const;
|
TPixel32 pickColor(const TRectD &area) const;
|
||||||
|
@ -80,5 +83,4 @@ public:
|
||||||
// il valore di ritorno si riferisce all'eventuale raster: (0,0)==leftbottom
|
// il valore di ritorno si riferisce all'eventuale raster: (0,0)==leftbottom
|
||||||
TPoint getRasterPoint(const TPointD &p) const;
|
TPoint getRasterPoint(const TPointD &p) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -44,14 +44,21 @@ class QLabel;
|
||||||
|
|
||||||
class DVAPI ComboHistoRGBLabel final : public QWidget {
|
class DVAPI ComboHistoRGBLabel final : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
enum DisplayMode { Display_8bit = 0, Display_16bit, Display_0_1 };
|
||||||
|
|
||||||
|
private:
|
||||||
QColor m_color;
|
QColor m_color;
|
||||||
|
|
||||||
|
DisplayMode m_mode;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ComboHistoRGBLabel(QColor color, QWidget *parent);
|
ComboHistoRGBLabel(QColor color, QWidget *parent);
|
||||||
|
|
||||||
~ComboHistoRGBLabel() {}
|
~ComboHistoRGBLabel() {}
|
||||||
|
|
||||||
void setColorAndUpdate(QColor color);
|
void setColorAndUpdate(QColor color);
|
||||||
|
void setDisplayMode(DisplayMode mode) { m_mode = mode; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *pe) override;
|
void paintEvent(QPaintEvent *pe) override;
|
||||||
|
@ -62,17 +69,20 @@ protected:
|
||||||
class DVAPI ChannelHistoGraph : public QWidget {
|
class DVAPI ChannelHistoGraph : public QWidget {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
QVector<int> m_values;
|
QVector<int> m_values[2]; // 0: current raster 1: snapshot
|
||||||
|
int m_maxValue[2];
|
||||||
|
|
||||||
int m_pickedValue;
|
int m_pickedValue;
|
||||||
|
int m_channelIndex;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int *m_channelValuePtr;
|
bool *m_showComparePtr;
|
||||||
|
|
||||||
ChannelHistoGraph(QWidget *parent = 0, int *channelValue = 0);
|
ChannelHistoGraph(int index, QWidget *parent = nullptr,
|
||||||
|
bool *showComparePtr = nullptr);
|
||||||
~ChannelHistoGraph();
|
~ChannelHistoGraph();
|
||||||
|
|
||||||
virtual void setValues();
|
virtual void setValues(int *buf, bool isComp);
|
||||||
|
|
||||||
void showCurrentChannelValue(int val);
|
void showCurrentChannelValue(int val);
|
||||||
|
|
||||||
|
@ -90,10 +100,10 @@ class DVAPI RGBHistoGraph final : public ChannelHistoGraph {
|
||||||
QImage m_histoImg;
|
QImage m_histoImg;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RGBHistoGraph(QWidget *parent = 0, int *channelValue = 0);
|
RGBHistoGraph(int index, QWidget *parent = 0);
|
||||||
~RGBHistoGraph();
|
~RGBHistoGraph();
|
||||||
|
|
||||||
void setValues() override;
|
void setValues(int *buf, bool isComp) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
|
@ -121,10 +131,12 @@ class DVAPI ChannelHisto final : public QWidget {
|
||||||
ChannelColorBar *m_colorBar;
|
ChannelColorBar *m_colorBar;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ChannelHisto(int channelIndex, int *channelValue, QWidget *parent = 0);
|
ChannelHisto(int channelIndex, bool *showComparePtr, QWidget *parent = 0);
|
||||||
~ChannelHisto() {}
|
~ChannelHisto() {}
|
||||||
|
|
||||||
void refleshValue() { m_histogramGraph->setValues(); }
|
void refleshValue(int *buf, bool isComp = false) {
|
||||||
|
m_histogramGraph->setValues(buf, isComp);
|
||||||
|
}
|
||||||
|
|
||||||
void showCurrentChannelValue(int val);
|
void showCurrentChannelValue(int val);
|
||||||
|
|
||||||
|
@ -153,6 +165,12 @@ class DVAPI ComboHistogram final : public QWidget {
|
||||||
QLabel *m_xPosLabel;
|
QLabel *m_xPosLabel;
|
||||||
QLabel *m_yPosLabel;
|
QLabel *m_yPosLabel;
|
||||||
|
|
||||||
|
QComboBox *m_displayModeCombo;
|
||||||
|
|
||||||
|
bool m_showCompare;
|
||||||
|
bool m_compHistoIsValid;
|
||||||
|
int m_channelValueComp[4][COMBOHIST_RESOLUTION_W];
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ComboHistogram(QWidget *parent = 0);
|
ComboHistogram(QWidget *parent = 0);
|
||||||
~ComboHistogram();
|
~ComboHistogram();
|
||||||
|
@ -160,10 +178,27 @@ public:
|
||||||
TRasterP getRaster() const { return m_raster; }
|
TRasterP getRaster() const { return m_raster; }
|
||||||
void setRaster(const TRasterP &raster, const TPaletteP &palette = 0);
|
void setRaster(const TRasterP &raster, const TPaletteP &palette = 0);
|
||||||
void updateInfo(const TPixel32 &pix, const TPointD &imagePos);
|
void updateInfo(const TPixel32 &pix, const TPointD &imagePos);
|
||||||
|
void updateInfo(const TPixel64 &pix, const TPointD &imagePos);
|
||||||
void updateAverageColor(const TPixel32 &pix);
|
void updateAverageColor(const TPixel32 &pix);
|
||||||
|
void updateAverageColor(const TPixel64 &pix);
|
||||||
|
void updateCompHistogram();
|
||||||
|
|
||||||
|
void setShowCompare(bool on) {
|
||||||
|
m_showCompare = on;
|
||||||
|
if (isVisible() && !m_compHistoIsValid) updateCompHistogram();
|
||||||
|
}
|
||||||
|
void invalidateCompHisto() {
|
||||||
|
m_compHistoIsValid = false;
|
||||||
|
if (isVisible() && m_showCompare) updateCompHistogram();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void computeChannelsValue();
|
void computeChannelsValue(int *buf, size_t size, TRasterP ras,
|
||||||
|
TPalette *extPlt = nullptr);
|
||||||
|
void showEvent(QShowEvent *) override;
|
||||||
|
|
||||||
|
protected slots:
|
||||||
|
void onDisplayModeChanged();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -172,6 +172,27 @@ TPixel32 StylePicker::pickColor(const TPointD &pos, double radius,
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
TPixel64 StylePicker::pickColor16(const TPointD &pos, double radius,
|
||||||
|
double scale2) const {
|
||||||
|
TToonzImageP ti = m_image;
|
||||||
|
TRasterImageP ri = m_image;
|
||||||
|
TVectorImageP vi = m_image;
|
||||||
|
assert(ri && !ti && !vi);
|
||||||
|
if (!ri || ti || vi) return TPixel64::Transparent;
|
||||||
|
|
||||||
|
TRasterP raster = ri->getRaster();
|
||||||
|
if (raster->getPixelSize() != 8) return TPixel64::Transparent;
|
||||||
|
|
||||||
|
TPoint point = getRasterPoint(pos);
|
||||||
|
if (!raster->getBounds().contains(point)) return TPixel64::Transparent;
|
||||||
|
|
||||||
|
TRaster64P raster64 = raster;
|
||||||
|
if (!raster64) return TPixel64::Transparent;
|
||||||
|
|
||||||
|
return raster64->pixels(point.y)[point.x];
|
||||||
|
}
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
TPixel32 StylePicker::pickAverageColor(const TRectD &rect) const {
|
TPixel32 StylePicker::pickAverageColor(const TRectD &rect) const {
|
||||||
TRasterImageP ri = m_image;
|
TRasterImageP ri = m_image;
|
||||||
assert(ri);
|
assert(ri);
|
||||||
|
@ -216,8 +237,50 @@ TPixel32 StylePicker::pickAverageColor(const TRectD &rect) const {
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
||||||
namespace {
|
TPixel64 StylePicker::pickAverageColor16(const TRectD &rect) const {
|
||||||
|
TRasterImageP ri = m_image;
|
||||||
|
assert(ri);
|
||||||
|
if (!ri) return TPixel64::Transparent;
|
||||||
|
TRasterP raster;
|
||||||
|
raster = ri->getRaster();
|
||||||
|
if (raster->getPixelSize() != 8) return TPixel64::Transparent;
|
||||||
|
|
||||||
|
TPoint topLeft = getRasterPoint(rect.getP00());
|
||||||
|
TPoint bottomRight = getRasterPoint(rect.getP11());
|
||||||
|
|
||||||
|
if (!raster->getBounds().overlaps(TRect(topLeft, bottomRight)))
|
||||||
|
return TPixel64::Transparent;
|
||||||
|
|
||||||
|
topLeft.x = std::max(0, topLeft.x);
|
||||||
|
topLeft.y = std::max(0, topLeft.y);
|
||||||
|
bottomRight.x = std::min(raster->getLx(), bottomRight.x);
|
||||||
|
bottomRight.y = std::min(raster->getLy(), bottomRight.y);
|
||||||
|
|
||||||
|
TRaster64P raster64 = raster;
|
||||||
|
assert(raster64);
|
||||||
|
if (!raster64) return TPixel64::Transparent;
|
||||||
|
|
||||||
|
UINT r = 0, g = 0, b = 0, m = 0, size = 0;
|
||||||
|
for (int y = topLeft.y; y < bottomRight.y; y++) {
|
||||||
|
TPixel64 *p = &raster64->pixels(y)[topLeft.x];
|
||||||
|
for (int x = topLeft.x; x < bottomRight.x; x++, p++) {
|
||||||
|
r += p->r;
|
||||||
|
g += p->g;
|
||||||
|
b += p->b;
|
||||||
|
m += p->m;
|
||||||
|
size++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (size)
|
||||||
|
return TPixel64(r / size, g / size, b / size, m / size);
|
||||||
|
else
|
||||||
|
return TPixel64::Transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------------------------------------
|
||||||
|
|
||||||
|
namespace {
|
||||||
TPixel32 getAverageColor(const TRect &rect) {
|
TPixel32 getAverageColor(const TRect &rect) {
|
||||||
GLenum fmt =
|
GLenum fmt =
|
||||||
#if defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM)
|
#if defined(TNZ_MACHINE_CHANNEL_ORDER_BGRM)
|
||||||
|
@ -234,8 +297,8 @@ TPixel32 getAverageColor(const TRect &rect) {
|
||||||
#endif
|
#endif
|
||||||
UINT r = 0, g = 0, b = 0, m = 0;
|
UINT r = 0, g = 0, b = 0, m = 0;
|
||||||
std::vector<TPixel32> buffer(rect.getLx() * rect.getLy());
|
std::vector<TPixel32> buffer(rect.getLx() * rect.getLy());
|
||||||
glReadPixels(rect.x0, rect.y0, rect.getLx(), rect.getLy(), fmt,
|
glReadPixels(rect.x0, rect.y0, rect.getLx(), rect.getLy(), fmt, TGL_TYPE,
|
||||||
GL_UNSIGNED_BYTE, &buffer[0]);
|
&buffer[0]);
|
||||||
int size = rect.getLx() * rect.getLy();
|
int size = rect.getLx() * rect.getLy();
|
||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
r += buffer[i].r;
|
r += buffer[i].r;
|
||||||
|
@ -243,7 +306,7 @@ TPixel32 getAverageColor(const TRect &rect) {
|
||||||
b += buffer[i].b;
|
b += buffer[i].b;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TPixel32(b / size, g / size, r / size, 255);
|
return TPixel32(b / size, g / size, r / size, TPixel32::maxChannelValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------
|
//---------------------------------------------------------
|
||||||
|
|
|
@ -791,15 +791,19 @@ void FlipBook::onButtonPressed(FlipConsole::EGadget button) {
|
||||||
clonedImg->setPalette(ti->getPalette());
|
clonedImg->setPalette(ti->getPalette());
|
||||||
}
|
}
|
||||||
TImageCache::instance()->add(QString("TnzCompareImg"), clonedImg);
|
TImageCache::instance()->add(QString("TnzCompareImg"), clonedImg);
|
||||||
|
// to update the histogram of compare snapshot image
|
||||||
|
m_imageViewer->invalidateCompHisto();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case FlipConsole::eCompare:
|
case FlipConsole::eCompare:
|
||||||
if ((TVectorImageP)getCurrentImage(m_flipConsole->getCurrentFrame())) {
|
if (m_flipConsole->isChecked(FlipConsole::eCompare) &&
|
||||||
|
(TVectorImageP)getCurrentImage(m_flipConsole->getCurrentFrame())) {
|
||||||
DVGui::warning(
|
DVGui::warning(
|
||||||
tr("It is not possible to take or compare snapshots for Toonz vector "
|
tr("It is not possible to take or compare snapshots for Toonz vector "
|
||||||
"levels."));
|
"levels."));
|
||||||
m_flipConsole->setChecked(FlipConsole::eCompare, false);
|
// cancel the button pressing
|
||||||
|
m_flipConsole->pressButton(FlipConsole::eCompare);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -45,6 +45,7 @@ HistogramPopup::HistogramPopup(QString title)
|
||||||
mainLay->setSpacing(0);
|
mainLay->setSpacing(0);
|
||||||
{ mainLay->addWidget(m_histogram); }
|
{ mainLay->addWidget(m_histogram); }
|
||||||
setLayout(mainLay);
|
setLayout(mainLay);
|
||||||
|
mainLay->setSizeConstraint(QLayout::SetFixedSize);
|
||||||
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,18 +75,37 @@ void HistogramPopup::setImage(TImageP image) {
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/*! show the picked color
|
/*! show the picked color
|
||||||
*/
|
*/
|
||||||
void HistogramPopup::updateInfo(const TPixel32 &pix, const TPointD &imagePos) {
|
void HistogramPopup::updateInfo(const TPixel32 &pix, const TPointD &imagePos) {
|
||||||
m_histogram->updateInfo(pix, imagePos);
|
m_histogram->updateInfo(pix, imagePos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistogramPopup::updateInfo(const TPixel64 &pix, const TPointD &imagePos) {
|
||||||
|
m_histogram->updateInfo(pix, imagePos);
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
/*! show the average-picked color
|
/*! show the average-picked color
|
||||||
*/
|
*/
|
||||||
void HistogramPopup::updateAverageColor(const TPixel32 &pix) {
|
void HistogramPopup::updateAverageColor(const TPixel32 &pix) {
|
||||||
m_histogram->updateAverageColor(pix);
|
m_histogram->updateAverageColor(pix);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void HistogramPopup::updateAverageColor(const TPixel64 &pix) {
|
||||||
|
m_histogram->updateAverageColor(pix);
|
||||||
|
}
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void HistogramPopup::setShowCompare(bool on) {
|
||||||
|
m_histogram->setShowCompare(on);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void HistogramPopup::invalidateCompHisto() {
|
||||||
|
m_histogram->invalidateCompHisto();
|
||||||
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
/*! \class ViewerHistogramPopup
|
/*! \class ViewerHistogramPopup
|
||||||
\brief The ViewerHistogramPopup show the histogram pertain to
|
\brief The ViewerHistogramPopup show the histogram pertain to
|
||||||
|
|
|
@ -27,7 +27,11 @@ public:
|
||||||
void setImage(TImageP image);
|
void setImage(TImageP image);
|
||||||
|
|
||||||
void updateInfo(const TPixel32 &pix, const TPointD &imagePos);
|
void updateInfo(const TPixel32 &pix, const TPointD &imagePos);
|
||||||
|
void updateInfo(const TPixel64 &pix, const TPointD &imagePos);
|
||||||
void updateAverageColor(const TPixel32 &pix);
|
void updateAverageColor(const TPixel32 &pix);
|
||||||
|
void updateAverageColor(const TPixel64 &pix);
|
||||||
|
void setShowCompare(bool on);
|
||||||
|
void invalidateCompHisto();
|
||||||
};
|
};
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
|
|
@ -370,6 +370,10 @@ void ImageViewer::contextMenuEvent(QContextMenuEvent *event) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ImageViewer::setVisual(const ImagePainter::VisualSettings &settings) {
|
void ImageViewer::setVisual(const ImagePainter::VisualSettings &settings) {
|
||||||
|
if (m_isHistogramEnable && m_histogramPopup &&
|
||||||
|
settings.m_doCompare != m_visualSettings.m_doCompare) {
|
||||||
|
m_histogramPopup->setShowCompare(settings.m_doCompare);
|
||||||
|
}
|
||||||
m_visualSettings = settings;
|
m_visualSettings = settings;
|
||||||
m_visualSettings.m_sceneProperties =
|
m_visualSettings.m_sceneProperties =
|
||||||
TApp::instance()->getCurrentScene()->getScene()->getProperties();
|
TApp::instance()->getCurrentScene()->getScene()->getProperties();
|
||||||
|
@ -857,7 +861,10 @@ void ImageViewer::mouseMoveEvent(QMouseEvent *event) {
|
||||||
|
|
||||||
if (m_rectRGBPick) {
|
if (m_rectRGBPick) {
|
||||||
update();
|
update();
|
||||||
rectPickColor();
|
// do not pick vector image while dragging as a portion of the red
|
||||||
|
// rubber band may affect the result
|
||||||
|
TImageP img = getPickedImage(m_pos);
|
||||||
|
if (img && img->raster()) rectPickColor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -941,34 +948,48 @@ void ImageViewer::pickColor(QMouseEvent *event, bool putValueToStyleEditor) {
|
||||||
|
|
||||||
StylePicker picker(img);
|
StylePicker picker(img);
|
||||||
|
|
||||||
TPointD mousePos = TPointD(curPos.x(), height() - 1 - curPos.y());
|
|
||||||
TRectD area = TRectD(mousePos.x, mousePos.y, mousePos.x, mousePos.y);
|
|
||||||
|
|
||||||
TPointD pos =
|
TPointD pos =
|
||||||
getViewAff().inv() * TPointD(curPos.x() - (qreal)(width()) / 2,
|
getViewAff().inv() * TPointD(curPos.x() - (qreal)(width()) / 2,
|
||||||
-curPos.y() + (qreal)(height()) / 2);
|
-curPos.y() + (qreal)(height()) / 2);
|
||||||
|
|
||||||
TRectD imgRect = (img->raster()) ? convert(TRect(img->raster()->getSize()))
|
TRectD imgRect = (img->raster()) ? convert(TRect(img->raster()->getSize()))
|
||||||
: img->getBBox();
|
: img->getBBox();
|
||||||
TPointD imagePos =
|
TPointD imagePos = (img->raster()) ? TPointD(0.5 * imgRect.getLx() + pos.x,
|
||||||
TPointD(0.5 * imgRect.getLx() + pos.x, 0.5 * imgRect.getLy() + pos.y);
|
0.5 * imgRect.getLy() + pos.y)
|
||||||
|
: pos;
|
||||||
|
|
||||||
TPixel32 pix;
|
if (!imgRect.contains(imagePos)) {
|
||||||
if (m_lutCalibrator && m_lutCalibrator->isValid()) {
|
// throw transparent color if picking outside of the image
|
||||||
|
m_histogramPopup->updateInfo(TPixel32::Transparent, TPointD(-1, -1));
|
||||||
|
} else if (!img->raster()) { // vector image
|
||||||
|
// For unknown reasons, glReadPixels is covering the entire window not the
|
||||||
|
// OpenGL widget.
|
||||||
|
QPointF winPos = event->windowPos() * getDevPixRatio();
|
||||||
|
TPointD mousePos =
|
||||||
|
TPointD(winPos.x(), (double)(window()->height()) - winPos.y());
|
||||||
|
TRectD area = TRectD(mousePos.x, mousePos.y, mousePos.x, mousePos.y);
|
||||||
|
TPixel32 pix = picker.pickColor(area);
|
||||||
|
m_histogramPopup->updateInfo(pix, imagePos);
|
||||||
|
if (putValueToStyleEditor) setPickedColorToStyleEditor(pix);
|
||||||
|
} else if (img->raster()->getPixelSize() == 8) // 16bpc raster
|
||||||
|
{
|
||||||
// for specifying pixel range on picking vector
|
// for specifying pixel range on picking vector
|
||||||
double scale2 = getViewAff().det();
|
double scale2 = getViewAff().det();
|
||||||
pix = picker.pickColor(pos + TPointD(-0.5, -0.5), 10.0, scale2);
|
TPixel64 pix = picker.pickColor16(pos + TPointD(-0.5, -0.5), 10.0, scale2);
|
||||||
} else
|
|
||||||
pix = picker.pickColor(area);
|
// throw the picked color to the histogram
|
||||||
|
m_histogramPopup->updateInfo(pix, imagePos);
|
||||||
|
// throw it to the style editor as well
|
||||||
|
if (putValueToStyleEditor) setPickedColorToStyleEditor(toPixel32(pix));
|
||||||
|
} else { // 8bpc raster
|
||||||
|
// for specifying pixel range on picking vector
|
||||||
|
double scale2 = getViewAff().det();
|
||||||
|
TPixel32 pix = picker.pickColor(pos + TPointD(-0.5, -0.5), 10.0, scale2);
|
||||||
|
|
||||||
if (!img->raster() || imgRect.contains(imagePos)) {
|
|
||||||
// throw the picked color to the histogram
|
// throw the picked color to the histogram
|
||||||
m_histogramPopup->updateInfo(pix, imagePos);
|
m_histogramPopup->updateInfo(pix, imagePos);
|
||||||
// throw it to the style editor as well
|
// throw it to the style editor as well
|
||||||
if (putValueToStyleEditor) setPickedColorToStyleEditor(pix);
|
if (putValueToStyleEditor) setPickedColorToStyleEditor(pix);
|
||||||
} else {
|
|
||||||
// throw transparent color if picking outside of the image
|
|
||||||
m_histogramPopup->updateInfo(TPixel32::Transparent, TPointD(-1, -1));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -996,6 +1017,28 @@ void ImageViewer::rectPickColor(bool putValueToStyleEditor) {
|
||||||
|
|
||||||
StylePicker picker(img);
|
StylePicker picker(img);
|
||||||
|
|
||||||
|
if (!img->raster()) { // vector image
|
||||||
|
TPointD pressedWinPos = convert(m_pressedMousePos) + m_winPosMousePosOffset;
|
||||||
|
TPointD startPos = TPointD(pressedWinPos.x,
|
||||||
|
(double)(window()->height()) - pressedWinPos.y);
|
||||||
|
TPointD currentWinPos =
|
||||||
|
TPointD(m_pos.x(), m_pos.y()) + m_winPosMousePosOffset;
|
||||||
|
TPointD endPos = TPointD(currentWinPos.x,
|
||||||
|
(double)(window()->height()) - currentWinPos.y);
|
||||||
|
TRectD area = TRectD(startPos, endPos);
|
||||||
|
area = area.enlarge(-4, -4);
|
||||||
|
if (area.getLx() < 2 || area.getLy() < 2) {
|
||||||
|
m_histogramPopup->updateAverageColor(TPixel32::Transparent);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
TPixel32 pix = picker.pickColor(area);
|
||||||
|
// throw the picked color to the histogram
|
||||||
|
m_histogramPopup->updateAverageColor(pix);
|
||||||
|
// throw it to the style editor as well
|
||||||
|
if (putValueToStyleEditor) setPickedColorToStyleEditor(pix);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
TPoint startPos =
|
TPoint startPos =
|
||||||
TPoint(m_pressedMousePos.x, height() - 1 - m_pressedMousePos.y);
|
TPoint(m_pressedMousePos.x, height() - 1 - m_pressedMousePos.y);
|
||||||
TPoint endPos = TPoint(m_pos.x(), height() - 1 - m_pos.y());
|
TPoint endPos = TPoint(m_pos.x(), height() - 1 - m_pos.y());
|
||||||
|
@ -1005,21 +1048,25 @@ void ImageViewer::rectPickColor(bool putValueToStyleEditor) {
|
||||||
m_histogramPopup->updateAverageColor(TPixel32::Transparent);
|
m_histogramPopup->updateAverageColor(TPixel32::Transparent);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
TPointD start = getViewAff().inv() *
|
||||||
|
TPointD(startPos.x - width() / 2, startPos.y - height() / 2);
|
||||||
|
TPointD end = getViewAff().inv() *
|
||||||
|
TPointD(endPos.x - width() / 2, endPos.y - height() / 2);
|
||||||
|
|
||||||
TPixel32 pix;
|
if (img->raster()->getPixelSize() == 8) // 16bpc raster
|
||||||
if (m_lutCalibrator && m_lutCalibrator->isValid() && isRas32(img)) {
|
{
|
||||||
TPointD start = getViewAff().inv() * TPointD(startPos.x - width() / 2,
|
TPixel64 pix = picker.pickAverageColor16(TRectD(start, end));
|
||||||
startPos.y - height() / 2);
|
// throw the picked color to the histogram
|
||||||
TPointD end = getViewAff().inv() *
|
m_histogramPopup->updateAverageColor(pix);
|
||||||
TPointD(endPos.x - width() / 2, endPos.y - height() / 2);
|
// throw it to the style editor as well
|
||||||
pix = picker.pickAverageColor(TRectD(start, end));
|
if (putValueToStyleEditor) setPickedColorToStyleEditor(toPixel32(pix));
|
||||||
} else
|
} else { // 8bpc raster
|
||||||
pix = picker.pickColor(area.enlarge(-1, -1));
|
TPixel32 pix = picker.pickAverageColor(TRectD(start, end));
|
||||||
|
// throw the picked color to the histogram
|
||||||
// throw the picked color to the histogram
|
m_histogramPopup->updateAverageColor(pix);
|
||||||
m_histogramPopup->updateAverageColor(pix);
|
// throw it to the style editor as well
|
||||||
// throw it to the style editor as well
|
if (putValueToStyleEditor) setPickedColorToStyleEditor(pix);
|
||||||
if (putValueToStyleEditor) setPickedColorToStyleEditor(pix);
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1087,6 +1134,9 @@ void ImageViewer::mousePressEvent(QMouseEvent *event) {
|
||||||
m_mouseButton = event->button();
|
m_mouseButton = event->button();
|
||||||
m_draggingZoomSelection = false;
|
m_draggingZoomSelection = false;
|
||||||
|
|
||||||
|
QPointF winPosMousePos = event->windowPos() * getDevPixRatio() - m_pos;
|
||||||
|
m_winPosMousePosOffset = TPointD(winPosMousePos.x(), winPosMousePos.y());
|
||||||
|
|
||||||
if (m_mouseButton != Qt::LeftButton) {
|
if (m_mouseButton != Qt::LeftButton) {
|
||||||
event->ignore();
|
event->ignore();
|
||||||
return;
|
return;
|
||||||
|
@ -1332,6 +1382,13 @@ void ImageViewer::changeSwapBehavior(bool enable) {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ImageViewer::invalidateCompHisto() {
|
||||||
|
if (!m_isHistogramEnable || !m_histogramPopup) return;
|
||||||
|
m_histogramPopup->invalidateCompHisto();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ImageViewer::keyPressEvent(QKeyEvent *event) {
|
void ImageViewer::keyPressEvent(QKeyEvent *event) {
|
||||||
if (FlipZoomer(this).exec(event)) return;
|
if (FlipZoomer(this).exec(event)) return;
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,11 @@ class ImageViewer final : public GLWidgetForHighDpi {
|
||||||
FlipBook *m_flipbook;
|
FlipBook *m_flipbook;
|
||||||
TPoint m_pressedMousePos;
|
TPoint m_pressedMousePos;
|
||||||
|
|
||||||
|
// Modifying rect-picking positon offset for vector image.
|
||||||
|
// For unknown reasons, glReadPixels is covering the entire window not the
|
||||||
|
// OpenGL widget.
|
||||||
|
TPointD m_winPosMousePosOffset;
|
||||||
|
|
||||||
Qt::MouseButton m_mouseButton;
|
Qt::MouseButton m_mouseButton;
|
||||||
bool m_draggingZoomSelection;
|
bool m_draggingZoomSelection;
|
||||||
|
|
||||||
|
@ -125,6 +130,7 @@ public:
|
||||||
|
|
||||||
void doSwapBuffers();
|
void doSwapBuffers();
|
||||||
void changeSwapBehavior(bool enable);
|
void changeSwapBehavior(bool enable);
|
||||||
|
void invalidateCompHisto();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void contextMenuEvent(QContextMenuEvent *event) override;
|
void contextMenuEvent(QContextMenuEvent *event) override;
|
||||||
|
|
|
@ -12,44 +12,68 @@
|
||||||
#include "toonz/preferences.h"
|
#include "toonz/preferences.h"
|
||||||
#include "toonzqt/lutcalibrator.h"
|
#include "toonzqt/lutcalibrator.h"
|
||||||
#include "toonzqt/gutil.h"
|
#include "toonzqt/gutil.h"
|
||||||
|
#include "timagecache.h"
|
||||||
|
#include "trasterimage.h"
|
||||||
|
|
||||||
|
// TnzBase includes
|
||||||
|
#include "tenv.h"
|
||||||
|
|
||||||
#include <QPushButton>
|
#include <QPushButton>
|
||||||
#include <QDialog>
|
#include <QDialog>
|
||||||
|
|
||||||
|
TEnv::IntVar HistogramChannelDisplayMode(
|
||||||
|
"HistogramChannelDisplayMode",
|
||||||
|
(int)ComboHistoRGBLabel::Display_8bit); // 8bit display by default
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
inline int idx(int y, int x) { return y * COMBOHIST_RESOLUTION_W + x; }
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// ChannelHistoGraph
|
// ChannelHistoGraph
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ChannelHistoGraph::ChannelHistoGraph(QWidget *parent, int *channelValue)
|
ChannelHistoGraph::ChannelHistoGraph(int index, QWidget *parent,
|
||||||
: QWidget(parent), m_channelValuePtr(channelValue), m_pickedValue(-1) {
|
bool *showComparePtr)
|
||||||
|
: QWidget(parent)
|
||||||
|
, m_showComparePtr(showComparePtr)
|
||||||
|
, m_channelIndex(index)
|
||||||
|
, m_pickedValue(-1) {
|
||||||
// width 256+2 pixels, height 100+2 pixels (with margin)
|
// width 256+2 pixels, height 100+2 pixels (with margin)
|
||||||
setFixedSize(COMBOHIST_RESOLUTION_W + 2, COMBOHIST_RESOLUTION_H + 2);
|
setFixedSize(COMBOHIST_RESOLUTION_W + 2, COMBOHIST_RESOLUTION_H + 2);
|
||||||
m_values.reserve(COMBOHIST_RESOLUTION_W);
|
m_values[0].reserve(COMBOHIST_RESOLUTION_W);
|
||||||
|
m_values[1].reserve(COMBOHIST_RESOLUTION_W);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ChannelHistoGraph::~ChannelHistoGraph() { m_values.clear(); }
|
ChannelHistoGraph::~ChannelHistoGraph() {
|
||||||
|
m_values[0].clear();
|
||||||
|
m_values[1].clear();
|
||||||
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ChannelHistoGraph::setValues() {
|
void ChannelHistoGraph::setValues(int *buf, bool isComp) {
|
||||||
m_values.clear();
|
int id = (isComp) ? 1 : 0;
|
||||||
m_values.resize(COMBOHIST_RESOLUTION_W);
|
m_values[id].clear();
|
||||||
|
m_values[id].resize(COMBOHIST_RESOLUTION_W);
|
||||||
|
m_maxValue[id] = 1;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
// normalize with the maximum value
|
// normalize with the maximum value
|
||||||
int maxValue = 1;
|
int maxValue = 1;
|
||||||
for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
||||||
int count = m_channelValuePtr[i];
|
m_values[id][i] = buf[i];
|
||||||
if (maxValue < count) maxValue = count;
|
if (m_maxValue[id] < buf[i]) m_maxValue[id] = buf[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
// for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
||||||
int v = m_channelValuePtr[i];
|
// int v = buf[i];
|
||||||
m_values[i] =
|
// m_values[id][i] =
|
||||||
tround((double)(v * COMBOHIST_RESOLUTION_H) / (double)maxValue);
|
// tround((double)(v * COMBOHIST_RESOLUTION_H) / (double)maxValue);
|
||||||
}
|
//}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -71,23 +95,41 @@ void ChannelHistoGraph::paintEvent(QPaintEvent *event) {
|
||||||
p.drawLine(posx, 1, posx, COMBOHIST_RESOLUTION_H);
|
p.drawLine(posx, 1, posx, COMBOHIST_RESOLUTION_H);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_values.size() == 0) return;
|
QColor compColor = (m_channelIndex == 0)
|
||||||
|
? Qt::red
|
||||||
|
: (m_channelIndex == 1)
|
||||||
|
? Qt::green
|
||||||
|
: (m_channelIndex == 2) ? Qt::blue : Qt::magenta;
|
||||||
|
compColor.setAlpha(120);
|
||||||
|
|
||||||
p.setPen(Qt::black);
|
int maxValue = m_maxValue[0];
|
||||||
|
if (!m_values[1].isEmpty() && m_showComparePtr && *m_showComparePtr &&
|
||||||
|
m_maxValue[0] < m_maxValue[1])
|
||||||
|
maxValue = m_maxValue[1];
|
||||||
|
|
||||||
// draw each histogram
|
p.translate(0, COMBOHIST_RESOLUTION_H);
|
||||||
for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
p.scale(1.0, -(double)COMBOHIST_RESOLUTION_H / (double)maxValue);
|
||||||
int v = m_values[i];
|
|
||||||
if (v <= 0) continue;
|
|
||||||
int x = 1 + i;
|
|
||||||
p.drawLine(x, COMBOHIST_RESOLUTION_H + 1 - v, x, COMBOHIST_RESOLUTION_H);
|
|
||||||
}
|
|
||||||
|
|
||||||
// draw picked color's channel value
|
for (int id = 0; id < 2; id++) {
|
||||||
if (m_pickedValue > -1) {
|
if (m_values[id].isEmpty()) continue;
|
||||||
p.setPen(Qt::white);
|
if (id == 1 && (!m_showComparePtr || !(*m_showComparePtr))) continue;
|
||||||
int x = 1 + m_pickedValue;
|
|
||||||
p.drawLine(x, 1, x, COMBOHIST_RESOLUTION_H);
|
p.setPen((id == 0) ? Qt::black : compColor);
|
||||||
|
|
||||||
|
// draw each histogram
|
||||||
|
for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
||||||
|
int v = m_values[id][i];
|
||||||
|
if (v <= 0) continue;
|
||||||
|
int x = 1 + i;
|
||||||
|
p.drawLine(x, 0, x, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
// draw picked color's channel value
|
||||||
|
if (m_pickedValue > -1) {
|
||||||
|
p.setPen(Qt::white);
|
||||||
|
int x = 1 + m_pickedValue;
|
||||||
|
p.drawLine(x, 1, x, maxValue);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +144,8 @@ void ChannelHistoGraph::showCurrentChannelValue(int val) {
|
||||||
// ChannelHistoGraph
|
// ChannelHistoGraph
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
RGBHistoGraph::RGBHistoGraph(QWidget *parent, int *channelValue)
|
RGBHistoGraph::RGBHistoGraph(int index, QWidget *parent)
|
||||||
: ChannelHistoGraph(parent, channelValue) {
|
: ChannelHistoGraph(index, parent) {
|
||||||
m_histoImg = QImage(COMBOHIST_RESOLUTION_W, COMBOHIST_RESOLUTION_H,
|
m_histoImg = QImage(COMBOHIST_RESOLUTION_W, COMBOHIST_RESOLUTION_H,
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
}
|
}
|
||||||
|
@ -116,7 +158,7 @@ RGBHistoGraph::~RGBHistoGraph() {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void RGBHistoGraph::setValues() {
|
void RGBHistoGraph::setValues(int *buf, bool) {
|
||||||
for (int chan = 0; chan < 3; chan++) {
|
for (int chan = 0; chan < 3; chan++) {
|
||||||
m_rgbValues[chan].clear();
|
m_rgbValues[chan].clear();
|
||||||
m_rgbValues[chan].resize(COMBOHIST_RESOLUTION_W);
|
m_rgbValues[chan].resize(COMBOHIST_RESOLUTION_W);
|
||||||
|
@ -126,12 +168,12 @@ void RGBHistoGraph::setValues() {
|
||||||
// normalize with the maximum value
|
// normalize with the maximum value
|
||||||
int maxValue = 1;
|
int maxValue = 1;
|
||||||
for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
||||||
int count = m_channelValuePtr[COMBOHIST_RESOLUTION_W * chan + i];
|
int count = buf[COMBOHIST_RESOLUTION_W * chan + i];
|
||||||
if (maxValue < count) maxValue = count;
|
if (maxValue < count) maxValue = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
||||||
int v = m_channelValuePtr[COMBOHIST_RESOLUTION_W * chan + i];
|
int v = buf[COMBOHIST_RESOLUTION_W * chan + i];
|
||||||
m_rgbValues[chan][i] =
|
m_rgbValues[chan][i] =
|
||||||
tround((double)(v * COMBOHIST_RESOLUTION_H) / (double)maxValue);
|
tround((double)(v * COMBOHIST_RESOLUTION_H) / (double)maxValue);
|
||||||
}
|
}
|
||||||
|
@ -150,8 +192,8 @@ void RGBHistoGraph::setValues() {
|
||||||
imgPainter.setCompositionMode(QPainter::CompositionMode_Plus);
|
imgPainter.setCompositionMode(QPainter::CompositionMode_Plus);
|
||||||
|
|
||||||
for (int chan = 0; chan < 3; chan++) {
|
for (int chan = 0; chan < 3; chan++) {
|
||||||
imgPainter.setPen((chan == 0) ? Qt::red : (chan == 1) ? Qt::green
|
imgPainter.setPen((chan == 0) ? Qt::red
|
||||||
: Qt::blue);
|
: (chan == 1) ? Qt::green : Qt::blue);
|
||||||
|
|
||||||
for (int i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
for (int i = 0; i < COMBOHIST_RESOLUTION_W; i++) {
|
||||||
int v = m_rgbValues[chan][i];
|
int v = m_rgbValues[chan][i];
|
||||||
|
@ -211,7 +253,7 @@ void ChannelColorBar::paintEvent(QPaintEvent *event) {
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
// ChannelHisto
|
// ChannelHisto
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
ChannelHisto::ChannelHisto(int channelIndex, int *channelValue,
|
ChannelHisto::ChannelHisto(int channelIndex, bool *showComparePtr,
|
||||||
QWidget *parent) {
|
QWidget *parent) {
|
||||||
QString label;
|
QString label;
|
||||||
QColor color;
|
QColor color;
|
||||||
|
@ -233,15 +275,16 @@ ChannelHisto::ChannelHisto(int channelIndex, int *channelValue,
|
||||||
color = QColor(0, 0, 0, 0);
|
color = QColor(0, 0, 0, 0);
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
label = tr("RGBA");
|
label = tr("RGB");
|
||||||
color = Qt::white;
|
color = Qt::white;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channelIndex != 4)
|
if (channelIndex != 4)
|
||||||
m_histogramGraph = new ChannelHistoGraph(this, channelValue);
|
m_histogramGraph =
|
||||||
|
new ChannelHistoGraph(channelIndex, this, showComparePtr);
|
||||||
else
|
else
|
||||||
m_histogramGraph = new RGBHistoGraph(this, channelValue);
|
m_histogramGraph = new RGBHistoGraph(channelIndex, this);
|
||||||
|
|
||||||
m_colorBar = new ChannelColorBar(this, color);
|
m_colorBar = new ChannelColorBar(this, color);
|
||||||
|
|
||||||
|
@ -302,7 +345,7 @@ void ChannelHisto::onShowAlphaButtonToggled(bool visible) {
|
||||||
// ComboHistoRGBLabel
|
// ComboHistoRGBLabel
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
ComboHistoRGBLabel::ComboHistoRGBLabel(QColor color, QWidget *parent)
|
ComboHistoRGBLabel::ComboHistoRGBLabel(QColor color, QWidget *parent)
|
||||||
: QWidget(parent), m_color(color) {
|
: QWidget(parent), m_color(color), m_mode(DisplayMode::Display_8bit) {
|
||||||
setFixedSize(COMBOHIST_RESOLUTION_W, 30);
|
setFixedSize(COMBOHIST_RESOLUTION_W, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,10 +383,36 @@ void ComboHistoRGBLabel::paintEvent(QPaintEvent *pe) {
|
||||||
p.setPen(Qt::black);
|
p.setPen(Qt::black);
|
||||||
p.setBrush(Qt::NoBrush);
|
p.setBrush(Qt::NoBrush);
|
||||||
|
|
||||||
p.drawText(rect(), Qt::AlignCenter, tr("R:%1 G:%2 B:%3")
|
QFont font = p.font();
|
||||||
.arg(m_color.red())
|
const int pixelSizes[3] = {18, 14, 14};
|
||||||
.arg(m_color.green())
|
font.setPixelSize(pixelSizes[(int)m_mode]);
|
||||||
.arg(m_color.blue()));
|
p.setFont(font);
|
||||||
|
QString colorStr;
|
||||||
|
switch (m_mode) {
|
||||||
|
case Display_8bit: {
|
||||||
|
colorStr = tr("R:%1 G:%2 B:%3")
|
||||||
|
.arg(m_color.red())
|
||||||
|
.arg(m_color.green())
|
||||||
|
.arg(m_color.blue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Display_16bit: {
|
||||||
|
QRgba64 rgba64 = m_color.rgba64();
|
||||||
|
colorStr = tr("R:%1 G:%2 B:%3")
|
||||||
|
.arg(rgba64.red())
|
||||||
|
.arg(rgba64.green())
|
||||||
|
.arg(rgba64.blue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Display_0_1: {
|
||||||
|
colorStr = tr("R:%1 G:%2 B:%3")
|
||||||
|
.arg(m_color.redF())
|
||||||
|
.arg(m_color.greenF())
|
||||||
|
.arg(m_color.blueF());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
p.drawText(rect(), Qt::AlignCenter, colorStr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=============================================================================
|
//=============================================================================
|
||||||
|
@ -351,21 +420,35 @@ void ComboHistoRGBLabel::paintEvent(QPaintEvent *pe) {
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ComboHistogram::ComboHistogram(QWidget *parent)
|
ComboHistogram::ComboHistogram(QWidget *parent)
|
||||||
: QWidget(parent), m_raster(0), m_palette(0) {
|
: QWidget(parent)
|
||||||
for (int chan = 0; chan < 4; chan++)
|
, m_raster(0)
|
||||||
m_histograms[chan] = new ChannelHisto(chan, &m_channelValue[chan][0], this);
|
, m_palette(0)
|
||||||
m_histograms[4] = new ChannelHisto(4, &m_channelValue[0][0], this);
|
, m_showCompare(false)
|
||||||
|
, m_compHistoIsValid(true) {
|
||||||
|
for (int chan = 0; chan < 4; chan++)
|
||||||
|
m_histograms[chan] = new ChannelHisto(chan, &m_showCompare, this);
|
||||||
|
m_histograms[4] = new ChannelHisto(4, &m_showCompare, this);
|
||||||
|
|
||||||
// RGB label
|
// RGB label
|
||||||
m_rgbLabel = new ComboHistoRGBLabel(QColor(128, 128, 128), this);
|
m_rgbLabel = new ComboHistoRGBLabel(QColor(128, 128, 128), this);
|
||||||
m_rgbLabel->setStyleSheet("font-size: 18px;");
|
// m_rgbLabel->setStyleSheet("font-size: 18px;");
|
||||||
|
|
||||||
m_rectAverageRgbLabel = new ComboHistoRGBLabel(QColor(128, 128, 128), this);
|
m_rectAverageRgbLabel = new ComboHistoRGBLabel(QColor(128, 128, 128), this);
|
||||||
m_rectAverageRgbLabel->setStyleSheet("font-size: 18px;");
|
// m_rectAverageRgbLabel->setStyleSheet("font-size: 18px;");
|
||||||
|
|
||||||
m_xPosLabel = new QLabel("", this);
|
m_xPosLabel = new QLabel("", this);
|
||||||
m_yPosLabel = new QLabel("", this);
|
m_yPosLabel = new QLabel("", this);
|
||||||
|
|
||||||
|
m_displayModeCombo = new QComboBox(this);
|
||||||
|
|
||||||
|
m_displayModeCombo->addItem(
|
||||||
|
tr("8bit (0-255)"), (int)ComboHistoRGBLabel::DisplayMode::Display_8bit);
|
||||||
|
m_displayModeCombo->addItem(
|
||||||
|
tr("16bit (0-65535)"),
|
||||||
|
(int)ComboHistoRGBLabel::DisplayMode::Display_16bit);
|
||||||
|
m_displayModeCombo->addItem(
|
||||||
|
tr("0.0-1.0"), (int)ComboHistoRGBLabel::DisplayMode::Display_0_1);
|
||||||
|
|
||||||
// layout
|
// layout
|
||||||
QVBoxLayout *mainLayout = new QVBoxLayout();
|
QVBoxLayout *mainLayout = new QVBoxLayout();
|
||||||
mainLayout->setMargin(5);
|
mainLayout->setMargin(5);
|
||||||
|
@ -373,8 +456,16 @@ ComboHistogram::ComboHistogram(QWidget *parent)
|
||||||
{
|
{
|
||||||
mainLayout->addWidget(m_histograms[4]); // RGB
|
mainLayout->addWidget(m_histograms[4]); // RGB
|
||||||
|
|
||||||
mainLayout->addWidget(new QLabel(tr("Picked Color"), this), 0,
|
QHBoxLayout *labelLay = new QHBoxLayout();
|
||||||
Qt::AlignLeft | Qt::AlignVCenter);
|
labelLay->setMargin(0);
|
||||||
|
labelLay->setSpacing(0);
|
||||||
|
{
|
||||||
|
labelLay->addWidget(new QLabel(tr("Picked Color"), this), 0);
|
||||||
|
labelLay->addStretch(1);
|
||||||
|
labelLay->addWidget(m_displayModeCombo, 0);
|
||||||
|
}
|
||||||
|
mainLayout->addLayout(labelLay, 0);
|
||||||
|
|
||||||
mainLayout->addWidget(m_rgbLabel, 0, Qt::AlignCenter);
|
mainLayout->addWidget(m_rgbLabel, 0, Qt::AlignCenter);
|
||||||
|
|
||||||
mainLayout->addWidget(new QLabel(tr("Average Color (Ctrl + Drag)"), this),
|
mainLayout->addWidget(new QLabel(tr("Average Color (Ctrl + Drag)"), this),
|
||||||
|
@ -405,11 +496,15 @@ ComboHistogram::ComboHistogram(QWidget *parent)
|
||||||
setLayout(mainLayout);
|
setLayout(mainLayout);
|
||||||
|
|
||||||
m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent);
|
m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent);
|
||||||
|
|
||||||
|
connect(m_displayModeCombo, SIGNAL(activated(int)), this,
|
||||||
|
SLOT(onDisplayModeChanged()));
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
ComboHistogram::~ComboHistogram() {
|
ComboHistogram::~ComboHistogram() {
|
||||||
memset(m_channelValue, 0, sizeof m_channelValue);
|
memset(m_channelValue, 0, sizeof m_channelValue);
|
||||||
|
memset(m_channelValueComp, 0, sizeof m_channelValueComp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -417,27 +512,30 @@ ComboHistogram::~ComboHistogram() {
|
||||||
void ComboHistogram::setRaster(const TRasterP &raster,
|
void ComboHistogram::setRaster(const TRasterP &raster,
|
||||||
const TPaletteP &palette) {
|
const TPaletteP &palette) {
|
||||||
if (palette.getPointer()) m_palette = palette;
|
if (palette.getPointer()) m_palette = palette;
|
||||||
m_raster = raster;
|
m_raster = raster;
|
||||||
computeChannelsValue();
|
computeChannelsValue(&m_channelValue[0][0], sizeof(m_channelValue), m_raster);
|
||||||
|
|
||||||
for (int i = 0; i < 5; i++) m_histograms[i]->refleshValue();
|
for (int chan = 0; chan < 4; chan++)
|
||||||
|
m_histograms[chan]->refleshValue(&m_channelValue[chan][0]);
|
||||||
|
m_histograms[4]->refleshValue(&m_channelValue[0][0]);
|
||||||
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ComboHistogram::computeChannelsValue() {
|
void ComboHistogram::computeChannelsValue(int *buf, size_t size, TRasterP ras,
|
||||||
memset(m_channelValue, 0, sizeof m_channelValue);
|
TPalette *extPlt) {
|
||||||
if (!m_raster.getPointer()) return;
|
memset(buf, 0, size);
|
||||||
TRasterCM32P cmRaster = m_raster;
|
if (!ras.getPointer()) return;
|
||||||
|
TRasterCM32P cmRaster = ras;
|
||||||
bool isCmRaster = !!cmRaster;
|
bool isCmRaster = !!cmRaster;
|
||||||
|
|
||||||
TRaster64P raster64 = m_raster;
|
TRaster64P raster64 = ras;
|
||||||
bool is64bit = !!raster64;
|
bool is64bit = !!raster64;
|
||||||
|
|
||||||
int lx = m_raster->getLx();
|
int lx = ras->getLx();
|
||||||
int ly = m_raster->getLy();
|
int ly = ras->getLy();
|
||||||
if (lx > 1 && ly > 1) {
|
if (lx > 1 && ly > 1) {
|
||||||
int i, j;
|
int i, j;
|
||||||
if (is64bit) {
|
if (is64bit) {
|
||||||
|
@ -446,44 +544,45 @@ void ComboHistogram::computeChannelsValue() {
|
||||||
for (i = 0; i < lx; i++, pix_64++) {
|
for (i = 0; i < lx; i++, pix_64++) {
|
||||||
int mValue = (int)byteFromUshort(pix_64->m);
|
int mValue = (int)byteFromUshort(pix_64->m);
|
||||||
if (mValue != 0) {
|
if (mValue != 0) {
|
||||||
++m_channelValue[0][(int)byteFromUshort(pix_64->r)];
|
++buf[idx(0, (int)byteFromUshort(pix_64->r))];
|
||||||
++m_channelValue[1][(int)byteFromUshort(pix_64->g)];
|
++buf[idx(1, (int)byteFromUshort(pix_64->g))];
|
||||||
++m_channelValue[2][(int)byteFromUshort(pix_64->b)];
|
++buf[idx(2, (int)byteFromUshort(pix_64->b))];
|
||||||
}
|
}
|
||||||
++m_channelValue[3][mValue];
|
++buf[idx(3, mValue)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (isCmRaster) {
|
} else if (isCmRaster) {
|
||||||
assert(m_palette);
|
TPalette *plt = (extPlt) ? extPlt : m_palette.getPointer();
|
||||||
|
assert(plt);
|
||||||
for (j = 0; j < ly; j++) {
|
for (j = 0; j < ly; j++) {
|
||||||
TPixelCM32 *pix_cm = cmRaster->pixels(j);
|
TPixelCM32 *pix_cm = cmRaster->pixels(j);
|
||||||
for (i = 0; i < lx; i++, pix_cm++) {
|
for (i = 0; i < lx; i++, pix_cm++) {
|
||||||
int styleId =
|
int styleId =
|
||||||
pix_cm->getTone() < 127 ? pix_cm->getInk() : pix_cm->getPaint();
|
pix_cm->getTone() < 127 ? pix_cm->getInk() : pix_cm->getPaint();
|
||||||
TColorStyle *colorStyle = m_palette->getStyle(styleId);
|
TColorStyle *colorStyle = plt->getStyle(styleId);
|
||||||
if (!colorStyle) continue;
|
if (!colorStyle) continue;
|
||||||
TPixel color = colorStyle->getAverageColor();
|
TPixel color = colorStyle->getAverageColor();
|
||||||
int mValue = color.m;
|
int mValue = color.m;
|
||||||
if (mValue != 0) {
|
if (mValue != 0) {
|
||||||
++m_channelValue[0][color.r];
|
++buf[idx(0, color.r)];
|
||||||
++m_channelValue[1][color.g];
|
++buf[idx(1, color.g)];
|
||||||
++m_channelValue[2][color.b];
|
++buf[idx(2, color.b)];
|
||||||
}
|
}
|
||||||
++m_channelValue[3][color.m];
|
++buf[idx(3, color.m)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else // 8bpc raster
|
} else // 8bpc raster
|
||||||
{
|
{
|
||||||
for (j = 0; j < ly; j++) {
|
for (j = 0; j < ly; j++) {
|
||||||
TPixel *pix = (TPixel *)m_raster->getRawData(0, j);
|
TPixel *pix = (TPixel *)ras->getRawData(0, j);
|
||||||
for (i = 0; i < lx; i++, pix++) {
|
for (i = 0; i < lx; i++, pix++) {
|
||||||
int mValue = pix->m;
|
int mValue = pix->m;
|
||||||
if (mValue != 0) {
|
if (mValue != 0) {
|
||||||
++m_channelValue[0][pix->r];
|
++buf[idx(0, pix->r)];
|
||||||
++m_channelValue[1][pix->g];
|
++buf[idx(1, pix->g)];
|
||||||
++m_channelValue[2][pix->b];
|
++buf[idx(2, pix->b)];
|
||||||
}
|
}
|
||||||
++m_channelValue[3][pix->m];
|
++buf[idx(3, pix->m)];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -512,6 +611,29 @@ void ComboHistogram::updateInfo(const TPixel32 &pix, const TPointD &imagePos) {
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ComboHistogram::updateInfo(const TPixel64 &pix, const TPointD &imagePos) {
|
||||||
|
if (pix == TPixel64::Transparent) {
|
||||||
|
m_histograms[0]->showCurrentChannelValue(-1);
|
||||||
|
m_histograms[1]->showCurrentChannelValue(-1);
|
||||||
|
m_histograms[2]->showCurrentChannelValue(-1);
|
||||||
|
m_rgbLabel->setColorAndUpdate(Qt::transparent);
|
||||||
|
m_xPosLabel->setText("");
|
||||||
|
m_yPosLabel->setText("");
|
||||||
|
} else {
|
||||||
|
TPixel32 pix32 = toPixel32(pix);
|
||||||
|
// show picked color's channel values
|
||||||
|
m_histograms[0]->showCurrentChannelValue((int)pix32.r);
|
||||||
|
m_histograms[1]->showCurrentChannelValue((int)pix32.g);
|
||||||
|
m_histograms[2]->showCurrentChannelValue((int)pix32.b);
|
||||||
|
m_rgbLabel->setColorAndUpdate(
|
||||||
|
QColor::fromRgba64((ushort)pix.r, (ushort)pix.g, (ushort)pix.b));
|
||||||
|
m_xPosLabel->setText(QString::number(tround(imagePos.x)));
|
||||||
|
m_yPosLabel->setText(QString::number(tround(imagePos.y)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
void ComboHistogram::updateAverageColor(const TPixel32 &pix) {
|
void ComboHistogram::updateAverageColor(const TPixel32 &pix) {
|
||||||
if (pix == TPixel32::Transparent) {
|
if (pix == TPixel32::Transparent) {
|
||||||
m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent);
|
m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent);
|
||||||
|
@ -522,3 +644,55 @@ void ComboHistogram::updateAverageColor(const TPixel32 &pix) {
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ComboHistogram::updateAverageColor(const TPixel64 &pix) {
|
||||||
|
if (pix == TPixel64::Transparent) {
|
||||||
|
m_rectAverageRgbLabel->setColorAndUpdate(Qt::transparent);
|
||||||
|
} else {
|
||||||
|
m_rectAverageRgbLabel->setColorAndUpdate(
|
||||||
|
QColor::fromRgba64((ushort)pix.r, (ushort)pix.g, (ushort)pix.b));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ComboHistogram::onDisplayModeChanged() {
|
||||||
|
ComboHistoRGBLabel::DisplayMode mode =
|
||||||
|
static_cast<ComboHistoRGBLabel::DisplayMode>(
|
||||||
|
m_displayModeCombo->currentData().toInt());
|
||||||
|
m_rgbLabel->setDisplayMode(mode);
|
||||||
|
m_rectAverageRgbLabel->setDisplayMode(mode);
|
||||||
|
HistogramChannelDisplayMode = (int)mode;
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ComboHistogram::updateCompHistogram() {
|
||||||
|
assert(!m_compHistoIsValid);
|
||||||
|
m_compHistoIsValid = true;
|
||||||
|
|
||||||
|
TImageP refimg =
|
||||||
|
TImageCache::instance()->get(QString("TnzCompareImg"), false);
|
||||||
|
|
||||||
|
if (!(TToonzImageP)refimg && !(TRasterImageP)refimg) return;
|
||||||
|
|
||||||
|
computeChannelsValue(&m_channelValueComp[0][0], sizeof m_channelValueComp,
|
||||||
|
refimg->raster(), refimg->getPalette());
|
||||||
|
|
||||||
|
for (int chan = 0; chan < 4; chan++)
|
||||||
|
m_histograms[chan]->refleshValue(&m_channelValueComp[chan][0], true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
void ComboHistogram::showEvent(QShowEvent *) {
|
||||||
|
if (!m_compHistoIsValid && m_showCompare) updateCompHistogram();
|
||||||
|
|
||||||
|
int envMode = HistogramChannelDisplayMode;
|
||||||
|
m_displayModeCombo->setCurrentIndex(m_displayModeCombo->findData(envMode));
|
||||||
|
ComboHistoRGBLabel::DisplayMode mode =
|
||||||
|
static_cast<ComboHistoRGBLabel::DisplayMode>(envMode);
|
||||||
|
m_rgbLabel->setDisplayMode(mode);
|
||||||
|
m_rectAverageRgbLabel->setDisplayMode(mode);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue