DGtal 1.4.0
Loading...
Searching...
No Matches
GradientColorMap.ih
1/**
2 * This program is free software: you can redistribute it and/or modify
3 * it under the terms of the GNU Lesser General Public License as
4 * published by the Free Software Foundation, either version 3 of the
5 * License, or (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program. If not, see <http://www.gnu.org/licenses/>.
14 *
15 **/
16
17/**
18 * @file GradientColorMap.ih
19 * @author Sebastien Fourey (\c Sebastien.Fourey@greyc.ensicaen.fr )
20 * Groupe de Recherche en Informatique, Image, Automatique et Instrumentation de Caen - GREYC (CNRS, UMR 6072), ENSICAEN, France
21 *
22 * @date 2010/07/19
23 *
24 * Implementation of inline methods defined in GradientColorMap.h
25 *
26 * This file is part of the DGtal library.
27 */
28
29//////////////////////////////////////////////////////////////////////////////
30#include <cstdlib>
31#include <cmath>
32#include <vector>
33//////////////////////////////////////////////////////////////////////////////
34
35///////////////////////////////////////////////////////////////////////////////
36// IMPLEMENTATION of inline methods.
37///////////////////////////////////////////////////////////////////////////////
38
39///////////////////////////////////////////////////////////////////////////////
40// ----------------------- Standard services ------------------------------
41
42template < typename PValue,
43 int PDefaultPreset,
44 int PDefaultFirstColor,
45 int PDefaultLastColor >
46inline
47DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::GradientColorMap
48( const PValue & minV,
49 const PValue & maxV,
50 const ColorGradientPreset preset,
51 const Color firstColor,
52 const Color lastColor )
53 : myMin( minV ), myMax( maxV )
54{
55 ASSERT_MSG(myMin < myMax, "Max should be strictly greather than Min in a colormap.");
56 switch ( preset ) {
57 case CMAP_GRAYSCALE:
58 myColors.push_back( Color::Black );
59 myColors.push_back( Color::White );
60 break;
61 case CMAP_SPRING:
62 myColors.push_back( Color( 255, 0, 255 ));
63 myColors.push_back( Color( 255, 255, 0 ));
64 break;
65 case CMAP_SUMMER:
66 myColors.push_back( Color( 0, 132, 100 ));
67 myColors.push_back( Color( 255, 255, 100 ));
68 break;
69 case CMAP_AUTUMN:
70 myColors.push_back( Color( 255, 0, 0 ));
71 myColors.push_back( Color( 255, 255, 0));
72 break;
73 case CMAP_WINTER:
74 myColors.push_back( Color( 0, 0, 255 ));
75 myColors.push_back( Color( 0, 255, 132 ));
76 break;
77 case CMAP_COOL:
78 myColors.push_back( Color( 0, 255, 255 ));
79 myColors.push_back( Color( 255, 0, 255 ));
80 break;
81 case CMAP_COPPER:
82 myColors.push_back( Color( 0, 0, 0 ));
83 myColors.push_back( Color( 255, 198, 123 ));
84 break;
85 case CMAP_HOT:
86 myColors.push_back( Color::Black );
87 myColors.push_back( Color::Red );
88 myColors.push_back( Color( 255, 140, 0 ) );
89 myColors.push_back( Color::Yellow );
90 myColors.push_back( Color::White );
91 break;
92 case CMAP_JET:
93 myColors.push_back( Color::Blue );
94 myColors.push_back( Color::Cyan );
95 myColors.push_back( Color::Yellow );
96 myColors.push_back( Color( 255, 140, 0 ) );
97 myColors.push_back( Color::Red );
98 myColors.push_back( Color( 132, 0, 0 ) );
99 break;
100 case CMAP_VIRIDIS:
101 myColors.push_back( Color(63,17,81) );
102 myColors.push_back( Color(63,110,139) );
103 myColors.push_back( Color( 40, 175, 127 ));
104 myColors.push_back( Color( 184, 222, 41 ));
105 myColors.push_back( Color( 253, 232, 37 ));
106
107 break;
108 case CMAP_CUSTOM:
109 if ( firstColor != Color::None
110 && lastColor != Color::None ) {
111 myColors.push_back( firstColor );
112 myColors.push_back( lastColor );
113 }
114 break;
115 }
116}
117
118template <typename PValue,
119 int PDefaultPreset,
120 int PDefaultFirstColor,
121 int PDefaultLastColor >
122inline
123DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::GradientColorMap
124( const GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> & other )
125 : myMin( other.myMin ), myMax( other.myMax ), myColors( other.myColors )
126{
127 ASSERT_MSG(myMin < myMax, "Max should be strictly greather than Min in a colormap.");
128}
129
130template <typename PValue,
131 int PDefaultPreset,
132 int PDefaultFirstColor,
133 int PDefaultLastColor >
134inline
135DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::~GradientColorMap()
136{
137}
138
139template <typename PValue,
140 int PDefaultPreset,
141 int PDefaultFirstColor,
142 int PDefaultLastColor >
143DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> &
144DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::operator=
145( const DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> & other )
146{
147 if ( &other != this ) {
148 myMin = other.myMin;
149 myMax = other.myMax;
150 ASSERT_MSG(myMin < myMax, "Max should be strictly greather than Min in a colormap.");
151 myColors = other.myColors;
152 }
153 return *this;
154}
155
156///////////////////////////////////////////////////////////////////////////////
157// Interface - public :
158
159
160template<typename PValue,
161 int PDefaultPreset,
162 int PDefaultFirstColor,
163 int PDefaultLastColor >
164inline
165void
166DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::addColor
167( const Color & color )
168{
169 myColors.push_back( color );
170}
171
172template<typename PValue,
173 int PDefaultPreset,
174 int PDefaultFirstColor,
175 int PDefaultLastColor >
176inline
177void
178DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::clearColors()
179{
180 myColors.clear();
181}
182
183template<typename PValue,
184 int PDefaultPreset,
185 int PDefaultFirstColor,
186 int PDefaultLastColor >
187inline
188const PValue &
189DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::min() const
190{
191 return myMin;
192}
193
194template<typename PValue,
195 int PDefaultPreset,
196 int PDefaultFirstColor,
197 int PDefaultLastColor >
198inline
199const PValue &
200DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::max() const
201{
202 return myMax;
203}
204
205template<typename PValue,
206 int PDefaultPreset,
207 int PDefaultFirstColor,
208 int PDefaultLastColor >
209inline
210DGtal::Color
211DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::operator()
212 ( const Value & value ) const
213{
214 return GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::getColor( myColors,
215 myMin,
216 myMax,
217 value );
218}
219
220/**
221 * Writes/Displays the object on an output stream.
222 * @param out the output stream where the object is written.
223 */
224template <typename PValue,
225 int PDefaultPreset,
226 int PDefaultFirstColor,
227 int PDefaultLastColor >
228inline
229void
230DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::selfDisplay
231( std::ostream & out ) const
232{
233 out << "[GradientColorMap "
234 << " min=" << myMin
235 << " max=" << myMax;
236 std::vector<Color>::const_iterator it = myColors.begin();
237 while ( it != myColors.end() ) {
238 out << " RGB("
239 << it->red() << ","
240 << it->green() << ","
241 << it->blue() << ") ";
242 ++it;
243 }
244 out << " ]";
245}
246
247/**
248 * Checks the validity/consistency of the object.
249 * @return 'true' if the object is valid, 'false' otherwise.
250 */
251template <typename PValue,
252 int PDefaultPreset,
253 int PDefaultFirstColor,
254 int PDefaultLastColor >
255inline
256bool
257DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::isValid() const
258{
259 return true;
260}
261
262template <typename PValue,
263 int PDefaultPreset,
264 int PDefaultFirstColor,
265 int PDefaultLastColor >
266inline
267DGtal::Color
268DGtal::GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor>::getColor
269( const std::vector<Color> & colors,
270 const Value & min,
271 const Value & max,
272 Value value )
273{
274 ASSERT_MSG(min < max, "Max should be strictly greather than Min in a colormap.");
275 if ( colors.size() < 2 )
276 return DGtal::Color::None;
277 if ( std::is_floating_point<PValue>::value
278 && ! ( std::isfinite( value ) || std::isinf( value ) ) )
279 return DGtal::Color::Black;
280 if ( value < min ) value = min;
281 if ( max < value ) value = max;
282 double scale = static_cast<double>( value - min ) / (max - min);
283 const int intervals = (const int)colors.size() - 1;
284 int upper_index = static_cast<int>( ceil( intervals * scale ) );
285 if ( !upper_index ) // Special case when value == min.
286 upper_index = 1;
287 const Color & firstColor = colors[ upper_index - 1 ];
288 const Color & lastColor = colors[ upper_index ];
289 scale = ( scale * intervals ) - (upper_index - 1);
290
291 const unsigned char red = static_cast<unsigned char>( firstColor.red() +
292 scale * ( lastColor.red() -
293 firstColor.red() ));
294 const unsigned char green = static_cast<unsigned char>( firstColor.green() +
295 scale * ( lastColor.green() -
296 firstColor.green() ));
297 const unsigned char blue = static_cast<unsigned char>( firstColor.blue() +
298 scale * ( lastColor.blue() -
299 firstColor.blue() ));
300 return DGtal::Color( red, green, blue );
301}
302
303///////////////////////////////////////////////////////////////////////////////
304// Implementation of inline functions //
305
306template <typename PValue,
307 int PDefaultPreset,
308 int PDefaultFirstColor,
309 int PDefaultLastColor >
310inline
311std::ostream&
312DGtal::operator<< ( std::ostream & out,
313 const GradientColorMap<PValue,PDefaultPreset,PDefaultFirstColor,PDefaultLastColor> & object )
314{
315 object.selfDisplay( out );
316 return out;
317}
318
319// //
320///////////////////////////////////////////////////////////////////////////////
321
322
323///////////////////////////////////////////////////////////////////////////////
324// Interface - private :