-
Notifications
You must be signed in to change notification settings - Fork 0
/
imagefilter.cpp
120 lines (109 loc) · 3.63 KB
/
imagefilter.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include <QImage>
#include "math.h"
template<class T>
inline const T& kClamp( const T& x, const T& low, const T& high )
{
if ( x < low ) return low;
else if ( high < x ) return high;
else return x;
}
inline
int changeBrightness( int value, int brightness )
{
return kClamp( value + brightness * 255 / 100, 0, 255 );
}
inline
int changeContrast( int value, int contrast )
{
return kClamp((( value - 127 ) * contrast / 100 ) + 127, 0, 255 );
}
inline
int changeGamma( int value, int gamma )
{
return kClamp( int( pow( value / 255.0, 100.0 / gamma ) * 255 ), 0, 255 );
}
inline
int changeUsingTable( int value, const int table[] )
{
return table[ value ];
}
template< int operation( int, int ) >
static
QImage changeImage( const QImage& image, int value )
{
QImage im = image;
im.detach();
if( im.colorCount() == 0 ) /* truecolor */
{
if( im.format() != QImage::Format_RGB32 ) /* just in case */
im = im.convertToFormat( QImage::Format_RGB32 );
int table[ 256 ];
for( int i = 0;
i < 256;
++i )
table[ i ] = operation( i, value );
if( im.hasAlphaChannel() )
{
for( int y = 0;
y < im.height();
++y )
{
QRgb* line = reinterpret_cast< QRgb* >( im.scanLine( y ));
for( int x = 0;
x < im.width();
++x )
line[ x ] = qRgba( changeUsingTable( qRed( line[ x ] ), table ),
changeUsingTable( qGreen( line[ x ] ), table ),
changeUsingTable( qBlue( line[ x ] ), table ),
changeUsingTable( qAlpha( line[ x ] ), table ));
}
}
else
{
for( int y = 0;
y < im.height();
++y )
{
QRgb* line = reinterpret_cast< QRgb* >( im.scanLine( y ));
for( int x = 0;
x < im.width();
++x )
line[ x ] = qRgb( changeUsingTable( qRed( line[ x ] ), table ),
changeUsingTable( qGreen( line[ x ] ), table ),
changeUsingTable( qBlue( line[ x ] ), table ));
}
}
}
else
{
QVector<QRgb> colors = im.colorTable();
for( int i = 0;
i < im.colorCount();
++i )
colors[ i ] = qRgb( operation( qRed( colors[ i ] ), value ),
operation( qGreen( colors[ i ] ), value ),
operation( qBlue( colors[ i ] ), value ));
}
return im;
}
// brightness is multiplied by 100 in order to avoid floating point numbers
QImage changeBrightness( const QImage& image, int brightness )
{
if( brightness == 0 ) // no change
return image;
return changeImage< changeBrightness >( image, brightness );
}
// contrast is multiplied by 100 in order to avoid floating point numbers
QImage changeContrast( const QImage& image, int contrast )
{
if( contrast == 100 ) // no change
return image;
return changeImage< changeContrast >( image, contrast );
}
// gamma is multiplied by 100 in order to avoid floating point numbers
QImage changeGamma( const QImage& image, int gamma )
{
if( gamma == 100 ) // no change
return image;
return changeImage< changeGamma >( image, gamma );
}