QGIS API Documentation 3.41.0-Master (45a0abf3bec)
Loading...
Searching...
No Matches
qgsprevieweffect.cpp
Go to the documentation of this file.
1/***************************************************************************
2 qgsprevieweffect.cpp
3 -------------------
4 begin : March 2014
5 copyright : (C) 2014 by Nyall Dawson
6 email : nyall dot dawson at gmail dot com
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18#include <QPainter>
19#include "qgsprevieweffect.h"
20#include "moc_qgsprevieweffect.cpp"
21
22
24 : QGraphicsEffect( parent )
25 , mMode( PreviewGrayscale )
26{
27 //effect is disabled by default
28 setEnabled( false );
29}
30
32{
33 mMode = mode;
34 update();
35}
36
37void QgsPreviewEffect::draw( QPainter *painter )
38{
39 QPoint offset;
40 QPixmap pixmap;
41
42 if ( sourceIsPixmap() )
43 {
44 // No point in drawing in device coordinates (pixmap will be scaled anyways).
45 pixmap = sourcePixmap( Qt::LogicalCoordinates, &offset );
46 }
47 else
48 {
49 // Draw pixmap in device coordinates to avoid pixmap scaling;
50 pixmap = sourcePixmap( Qt::DeviceCoordinates, &offset );
51 painter->setWorldTransform( QTransform() );
52 }
53
54 QImage image = pixmap.toImage();
55
56 switch ( mMode )
57 {
59 {
60 const QImage bwImage = image.convertToFormat( QImage::Format_Mono );
61 painter->drawImage( offset, bwImage );
62 break;
63 }
68 {
69 QRgb *line = nullptr;
70
71 for ( int y = 0; y < image.height(); y++ )
72 {
73 line = ( QRgb * )image.scanLine( y );
74 for ( int x = 0; x < image.width(); x++ )
75 {
76 line[x] = simulateColorBlindness( line[x], mMode );
77 }
78 }
79
80 painter->drawImage( offset, image );
81 break;
82 }
83 }
84
85}
86
87QRgb QgsPreviewEffect::simulateColorBlindness( QRgb &originalColor, QgsPreviewEffect::PreviewMode mode )
88{
89 int red = qRed( originalColor );
90 int green = qGreen( originalColor );
91 int blue = qBlue( originalColor );
92
93 int r = red;
94 int g = green;
95 int b = blue;
96
97 //simulate color blindness
98 //matrix values taken from Machado et al. (2009), https://doi.org/10.1109/TVCG.2009.113:
99 //https://www.inf.ufrgs.br/~oliveira/pubs_files/CVD_Simulation/CVD_Simulation.html
100 switch ( mode )
101 {
102 case PreviewGrayscale:
103 simulateGrayscale( r, g, b, red, green, blue );
104 break;
105 case PreviewProtanope:
106 simulateProtanope( r, g, b, red, green, blue );
107 break;
109 simulateDeuteranope( r, g, b, red, green, blue );
110 break;
111 case PreviewTritanope:
112 simulateTritanope( r, g, b, red, green, blue );
113 break;
114 default:
115 break;
116 }
117
118 //restrict values to 0-255
119 r = std::max( std::min( 255, r ), 0 );
120 g = std::max( std::min( 255, g ), 0 );
121 b = std::max( std::min( 255, b ), 0 );
122
123 return qRgb( r, g, b );
124}
125
126void QgsPreviewEffect::simulateGrayscale( int &r, int &g, int &b, int &red, int &green, int &blue )
127{
128 r = ( 0.2126 * red ) + ( 0.7152 * green ) + ( 0.0722 * blue );
129 g = r;
130 b = r;
131}
132
133void QgsPreviewEffect::simulateProtanope( int &r, int &g, int &b, int &red, int &green, int &blue )
134{
135 r = ( 0.152286 * red ) + ( 1.052583 * green ) + ( -0.204868 * blue );
136 g = ( 0.114503 * red ) + ( 0.786281 * green ) + ( 0.099216 * blue );
137 b = ( -0.003882 * red ) + ( -0.048116 * green ) + ( 1.051998 * blue );
138}
139
140void QgsPreviewEffect::simulateDeuteranope( int &r, int &g, int &b, int &red, int &green, int &blue )
141{
142 r = ( 0.367322 * red ) + ( 0.860646 * green ) + ( -0.227968 * blue );
143 g = ( 0.280085 * red ) + ( 0.672501 * green ) + ( 0.047413 * blue );
144 b = ( -0.011820 * red ) + ( 0.042940 * green ) + ( 0.968881 * blue );
145}
146
147void QgsPreviewEffect::simulateTritanope( int &r, int &g, int &b, int &red, int &green, int &blue )
148{
149 r = ( 1.255528 * red ) + ( -0.076749 * green ) + ( -0.178779 * blue );
150 g = ( -0.078411 * red ) + ( 0.930809 * green ) + ( 0.147602 * blue );
151 b = ( 0.004733 * red ) + ( 0.691367 * green ) + ( 0.303900 * blue );
152}
void draw(QPainter *painter) override
void setMode(PreviewMode mode)
Sets the mode for the preview effect, which controls how the effect modifies a widgets appearance.
PreviewMode mode() const
Returns the mode used for the preview effect.
QgsPreviewEffect(QObject *parent)