对图像的亮度、对照度进行变换是非经常常使用的一种图像处理操作,可是Qt 本身却没有提供对应的功能代码。因此我写了个简单的类来实现这些操作。我把这个类称为 BrightnessMapper


代码例如以下:

#ifndef BRIGHTNESSMAPPER_H
#define BRIGHTNESSMAPPER_H
#include <QImage>

class BrightnessMapper
{
public:
BrightnessMapper();
~BrightnessMapper();
void setRedMap(unsigned char red[]);
void setGreenMap(unsigned char green[]);
void setBlueMap(unsigned char blue[]);
void setMap(unsigned char map[]);
void updateBCG(double brightness, double contrast, double gamma);
void setColorMap(unsigned char red[], unsigned char green[], unsigned char blue[]);
void apply(const QImage &from, QImage &to);
QImage apply(const QImage &from);
unsigned char *redMap(){ return m_red;}
unsigned char *blueMap(){return m_blue;}
unsigned char *greenMap(){return m_green;}
void redMap(double red[256]);
void greenMap(double green[256]);
void blueMap(double blue[256]);
private:
unsigned char m_red[256];
unsigned char m_green[256];
unsigned char m_blue[256];
};

#endif // BRIGHTNESSMAPPER_H


#include "brightnessmapper.h"
#include <math.h>
#include <QDebug>
BrightnessMapper::BrightnessMapper()
{
for(int i = 0; i < 256; i++)
{
m_red[i] = i;
m_green[i] = i;
m_blue[i] = i;
}
}

BrightnessMapper::~BrightnessMapper()
{

}

void BrightnessMapper::updateBCG(double brightness, double contrast, double gamma)
{
double x, y;
for(int i = 0; i < 256; i ++)
{
x = i / 255.0;
y = exp(log(x) * gamma);
y = (y - 0.5) * brightness + 0.5 + contrast / 255;
y = y * 255.0;
m_red[i] = qBound(0.0, y, 255.0);
m_green[i] = m_red[i];
m_blue[i] = m_red[i];

}
}

QImage BrightnessMapper::apply(const QImage &from)
{
QImage to = from;
apply(from, to);
return to;
}

void BrightnessMapper::apply(const QImage &from, QImage &to)
{
if(to.size() != from.size() || to.format()!= from.format())
{
to = from.copy();
}
int height = from.height();
int width = from.width();
switch(from.format())
{
case QImage::Format_Indexed8:
for(int i = 0; i < height; i++)
{
const uchar *pFrom = (const uchar *)from.constScanLine(i);
uchar *pTo = (uchar *)to.scanLine(i);
for(int j = 0; j < width; j++)
{
pTo[j] = m_red[pFrom[i]];
}
}
break;
case QImage::Format_RGB32:
case QImage::Format_ARGB32:
case QImage::Format_ARGB32_Premultiplied:
for(int i = 0; i < height; i++)
{
const QRgb *pFrom = (const QRgb *)from.constScanLine(i);
QRgb *pTo = (QRgb *)to.scanLine(i);
for(int j = 0; j < width; j++)
{
int r, g, b;
r = qRed(pFrom[j]);
g = qGreen(pFrom[j]);
b = qBlue(pFrom[j]);
r = m_red[r];
g = m_green[g];
b = m_blue[b];
pTo[j] = qRgb(r, g, b);
}
}
break;
}
}
void BrightnessMapper::setRedMap(unsigned char red[])
{
for(int i = 0; i < 256; i++)
{
m_red[i] = red[i];
}
}

void BrightnessMapper::setGreenMap(unsigned char green[])
{
for(int i = 0; i < 256; i++)
{
m_green[i] = green[i];
}
}

void BrightnessMapper::setBlueMap(unsigned char blue[])
{
for(int i = 0; i < 256; i++)
{
m_blue[i] = blue[i];
}
}

void BrightnessMapper::setMap(unsigned char map[])
{
for(int i = 0; i < 256; i++)
{
m_red[i] = map[i];
m_green[i] = map[i];
m_blue[i] = map[i];
}
}

void BrightnessMapper::setColorMap(unsigned char red[], unsigned char green[], unsigned char blue[])
{
for(int i = 0; i < 256; i++)
{
m_red[i] = red[i];
m_green[i] = green[i];
m_blue[i] = blue[i];
}
}
void BrightnessMapper::redMap(double red[256])
{
for(int i = 0; i < 256; i++)
{
red[i] = m_red[i];
}
}

void BrightnessMapper::greenMap(double green[256])
{
for(int i = 0; i < 256; i++)
{
green[i] = m_green[i];
}
}

void BrightnessMapper::blueMap(double blue[256])
{
for(int i = 0; i < 256; i++)
{
blue[i] = m_blue[i];
}
}


这个类的使用方法非常easy。

能够用以下几个函数来设置灰度变换关系。


void setRedMap(unsigned char red[]);

void setGreenMap(unsigned char green[]);

void setBlueMap(unsigned char blue[]);

void setMap(unsigned char map[]);

void setColorMap(unsigned char red[], unsigned char green[], unsigned char blue[]);


也能够用以下这个函数通过设置亮度、对照度、gamma 值来确定变换关系。

void updateBCG(double brightness, double contrast, double gamma);


变换关系确定后能够利用以下两个函数之中的一个来对图像进行变换处理。

void apply(const QImage &from, QImage &to);

QImage apply(const QImage &from);


还有几个辅助函数能够用来读取变换关系表。

unsigned char *redMap(){ return m_red;}

unsigned char *blueMap(){return m_blue;}

unsigned char *greenMap(){return m_green;}

void redMap(double red[256]);

void greenMap(double green[256]);

void blueMap(double blue[256]);


由于代码非常简答,就不多介绍了。

希望对大家实用。