137 lines
3.2 KiB
C++
137 lines
3.2 KiB
C++
|
#include "histogram.h"
|
||
|
|
||
|
#include <QDebug>
|
||
|
#include <QPainter>
|
||
|
|
||
|
#include <cmath>
|
||
|
|
||
|
Histogram::Histogram(QImage* image)
|
||
|
{
|
||
|
R = new QHash<int, int>;
|
||
|
G = new QHash<int, int>;
|
||
|
B = new QHash<int, int>;
|
||
|
L = new QHash<int, int>;
|
||
|
generate(image);
|
||
|
}
|
||
|
|
||
|
Histogram::~Histogram()
|
||
|
{
|
||
|
delete R;
|
||
|
delete G;
|
||
|
delete B;
|
||
|
delete L;
|
||
|
}
|
||
|
|
||
|
void Histogram::generate(QImage* image)
|
||
|
{
|
||
|
int width = image->width();
|
||
|
int height = image->height();
|
||
|
|
||
|
for (int x = 0; x < width; x++) {
|
||
|
|
||
|
for (int y = 0; y < height; y++) {
|
||
|
|
||
|
QRgb pixel = image->pixel(x,y);
|
||
|
|
||
|
// Get color values
|
||
|
int r = Histogram::R->value(qRed(pixel));
|
||
|
int g = Histogram::G->value(qGreen(pixel));
|
||
|
int b = Histogram::B->value(qBlue(pixel));
|
||
|
int l = Histogram::L->value(qGray(pixel));
|
||
|
|
||
|
// Insert color values
|
||
|
Histogram::R->insert(qRed(pixel), r+1);
|
||
|
Histogram::G->insert(qGreen(pixel), g+1);
|
||
|
Histogram::B->insert(qBlue(pixel), b+1);
|
||
|
Histogram::L->insert(qGray(pixel), l+1);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Returns the maximal value of the histogram in the given channel */
|
||
|
int Histogram::maximumValue(Channel selectedChannel = RGB)
|
||
|
{
|
||
|
// Create and set max value
|
||
|
int max = 0;
|
||
|
|
||
|
// Iterate over values
|
||
|
for(int i = 0; i < R->size(); i++)
|
||
|
{
|
||
|
if(R->value(i) > max)
|
||
|
{
|
||
|
max = R->value(i);
|
||
|
}
|
||
|
}
|
||
|
for(int i = 0; i < G->size(); i++)
|
||
|
{
|
||
|
if(G->value(i) > max)
|
||
|
{
|
||
|
max = G->value(i);
|
||
|
}
|
||
|
}
|
||
|
for(int i = 0; i < B->size(); i++)
|
||
|
{
|
||
|
if(B->value(i) > max)
|
||
|
{
|
||
|
max = B->value(i);
|
||
|
}
|
||
|
}
|
||
|
for(int i = 0; i < L->size(); i++)
|
||
|
{
|
||
|
if(L->value(i) > max)
|
||
|
{
|
||
|
max = L->value(i);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return max;
|
||
|
}
|
||
|
|
||
|
|
||
|
/** Returns a pointer to the given channel QHash<int, int> */
|
||
|
QHash<int, int>* Histogram::get(Channel channel = LChannel)
|
||
|
{
|
||
|
if (channel==LChannel) return L;
|
||
|
if (channel==RChannel) return R;
|
||
|
if (channel==GChannel) return G;
|
||
|
if (channel==BChannel) return B;
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Returns a 255 by 100 QImage containing a Histogram for the given channel.
|
||
|
* The background is transparent (Alpha 0, RGB=255) */
|
||
|
QImage Histogram::getImage(Channel channel = LChannel, QBrush pen = Qt::gray)
|
||
|
{
|
||
|
// Create blank QImage and fill it with transparent background:
|
||
|
QImage histImage(255, 100, QImage::Format_ARGB32);
|
||
|
histImage.fill(0);
|
||
|
QPainter painter(&histImage);
|
||
|
painter.setBrush(Qt::transparent);
|
||
|
painter.setPen(Qt::transparent);
|
||
|
painter.drawRect(0,0,255,100);
|
||
|
|
||
|
// Calculate the aspect ratio using the maximal value of the color histograms
|
||
|
int maximum = (channel == LChannel ? maximumValue(LChannel) : maximumValue(RGB));
|
||
|
float ratio = 100.0/float(maximum);
|
||
|
|
||
|
// Preparing the painter:
|
||
|
painter.setBrush(pen);
|
||
|
painter.setPen(pen.color());
|
||
|
|
||
|
int h;
|
||
|
// Draw histogram
|
||
|
QHash<int, int>* hist = get(channel);
|
||
|
QHash<int, int>::const_iterator cit = hist->begin();
|
||
|
|
||
|
while (cit != hist->end())
|
||
|
{
|
||
|
h = 100 - floor(ratio*cit.value());
|
||
|
painter.drawLine(cit.key(), h, cit.key(), 100);
|
||
|
++cit;
|
||
|
}
|
||
|
|
||
|
return histImage;
|
||
|
}
|