From 21c135a2fc976d215c112d07529e9b08f1c2b605 Mon Sep 17 00:00:00 2001 From: shun-iwasawa Date: Aug 30 2019 08:17:23 +0000 Subject: fix histogram with 3dlut --- diff --git a/toonz/sources/include/tools/stylepicker.h b/toonz/sources/include/tools/stylepicker.h index 54f7c64..b5381bb 100644 --- a/toonz/sources/include/tools/stylepicker.h +++ b/toonz/sources/include/tools/stylepicker.h @@ -60,11 +60,12 @@ public: int pickStyleId(const TPointD &point, double radius2 = 1, int mode = 2) const; /*--- Toonz Raster LevelのToneを拾う。 ---*/ - int pickTone(const TPointD &pos); + int pickTone(const TPointD &pos) const; // per pli come sopra, ma ritorna il maincolor // per tzp e fullcolor ritorna il colore effettivo del pixel TPixel32 pickColor(const TPointD &point, double radius2 = 1) const; + TPixel32 pickAverageColor(const TRectD &rect) const; // ritorna il colore medio presente nell'area della finestra corrente openGL TPixel32 pickColor(const TRectD &area) const; diff --git a/toonz/sources/tnztools/stylepicker.cpp b/toonz/sources/tnztools/stylepicker.cpp index a236390..b6cc05a 100644 --- a/toonz/sources/tnztools/stylepicker.cpp +++ b/toonz/sources/tnztools/stylepicker.cpp @@ -12,6 +12,8 @@ #include "tpixelutils.h" #include "tregion.h" +#include + //--------------------------------------------------------- StylePicker::StylePicker(const TImageP &image) @@ -74,7 +76,7 @@ int StylePicker::pickStyleId(const TPointD &pos, double radius2, styleId = palette->getClosestStyle(col); } else if (TVectorImageP vi = m_image) { // prima cerca lo stile della regione piu' vicina - TRegion *r = vi->getRegion(pos); + TRegion *r = vi->getRegion(pos); if (r) styleId = r->getStyle(); // poi cerca quello della stroke, ma se prima aveva trovato una regione, // richiede che @@ -101,7 +103,7 @@ int StylePicker::pickStyleId(const TPointD &pos, double radius2, //--------------------------------------------------------- /*--- Toonz Raster LevelのToneを拾う。 ---*/ -int StylePicker::pickTone(const TPointD &pos) { +int StylePicker::pickTone(const TPointD &pos) const { if (TToonzImageP ti = m_image) { TRasterCM32P ras = ti->getRaster(); if (!ras) return -1; @@ -119,6 +121,7 @@ int StylePicker::pickTone(const TPointD &pos) { TPixel32 StylePicker::pickColor(const TPointD &pos, double radius2) const { TToonzImageP ti = m_image; TRasterImageP ri = m_image; + TVectorImageP vi = m_image; if (!!ri) // !!ti || !!ri) { TRasterP raster; @@ -135,12 +138,74 @@ TPixel32 StylePicker::pickColor(const TPointD &pos, double radius2) const { TRasterGR8P rasterGR8 = raster; if (rasterGR8) return toPixel32(rasterGR8->pixels(point.y)[point.x]); - } else if (TVectorImageP vi = m_image) { + } else if (vi) { const TPalette *palette = m_palette.getPointer(); if (!palette) return TPixel32::Transparent; int styleId = pickStyleId(pos, radius2); if (0 <= styleId && styleId < palette->getStyleCount()) return palette->getStyle(styleId)->getAverageColor(); + } else if (ti) { + const TPalette *palette = m_palette.getPointer(); + if (!palette) return TPixel32::Transparent; + int paintId = pickStyleId(pos, radius2, 0); + int inkId = pickStyleId(pos, radius2, 1); + int tone = pickTone(pos); + TPixel32 ink, paint; + if (0 <= inkId && inkId < palette->getStyleCount()) + ink = palette->getStyle(inkId)->getAverageColor(); + if (0 <= paintId && paintId < palette->getStyleCount()) + paint = palette->getStyle(paintId)->getAverageColor(); + + if (tone == 0) + return ink; + else if (tone == 255) + return paint; + else + return blend(ink, paint, tone, TPixelCM32::getMaxTone()); + } + return TPixel32::Transparent; +} + +//--------------------------------------------------------- + +TPixel32 StylePicker::pickAverageColor(const TRectD &rect) const { + TRasterImageP ri = m_image; + assert(ri); + if (!!ri) { + TRasterP raster; + raster = ri->getRaster(); + + TPoint topLeft = getRasterPoint(rect.getP00()); + TPoint bottomRight = getRasterPoint(rect.getP11()); + + if (!raster->getBounds().overlaps(TRect(topLeft, bottomRight))) + return TPixel32::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); + + TRaster32P raster32 = raster; + assert(raster32); + if (raster32) { + UINT r = 0, g = 0, b = 0, m = 0, size = 0; + for (int y = topLeft.y; y < bottomRight.y; y++) { + TPixel32 *p = &raster32->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 TPixel32(r / size, g / size, b / size, m / size); + else + return TPixel32::Transparent; + } } return TPixel32::Transparent; } @@ -236,7 +301,7 @@ TPixel32 getAverageColor(TStroke *stroke) { return TPixel32(buffer[0].b, buffer[0].g, buffer[0].r, 255); } -} // namspace +} // namespace //--------------------------------------------------------- diff --git a/toonz/sources/toonz/colormodelviewer.cpp b/toonz/sources/toonz/colormodelviewer.cpp index 5323e93..39deb09 100644 --- a/toonz/sources/toonz/colormodelviewer.cpp +++ b/toonz/sources/toonz/colormodelviewer.cpp @@ -198,7 +198,7 @@ void ColorModelViewer::loadImage(const TFilePath &fp) { //----------------------------------------------------------------------------- /*! Create and open the Right-click menu color model viewer. -*/ + */ void ColorModelViewer::contextMenuEvent(QContextMenuEvent *event) { /*-- Levelが取得できない場合はMenuを出さない --*/ TApp *app = TApp::instance(); @@ -258,21 +258,21 @@ void ColorModelViewer::contextMenuEvent(QContextMenuEvent *event) { //----------------------------------------------------------------------------- /*! If left button is pressed recall \b pick() in event pos. -*/ + */ void ColorModelViewer::mousePressEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) pick(event->pos() * getDevPixRatio()); } //----------------------------------------------------------------------------- /*! If left button is moved recall \b pick() in event pos. -*/ + */ void ColorModelViewer::mouseMoveEvent(QMouseEvent *event) { if (event->buttons() & Qt::LeftButton) pick(event->pos() * getDevPixRatio()); } //----------------------------------------------------------------------------- /*! Pick color from image and set it as current style. -*/ + */ void ColorModelViewer::pick(const QPoint &p) { TImageP img = m_imageViewer->getImage(); if (!img) return; @@ -296,7 +296,7 @@ void ColorModelViewer::pick(const QPoint &p) { カレントToolに合わせてPickモードを変更 0=Area, 1=Line, 2=Line&Areas(default) ---*/ - int styleIndex = picker.pickStyleId(pos, 1, m_mode); + int styleIndex = picker.pickStyleId(pos + TPointD(-0.5, -0.5), 1, m_mode); if (styleIndex < 0) return; @@ -366,7 +366,7 @@ void ColorModelViewer::showEvent(QShowEvent *e) { ToolHandle *toolHandle = TApp::instance()->getCurrentTool(); bool ret = connect(paletteHandle, SIGNAL(paletteSwitched()), this, SLOT(showCurrentImage())); - ret = ret && connect(paletteHandle, SIGNAL(paletteChanged()), this, + ret = ret && connect(paletteHandle, SIGNAL(paletteChanged()), this, SLOT(showCurrentImage())); ret = ret && connect(paletteHandle, SIGNAL(colorStyleChanged(bool)), this, SLOT(showCurrentImage())); @@ -487,7 +487,7 @@ void ColorModelViewer::showCurrentImage() { //----------------------------------------------------------------------------- /*! Clone current image and set it in viewer. -*/ + */ void ColorModelViewer::loadCurrentFrame() { TApp *app = TApp::instance(); TXshLevel *xl = app->getCurrentLevel()->getLevel(); @@ -535,8 +535,8 @@ void ColorModelViewer::loadCurrentFrame() { m_flipConsole->enableProgressBar(false); m_flipConsole->setProgressBarStatus(0); m_flipConsole->setFrameRange(1, 1, 1); - m_title1 = m_viewerTitle + " :: " + - m_currentRefImgPath.withoutParentDir().withFrame(fid); + m_title1 = m_viewerTitle + + " :: " + m_currentRefImgPath.withoutParentDir().withFrame(fid); m_title = " :: "; m_imageViewer->setImage(refImg); @@ -585,8 +585,8 @@ void ColorModelViewer::reloadCurrentFrame() { m_flipConsole->enableProgressBar(false); m_flipConsole->setProgressBarStatus(0); m_flipConsole->setFrameRange(1, 1, 1); - m_title1 = m_viewerTitle + " :: " + - m_currentRefImgPath.withoutParentDir().withFrame(fids[0]); + m_title1 = m_viewerTitle + + " :: " + m_currentRefImgPath.withoutParentDir().withFrame(fids[0]); m_title = " :: "; m_imageViewer->setImage(refImg); diff --git a/toonz/sources/toonz/imageviewer.cpp b/toonz/sources/toonz/imageviewer.cpp index bd8d79d..2a4b206 100644 --- a/toonz/sources/toonz/imageviewer.cpp +++ b/toonz/sources/toonz/imageviewer.cpp @@ -882,10 +882,10 @@ void ImageViewer::pickColor(QMouseEvent *event, bool putValueToStyleEditor) { if (!m_isHistogramEnable) return; if (!m_histogramPopup->isVisible()) return; - QPoint curPos = event->pos() * getDevPixRatio(); + QPointF curPos = event->localPos() * getDevPixRatio(); // avoid to pick outside of the flip - if ((!m_image) || !rect().contains(curPos)) { + if ((!m_image) || !rect().contains(curPos.toPoint())) { // throw transparent color m_histogramPopup->updateInfo(TPixel32::Transparent, TPointD(-1, -1)); return; @@ -893,21 +893,26 @@ void ImageViewer::pickColor(QMouseEvent *event, bool putValueToStyleEditor) { StylePicker picker(m_image); - TPoint mousePos = TPoint(curPos.x(), height() - 1 - curPos.y()); - TRectD area = TRectD(mousePos.x, mousePos.y, mousePos.x, mousePos.y); + TPointD mousePos = TPointD(curPos.x(), height() - 1 - curPos.y()); + TRectD area = TRectD(mousePos.x, mousePos.y, mousePos.x, mousePos.y); - if (m_lutCalibrator && m_lutCalibrator->isValid()) m_fbo->bind(); + TPointD pos = + getViewAff().inv() * TPointD(curPos.x() - (qreal)(width()) / 2, + -curPos.y() + (qreal)(height()) / 2); - const TPixel32 pix = picker.pickColor(area); + TRectD imgRect = (m_image->raster()) + ? convert(TRect(m_image->raster()->getSize())) + : m_image->getBBox(); + TPointD imagePos = + TPointD(0.5 * imgRect.getLx() + pos.x, 0.5 * imgRect.getLy() + pos.y); - if (m_lutCalibrator && m_lutCalibrator->isValid()) m_fbo->release(); + TPixel32 pix; + if (m_lutCalibrator && m_lutCalibrator->isValid()) + pix = picker.pickColor(pos + TPointD(-0.5, -0.5)); + else + pix = picker.pickColor(area); - QPoint viewP = mapFrom(this, curPos); - TPointD pos = getViewAff().inv() * - TPointD(viewP.x() - width() / 2, -viewP.y() + height() / 2); - TPointD imagePos = TPointD(0.5 * m_image->getBBox().getLx() + pos.x, - 0.5 * m_image->getBBox().getLy() + pos.y); - if (m_image->getBBox().contains(imagePos)) { + if (!m_image->raster() || imgRect.contains(imagePos)) { // throw the picked color to the histogram m_histogramPopup->updateInfo(pix, imagePos); // throw it to the style editor as well @@ -923,6 +928,14 @@ void ImageViewer::pickColor(QMouseEvent *event, bool putValueToStyleEditor) { * specified rectangle */ void ImageViewer::rectPickColor(bool putValueToStyleEditor) { + auto isRas32 = [this]() -> bool { + TRasterImageP ri = m_image; + if (!ri) return false; + TRaster32P ras32 = ri->getRaster(); + if (!ras32) return false; + return true; + }; + if (!m_isHistogramEnable) return; if (!m_histogramPopup->isVisible()) return; @@ -938,11 +951,15 @@ void ImageViewer::rectPickColor(bool putValueToStyleEditor) { return; } - if (m_lutCalibrator && m_lutCalibrator->isValid() && m_fbo) m_fbo->bind(); - - const TPixel32 pix = picker.pickColor(area.enlarge(-1, -1)); - - if (m_lutCalibrator && m_lutCalibrator->isValid() && m_fbo) m_fbo->release(); + TPixel32 pix; + if (m_lutCalibrator && m_lutCalibrator->isValid() && isRas32()) { + 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); + pix = picker.pickAverageColor(TRectD(start, end)); + } else + pix = picker.pickColor(area.enlarge(-1, -1)); // throw the picked color to the histogram m_histogramPopup->updateAverageColor(pix); diff --git a/toonz/sources/toonzqt/combohistogram.cpp b/toonz/sources/toonzqt/combohistogram.cpp index 7e9fa13..11400a0 100644 --- a/toonz/sources/toonzqt/combohistogram.cpp +++ b/toonz/sources/toonzqt/combohistogram.cpp @@ -40,7 +40,7 @@ void ChannelHistoGraph::setValues() { // normalize with the maximum value int maxValue = 1; for (i = 0; i < COMBOHIST_RESOLUTION_W; i++) { - int count = m_channelValuePtr[i]; + int count = m_channelValuePtr[i]; if (maxValue < count) maxValue = count; } @@ -284,7 +284,7 @@ ChannelHisto::ChannelHisto(int channelIndex, int *channelValue, //----------------------------------------------------------------------------- /*! update the picked color's channel value -*/ + */ void ChannelHisto::showCurrentChannelValue(int val) { m_histogramGraph->showCurrentChannelValue(val); } @@ -321,7 +321,6 @@ void ComboHistoRGBLabel::paintEvent(QPaintEvent *pe) { p.drawRect(bgRect); return; } - if (LutManager::instance()->isValid()) { QColor convertedColor(m_color); LutManager::instance()->convert(convertedColor); @@ -339,10 +338,11 @@ void ComboHistoRGBLabel::paintEvent(QPaintEvent *pe) { p.setPen(Qt::black); p.setBrush(Qt::NoBrush); - p.drawText(rect(), Qt::AlignCenter, tr("R:%1 G:%2 B:%3") - .arg(m_color.red()) - .arg(m_color.green()) - .arg(m_color.blue())); + p.drawText(rect(), Qt::AlignCenter, + tr("R:%1 G:%2 B:%3") + .arg(m_color.red()) + .arg(m_color.green()) + .arg(m_color.blue())); } //============================================================================= @@ -351,9 +351,9 @@ void ComboHistoRGBLabel::paintEvent(QPaintEvent *pe) { ComboHistogram::ComboHistogram(QWidget *parent) : QWidget(parent), m_raster(0), m_palette(0) { - for (int chan = 0; chan < 4; chan++) + for (int chan = 0; chan < 4; chan++) m_histograms[chan] = new ChannelHisto(chan, &m_channelValue[chan][0], this); - m_histograms[4] = new ChannelHisto(4, &m_channelValue[0][0], this); + m_histograms[4] = new ChannelHisto(4, &m_channelValue[0][0], this); // RGB label m_rgbLabel = new ComboHistoRGBLabel(QColor(128, 128, 128), this); @@ -416,7 +416,7 @@ ComboHistogram::~ComboHistogram() { void ComboHistogram::setRaster(const TRasterP &raster, const TPaletteP &palette) { if (palette.getPointer()) m_palette = palette; - m_raster = raster; + m_raster = raster; computeChannelsValue(); for (int i = 0; i < 5; i++) m_histograms[i]->refleshValue();