diff --git a/src/tools/histogram-viewer/histogram_viewer.cpp b/src/tools/histogram-viewer/histogram_viewer.cpp index c55e82a..04e9e62 100644 --- a/src/tools/histogram-viewer/histogram_viewer.cpp +++ b/src/tools/histogram-viewer/histogram_viewer.cpp @@ -2,12 +2,6 @@ Copyright (C) 2020 Arindam Chaudhuri */ #include "histogram_viewer.h" -#include -#include -#include -#include -#include -#include #define PLUGIN_NAME "Histogram Viewer" @@ -18,88 +12,100 @@ Q_EXPORT_PLUGIN2(histogram-viewer, ToolPlugin); //********* ---------- Histogram Viewer --------- ********** // -void getHistogram(QImage &img, uint hist_r[], uint hist_g[], uint hist_b[], uint hist_y[]) +void getHistogram(QImage &img, uint hist_r[], uint hist_g[], uint hist_b[]) { int w = img.width(); int h = img.height(); + int x, y, r, g, b; - for (int y=0; y -QImage histogramImage(T histogram[], QColor color, int hist_w, int hist_h) +template QImage histogramImage(T histr[], T histg[], T histb[], int hist_w, int hist_h, bool logarithmic) { // get maximum in each histogram - T max_val=0; - for (int i=0; i<256; i++) { - if (histogram[i] > max_val) max_val = histogram[i]; + T max_val = 0; + int i, j, i1, x, ro, go, bo; + float factorh, factorl, factorw; + float r, g, b, k, ix, kx; + for (i = 0; i < 256; i++) + { + if (histr[i] > max_val) max_val = histr[i]; + if (histg[i] > max_val) max_val = histg[i]; + if (histb[i] > max_val) max_val = histb[i]; } // create histogram image and draw histogram - double factor = (double)hist_h / max_val; + factorh = (float)max_val / (float)hist_h; + factorl = (max_val > 0) ? (float)max_val / log((float)max_val + 1.0f) : 1.0f; + factorw = 256.0f / (float)hist_w; - QImage hist_img(hist_w+2, hist_h+2, QImage::Format_RGB32); - hist_img.fill(Qt::white); + QImage hist_img(hist_w, hist_h, QImage::Format_RGB32); - QPainter painter(&hist_img); - // draw outline and grid - painter.drawRect(0,0, hist_w+1, hist_h+1); - painter.setPen(QColor(220,220,220)); - for (int i=1; i<5; i++) { - painter.drawLine(QPoint(i*255/5,1), QPoint(i*255/5,hist_h)); - } // draw histogram bars - painter.setPen(color); - for (int i=0; i<256; i++) { - int line_height = factor*histogram[i]; - if (line_height==0) - continue; - QPoint start(i+1, 1); - QPoint end(i+1, line_height); - painter.drawLine(start, end); + for (j = 0; j < hist_h; j++) + { + QRgb *row = (QRgb*)hist_img.constScanLine(j); + for (x = 0; x < hist_w; x++) + { + ix = factorw * x; + i = (int)ix; + i1 = ((i + 1) < hist_w) ? (i + 1) : i; + kx = ix - i; + k = (float)max_val - (float)j * factorh; + r = ((1.0f - kx) * (float)histr[i] + kx * (float)histr[i1]); + g = ((1.0f - kx) * (float)histg[i] + kx * (float)histg[i1]); + b = ((1.0f - kx) * (float)histb[i] + kx * (float)histb[i1]); + if (logarithmic) + { + r = log(r + 1.0f) * factorl; + g = log(g + 1.0f) * factorl; + b = log(b + 1.0f) * factorl; + } + ro = (r > k) ? 255 : 0; + go = (g > k) ? 255 : 0; + bo = (b > k) ? 255 : 0; + row[x] = qRgb(ro, go, bo); + } } - painter.end(); - // flip, because Y axis has reverse direction in QImage - QTransform tfm; - tfm.rotate(180, Qt::XAxis); - return hist_img.transformed(tfm); + return hist_img; } //--------- **************** Histogram Dialog ****************--------- HistogramDialog:: HistogramDialog(QWidget *parent, QImage &image) : QDialog(parent) { - this->setWindowTitle("R G B and Luminance(Y) Histogram"); + this->setWindowTitle("R G B Histogram"); this->resize(540, 400); - QGridLayout *gridLayout = new QGridLayout(this); + gridLayout = new QGridLayout(this); histLabel = new QLabel(this); histLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); gridLayout->addWidget(histLabel, 0, 0, 1, 2); // container for holding buttons - QWidget *container = new QWidget(this); + container = new QWidget(this); gridLayout->addWidget(container, 1, 0, 1, 1); - QDialogButtonBox *buttonBox = new QDialogButtonBox(Qt::Horizontal, this); + buttonBox = new QDialogButtonBox(Qt::Horizontal, this); buttonBox->setStandardButtons(QDialogButtonBox::Close); gridLayout->addWidget(buttonBox, 1, 1, 1, 1); - QHBoxLayout *hLayout = new QHBoxLayout(container); + hLayout = new QHBoxLayout(container); container->setLayout(hLayout); - QCheckBox *logBtn = new QCheckBox("Logarithmic", this); + logBtn = new QCheckBox("Logarithmic", this); hLayout->addWidget(logBtn); connect(logBtn, SIGNAL(clicked(bool)), this, SLOT(drawHistogram(bool))); @@ -107,44 +113,16 @@ HistogramDialog:: HistogramDialog(QWidget *parent, QImage &image) : QDialog(pare connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); // generate histograms - getHistogram(image, hist_r, hist_g, hist_b, hist_y); + getHistogram(image, hist_r, hist_g, hist_b); drawHistogram(false); } -void -HistogramDialog:: drawHistogram(bool logarithmic) +void HistogramDialog:: drawHistogram(bool logarithmic) { - int hist_w = 256; - int hist_h = 160; - QImage imgR, imgG, imgB, imgY; - if (not logarithmic) { - imgR = histogramImage(hist_r, Qt::red, hist_w, hist_h); - imgG = histogramImage(hist_g, Qt::green, hist_w, hist_h); - imgB = histogramImage(hist_b, Qt::blue, hist_w, hist_h); - imgY = histogramImage(hist_y, QColor(127,127,127), hist_w, hist_h); - } - else { // logarithmic histograms - double loghist[4][256] = {}; - for (int i=0; i<256; i++) { - loghist[0][i] = log(hist_r[i]); - loghist[1][i] = log(hist_g[i]); - loghist[2][i] = log(hist_b[i]); - loghist[3][i] = log(hist_y[i]); - } - imgR = histogramImage(loghist[0], Qt::red, hist_w, hist_h); - imgG = histogramImage(loghist[1], Qt::green, hist_w, hist_h); - imgB = histogramImage(loghist[2], Qt::blue, hist_w, hist_h); - imgY = histogramImage(loghist[3], QColor(127,127,127), hist_w, hist_h); - } - - QImage img(hist_w*2+3, hist_h*2+3, QImage::Format_RGB32); - img.fill(Qt::white); - QPainter painter(&img); - painter.drawImage(0, 0, imgR); - painter.drawImage(hist_w+1, 0, imgG); - painter.drawImage(0, hist_h+1, imgB); - painter.drawImage(hist_w+1, hist_h+1, imgY); - painter.end(); + int hist_w = 512; + int hist_h = 320; + QImage img; + img = histogramImage(hist_r, hist_g, hist_b, hist_w, hist_h, logarithmic); histLabel->setPixmap(QPixmap::fromImage(img)); } diff --git a/src/tools/histogram-viewer/histogram_viewer.h b/src/tools/histogram-viewer/histogram_viewer.h index 0d53b67..9f7189f 100644 --- a/src/tools/histogram-viewer/histogram_viewer.h +++ b/src/tools/histogram-viewer/histogram_viewer.h @@ -1,7 +1,12 @@ #pragma once #include "plugin.h" +#include #include #include +#include +#include +#include +#include class ToolPlugin : public QObject, Plugin { @@ -27,8 +32,12 @@ class HistogramDialog : public QDialog uint hist_r[256] = {}; uint hist_g[256] = {}; uint hist_b[256] = {}; - uint hist_y[256] = {}; //widgets + QGridLayout *gridLayout; + QWidget *container; + QDialogButtonBox *buttonBox; + QHBoxLayout *hLayout; + QCheckBox *logBtn; QLabel *histLabel; HistogramDialog(QWidget *parent, QImage &image);