]> git.sesse.net Git - nageru/blobdiff - nageru/rgb_histogram.cpp
Remove the QCustomPlot dependency.
[nageru] / nageru / rgb_histogram.cpp
diff --git a/nageru/rgb_histogram.cpp b/nageru/rgb_histogram.cpp
new file mode 100644 (file)
index 0000000..fb1a0ca
--- /dev/null
@@ -0,0 +1,94 @@
+#include "rgb_histogram.h"
+
+#include <QPainter>
+#include <QRect>
+
+class QPaintEvent;
+class QResizeEvent;
+
+using namespace std;
+
+static constexpr int margin_left = 16;
+static constexpr int margin_top = 14;
+static constexpr int margin_right = 14;
+static constexpr int margin_bottom = 25;
+
+RGBHistogram::RGBHistogram(QWidget *parent)
+       : QWidget(parent), red(256, 0.0), green(256, 0.0), blue(256, 0.0)
+{
+}
+
+void RGBHistogram::set_histograms(std::vector<double> red, std::vector<double> green, std::vector<double> blue)
+{
+       assert(red.size() == 256);
+       assert(green.size() == 256);
+       assert(blue.size() == 256);
+       this->red = std::move(red);
+       this->green = std::move(green);
+       this->blue = std::move(blue);
+       repaint();
+}
+
+void RGBHistogram::paintEvent(QPaintEvent *event)
+{
+       QPainter painter(this);
+       painter.fillRect(0, 0, width(), height(), Qt::white);
+       painter.setRenderHints(QPainter::Antialiasing);
+
+       double max = 0.0;
+       for (unsigned i = 0; i < 256; ++i) {
+               max = std::max(max, red[i]);
+               max = std::max(max, green[i]);
+               max = std::max(max, blue[i]);
+       }
+
+       // Draw the graphs. (We'd like to get rid of the bottom line, but that's just cosmetic.)
+       painter.setPen(QPen(Qt::red));
+       painter.setBrush(QBrush(QColor(255, 127, 127, 80)));
+       draw(red, max, Qt::GlobalColor::red, &painter);
+
+       painter.setPen(QPen(Qt::green));
+       painter.setBrush(QBrush(QColor(127, 255, 127, 80)));
+       draw(green, max, Qt::GlobalColor::green, &painter);
+
+       painter.setPen(QPen(Qt::blue));
+       painter.setBrush(QBrush(QColor(127, 127, 255, 80)));
+       draw(blue, max, Qt::GlobalColor::blue, &painter);
+
+       // Draw the tick lines.
+       int w = (width() - 1) - margin_left - margin_right;
+       painter.setPen(QPen(Qt::black));
+       painter.setBrush(QBrush());
+       for (int i = 0; i < 256; i += 10) {
+               int th = (i % 50 == 0) ? 5 : 2;
+               double x = (i / 255.0) * w + margin_left;
+               double y = (height() - 1) - margin_top - margin_bottom;
+               painter.drawLine(QPointF(x, y + margin_top), QPointF(x, y + margin_top - th));
+       }
+
+       // And the axis labels.
+       for (int i = 0; i < 256; i += 50) {
+               char buf[16];
+               snprintf(buf, sizeof(buf), "%d", i);
+
+               double x = (i / 255.0) * w + margin_left;
+               double y = (height() - 1) - margin_top - margin_bottom;
+               painter.drawText(QRectF(x - 20, y + margin_top, 40, margin_bottom), Qt::AlignCenter | Qt::AlignTop, QString(buf));
+       }
+}
+
+void RGBHistogram::draw(const vector<double> &v, double max, Qt::GlobalColor color, QPainter *painter)
+{
+       int w = (width() - 1) - margin_left - margin_right;
+       int h = (height() - 1) - margin_top - margin_bottom;
+
+       QPointF points[258];
+       points[0] = QPointF(margin_left, margin_top + h);
+       for (int i = 0; i < 256; ++i) {
+               double x = (i / 255.0) * w + margin_left;
+               double y = (1.0 - (v[i] / max)) * h + margin_top;
+               points[i + 1] = QPointF(x, y);
+       }
+       points[257] = QPointF(margin_left + w, margin_top + h);
+       painter->drawPolygon(points, 258);
+}