1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at
8  *
9  *         http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkRGBAPixel_h
19 #define itkRGBAPixel_h
20 
21 // Undefine an eventual RGBAPixel macro
22 #ifdef RGBAPixel
23 #undef RGBAPixel
24 #endif
25 
26 #include "itkIndent.h"
27 #include "itkFixedArray.h"
28 #include "itkMath.h"
29 
30 namespace itk
31 {
32 /** \class RGBAPixel
33  * \brief Represent Red, Green, Blue and Alpha components for color images.
34  *
35  * This class is templated over the representation used for each
36  * component.
37  *
38  * The following syntax for assigning an index is allowed/suggested:
39  *
40    \code
41       RGBAPixel<float> pixel; pixel = 1.0f, 0.0f, .5f, .8;
42       RGBAPixel<char> pixelArray[2];
43       pixelArray[0] = 255, 255, 255, 230;
44       pixelArray[1] = 255, 255, 244, 255;
45    \endcode
46  *
47  * Since RGBAPixel is a subclass of Array, you can access its components as:
48  * pixel[0], pixel[1], pixel[2], pixel[3]
49  * \ingroup ImageObjects
50  *
51  * \ingroup ITKCommon
52  *
53  * \wiki
54  * \wikiexample{SimpleOperations/Transparency,Make part of an image transparent}
55  * \endwiki
56  */
57 
58 template< typename TComponent = unsigned short >
59 class ITK_TEMPLATE_EXPORT RGBAPixel:public FixedArray< TComponent, 4 >
60 {
61 public:
62   /** Standard class type aliases. */
63   using Self = RGBAPixel;
64   using Superclass = FixedArray< TComponent, 4 >;
65 
66   /** Dimension of the vector space. */
67   static constexpr unsigned int Dimension = 4;
68 
69   /** Length of the pixel. */
70   static constexpr unsigned int Length = 4;
71 
72   /** Convenience type alias. */
73   using BaseArray = FixedArray< TComponent, 4 >;
74 
75   /**  Define the component type. */
76   using ComponentType = TComponent;
77   using LuminanceType = typename NumericTraits< ComponentType >::RealType;
78 
79   /** Default constructors */
RGBAPixel()80   RGBAPixel() { this->Fill(0); }
81   RGBAPixel(const RGBAPixel &) = default;
82   RGBAPixel & operator=(const RGBAPixel &) = default;
83   RGBAPixel( RGBAPixel &&) = default;
84   RGBAPixel & operator=(RGBAPixel &&) = default;
85   ~RGBAPixel() = default;
86 
87   /** Pass-through constructor for the Array base class. */
88   template< typename TRGBAPixelValueType >
RGBAPixel(const RGBAPixel<TRGBAPixelValueType> & r)89   RGBAPixel(const RGBAPixel< TRGBAPixelValueType > & r):BaseArray(r) {}
RGBAPixel(const ComponentType r[4])90   RGBAPixel(const ComponentType r[4]):BaseArray(r) {}
RGBAPixel(const ComponentType & r)91   RGBAPixel(const ComponentType & r) { this->Fill(r); }
92 
93   /** Pass-through assignment operator for the Array base class. */
94   RGBAPixel & operator=(const ComponentType r[4]);
95 
96   /** Aritmetic operations between pixels. Return a new RGBAPixel. */
97   Self operator+(const Self & vec) const;
98   Self operator-(const Self & vec) const;
99   Self operator *(const ComponentType & f) const;
100   Self operator /(const ComponentType & f) const;
101 
102   /** Arithmetic-assigment operators. */
103   const Self & operator+=(const Self & vec);
104   const Self & operator-=(const Self & vec);
105   const Self & operator*=(const ComponentType & f);
106   const Self & operator/=(const ComponentType & f);
107 
108   /** Implements strict weak ordering. For use in STL, e.g. std::map. */
109   bool operator<(const Self & vec) const;
110 
111   bool operator==(const Self & vec) const;
112 
113   /** Return the number of components. */
GetNumberOfComponents()114   static unsigned int GetNumberOfComponents() { return 4; }
115 
116   /** Return the value for the Nth component. */
GetNthComponent(int c)117   ComponentType GetNthComponent(int c) const { return this->operator[](c); }
118 
119   /** Return the Euclidean norm of the vector defined by the RGB components. Alpha is not used. */
GetScalarValue()120   ComponentType GetScalarValue() const
121   {
122     return static_cast< ComponentType >( std::sqrt(
123                                            static_cast< double >( this->operator[](0) )
124                                            * static_cast< double >( this->operator[](0) )
125                                            + static_cast< double >( this->operator[](1) )
126                                            * static_cast< double >( this->operator[](1) )
127                                            + static_cast< double >( this->operator[](2) )
128                                            * static_cast< double >( this->operator[](2) ) ) );
129   }
130 
131   /** Set the Nth component to v. */
SetNthComponent(int c,const ComponentType & v)132   void SetNthComponent(int c, const ComponentType & v) {  this->operator[](c) = v; }
133 
134   /** Set the Red component. */
SetRed(ComponentType red)135   void SetRed(ComponentType red) { this->operator[](0) = red; }
136 
137   /** Set the Green component. */
SetGreen(ComponentType green)138   void SetGreen(ComponentType green) { this->operator[](1) = green; }
139 
140   /** Set the Blue component. */
SetBlue(ComponentType blue)141   void SetBlue(ComponentType blue) { this->operator[](2) = blue; }
142 
143   /** Set the Alpha component. */
SetAlpha(ComponentType alpha)144   void SetAlpha(ComponentType alpha) { this->operator[](3) = alpha; }
145 
146   /** Set the four components. */
Set(ComponentType red,ComponentType green,ComponentType blue,ComponentType alpha)147   void Set(ComponentType red, ComponentType green, ComponentType blue, ComponentType alpha)
148   {
149     this->operator[](0) = red;
150     this->operator[](1) = green;
151     this->operator[](2) = blue;
152     this->operator[](3) = alpha;
153   }
154 
155   /** Get the Red component. */
GetRed()156   const ComponentType & GetRed() const { return this->operator[](0); }
157 
158   /** Get the Green component. */
GetGreen()159   const ComponentType & GetGreen() const { return this->operator[](1); }
160 
161   /** Get the Blue component. */
GetBlue()162   const ComponentType & GetBlue() const { return this->operator[](2); }
163 
164   /** Get the Alpha component. */
GetAlpha()165   const ComponentType & GetAlpha() const { return this->operator[](3); }
166 
167   /** Get Luminance out of RGB */
168   LuminanceType GetLuminance() const;
169 };
170 
171 template< typename TComponent  >
172 std::ostream & operator<<(std::ostream & os,
173                                      const RGBAPixel< TComponent > & c);
174 
175 template< typename TComponent  >
176 std::istream & operator>>(std::istream & is,
177                                      RGBAPixel< TComponent > & c);
178 
179 template<typename T>
swap(RGBAPixel<T> & a,RGBAPixel<T> & b)180 inline void swap( RGBAPixel<T> &a, RGBAPixel<T> &b )
181 {
182   a.swap(b);
183 }
184 
185 } // end namespace itk
186 
187 //
188 // Numeric traits must be included after (optionally) including the explicit
189 // instantiations control of this class, in case the implicit instantiation
190 // needs to be disabled.
191 //
192 // NumericTraits must be included before (optionally) including the .hxx file,
193 // in case the .hxx requires to use NumericTraits.
194 //
195 #include "itkNumericTraitsRGBAPixel.h"
196 
197 #ifndef ITK_MANUAL_INSTANTIATION
198 #include "itkRGBAPixel.hxx"
199 #endif
200 
201 #endif
202