Generic Image Library: color_convert.hpp Source File Boost , ,
color_convert.hpp Go to the documentation of this file. 00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef GIL_COLOR_CONVERT_HPP
00013 #define GIL_COLOR_CONVERT_HPP
00014
00026
00027 #include <functional>
00028 #include "gil_config.hpp "
00029 #include "channel_algorithm.hpp "
00030 #include "pixel.hpp "
00031 #include "gray.hpp "
00032 #include "rgb.hpp "
00033 #include "rgba.hpp "
00034 #include "cmyk.hpp "
00035 #include "metafunctions.hpp "
00036 #include "utilities.hpp "
00037 #include "color_base_algorithm.hpp "
00038
00039 namespace boost { namespace gil {
00040
00041
00042 template <typename P> struct channel_type;
00043
00049
00052 template <typename C1, typename C2>
00053 struct default_color_converter_impl {};
00054
00057 template <typename C>
00058 struct default_color_converter_impl <C,C> {
00059 template <typename P1, typename P2>
00060 void operator()(const P1& src, P2& dst) const {
00061 static_for_each(src,dst,default_channel_converter ());
00062 }
00063 };
00064
00065 namespace detail {
00066
00068
00069
00070 template <typename RedChannel, typename GreenChannel, typename BlueChannel, typename GrayChannelValue>
00071 struct rgb_to_luminance_fn {
00072 GrayChannelValue operator()(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) const {
00073 return channel_convert<GrayChannelValue>( bits32f (
00074 channel_convert<bits32f>(red )*0.30f +
00075 channel_convert<bits32f>(green)*0.59f +
00076 channel_convert<bits32f>(blue )*0.11f) );
00077 }
00078 };
00079
00080
00081 template <typename GrayChannelValue>
00082 struct rgb_to_luminance_fn <uint8_t,uint8_t,uint8_t, GrayChannelValue> {
00083 GrayChannelValue operator()(uint8_t red, uint8_t green, uint8_t blue) const {
00084 return channel_convert<GrayChannelValue>(uint8_t(
00085 ((uint32_t(red )*4915 + uint32_t(green)*9667 + uint32_t(blue )*1802) + 8192) >> 14));
00086 }
00087 };
00088
00089 template <typename GrayChannel, typename RedChannel, typename GreenChannel, typename BlueChannel>
00090 typename channel_traits<GrayChannel>::value_type rgb_to_luminance(const RedChannel& red, const GreenChannel& green, const BlueChannel& blue) {
00091 return rgb_to_luminance_fn<RedChannel,GreenChannel,BlueChannel,
00092 typename channel_traits<GrayChannel>::value_type>()(red,green,blue);
00093 }
00094
00095 }
00096
00099 template <>
00100 struct default_color_converter_impl <gray_t,rgb_t> {
00101 template <typename P1, typename P2>
00102 void operator()(const P1& src, P2& dst) const {
00103 get_color (dst,red_t ()) =
00104 channel_convert<typename color_element_type<P2, red_t >::type>(get_color (src,gray_color_t ()));
00105 get_color (dst,green_t ())=
00106 channel_convert<typename color_element_type<P2, green_t>::type>(get_color (src,gray_color_t ()));
00107 get_color (dst,blue_t ()) =
00108 channel_convert<typename color_element_type<P2, blue_t >::type>(get_color (src,gray_color_t ()));
00109 }
00110 };
00111
00114 template <>
00115 struct default_color_converter_impl <gray_t,cmyk_t> {
00116 template <typename P1, typename P2>
00117 void operator()(const P1& src, P2& dst) const {
00118 get_color (dst,cyan_t ())=
00119 channel_traits<typename color_element_type<P2, cyan_t >::type >::min_value();
00120 get_color (dst,magenta_t ())=
00121 channel_traits<typename color_element_type<P2, magenta_t>::type >::min_value();
00122 get_color (dst,yellow_t ())=
00123 channel_traits<typename color_element_type<P2, yellow_t >::type >::min_value();
00124 get_color (dst,black_t ())=
00125 channel_convert<typename color_element_type<P2, black_t >::type>(get_color (src,gray_color_t ()));
00126 }
00127 };
00128
00131 template <>
00132 struct default_color_converter_impl <rgb_t,gray_t> {
00133 template <typename P1, typename P2>
00134 void operator()(const P1& src, P2& dst) const {
00135 get_color (dst,gray_color_t ()) =
00136 detail::rgb_to_luminance<typename color_element_type<P2,gray_color_t>::type>(
00137 get_color (src,red_t ()), get_color (src,green_t ()), get_color (src,blue_t ())
00138 );
00139 }
00140 };
00141
00142
00150 template <>
00151 struct default_color_converter_impl <rgb_t,cmyk_t> {
00152 template <typename P1, typename P2>
00153 void operator()(const P1& src, P2& dst) const {
00154 typedef typename channel_type<P2>::type T2;
00155 get_color (dst,cyan_t ()) = channel_invert (channel_convert<T2>(get_color (src,red_t ())));
00156 get_color (dst,magenta_t ()) = channel_invert (channel_convert<T2>(get_color (src,green_t ())));
00157 get_color (dst,yellow_t ()) = channel_invert (channel_convert<T2>(get_color (src,blue_t ())));
00158 get_color (dst,black_t ()) = (std::min)(get_color (dst,cyan_t ()),
00159 (std::min)(get_color (dst,magenta_t ()),
00160 get_color (dst,yellow_t ())));
00161 T2 x = channel_traits<T2>::max_value ()-get_color (dst,black_t ());
00162 if (x>0.0001f) {
00163 float x1 = channel_traits<T2>::max_value ()/float(x);
00164 get_color (dst,cyan_t ()) = (T2)((get_color (dst,cyan_t ()) - get_color (dst,black_t ()))*x1);
00165 get_color (dst,magenta_t ()) = (T2)((get_color (dst,magenta_t ()) - get_color (dst,black_t ()))*x1);
00166 get_color (dst,yellow_t ()) = (T2)((get_color (dst,yellow_t ()) - get_color (dst,black_t ()))*x1);
00167 } else {
00168 get_color (dst,cyan_t ())=get_color (dst,magenta_t ())=get_color (dst,yellow_t ())=0;
00169 }
00170 }
00171 };
00172
00179 template <>
00180 struct default_color_converter_impl <cmyk_t,rgb_t> {
00181 template <typename P1, typename P2>
00182 void operator()(const P1& src, P2& dst) const {
00183 typedef typename channel_type<P1>::type T1;
00184 get_color (dst,red_t ()) =
00185 channel_convert<typename color_element_type<P2,red_t>::type>(
00186 channel_invert<T1>(
00187 (std::min)(channel_traits<T1>::max_value (),
00188 T1(get_color (src,cyan_t ())*channel_invert (get_color (src,black_t ()))+get_color (src,black_t ())))));
00189 get_color (dst,green_t ())=
00190 channel_convert<typename color_element_type<P2,green_t>::type>(
00191 channel_invert<T1>(
00192 (std::min)(channel_traits<T1>::max_value (),
00193 T1(get_color (src,magenta_t ())*channel_invert (get_color (src,black_t ()))+get_color (src,black_t ())))));
00194 get_color (dst,blue_t ()) =
00195 channel_convert<typename color_element_type<P2,blue_t>::type>(
00196 channel_invert<T1>(
00197 (std::min)(channel_traits<T1>::max_value (),
00198 T1(get_color (src,yellow_t ())*channel_invert (get_color (src,black_t ()))+get_color (src,black_t ())))));
00199 }
00200 };
00201
00202
00207 template <>
00208 struct default_color_converter_impl <cmyk_t,gray_t> {
00209 template <typename P1, typename P2>
00210 void operator()(const P1& src, P2& dst) const {
00211 get_color (dst,gray_color_t ())=
00212 channel_convert<typename color_element_type<P2,gray_t>::type>(
00213 channel_multiply (
00214 channel_invert (
00215 detail::rgb_to_luminance<typename color_element_type<P1,black_t>::type >(
00216 get_color (src,cyan_t ()),
00217 get_color (src,magenta_t ()),
00218 get_color (src,yellow_t ())
00219 )
00220 ),
00221 channel_invert (get_color (src,black_t ()))));
00222 }
00223 };
00224
00225 namespace detail {
00226 template <typename Pixel>
00227 typename channel_type<Pixel>::type alpha_or_max_impl(const Pixel& p, mpl::true_) {
00228 return get_color (p,alpha_t ());
00229 }
00230 template <typename Pixel>
00231 typename channel_type<Pixel>::type alpha_or_max_impl(const Pixel& , mpl::false_) {
00232 return channel_traits<typename channel_type<Pixel>::type>::max_value();
00233 }
00234 }
00235
00236
00237 template <typename Pixel>
00238 typename channel_type<Pixel>::type alpha_or_max(const Pixel& p) {
00239 return detail::alpha_or_max_impl(p, mpl::contains<typename color_space_type<Pixel>::type,alpha_t>());
00240 }
00241
00242
00245 template <typename C1>
00246 struct default_color_converter_impl <C1,rgba_t> {
00247 template <typename P1, typename P2>
00248 void operator()(const P1& src, P2& dst) const {
00249 typedef typename channel_type<P2>::type T2;
00250 pixel<T2,rgb_layout_t> tmp;
00251 default_color_converter_impl<C1,rgb_t> ()(src,tmp);
00252 get_color (dst,red_t ()) =get_color (tmp,red_t ());
00253 get_color (dst,green_t ())=get_color (tmp,green_t ());
00254 get_color (dst,blue_t ()) =get_color (tmp,blue_t ());
00255 get_color (dst,alpha_t ())=channel_convert<T2>(alpha_or_max(src));
00256 }
00257 };
00258
00265 template <typename C2>
00266 struct default_color_converter_impl <rgba_t,C2> {
00267 template <typename P1, typename P2>
00268 void operator()(const P1& src, P2& dst) const {
00269 typedef typename channel_type<P1>::type T1;
00270 default_color_converter_impl<rgb_t,C2> ()(
00271 pixel<T1,rgb_layout_t> (channel_multiply (get_color (src,red_t ()), get_color (src,alpha_t ())),
00272 channel_multiply (get_color (src,green_t ()),get_color (src,alpha_t ())),
00273 channel_multiply (get_color (src,blue_t ()), get_color (src,alpha_t ())))
00274 ,dst);
00275 }
00276 };
00277
00280 template <>
00281 struct default_color_converter_impl <rgba_t,rgba_t> {
00282 template <typename P1, typename P2>
00283 void operator()(const P1& src, P2& dst) const {
00284 static_for_each(src,dst,default_channel_converter ());
00285 }
00286 };
00287
00291
00294 struct default_color_converter {
00295 template <typename SrcP, typename DstP>
00296 void operator()(const SrcP& src,DstP& dst) const {
00297 typedef typename color_space_type<SrcP>::type SrcColorSpace;
00298 typedef typename color_space_type<DstP>::type DstColorSpace;
00299 default_color_converter_impl<SrcColorSpace,DstColorSpace> ()(src,dst);
00300 }
00301 };
00302
00307 template <typename SrcP, typename DstP>
00308 inline void color_convert (const SrcP& src, DstP& dst) {
00309 default_color_converter ()(src,dst);
00310 }
00311
00312 } }
00313
00314 #endif
Generated on Sat May 2 13:50:13 2009 for Generic Image Library by
1.5.6
Статья Generic Image Library: color_convert.hpp Source File раздела может быть полезна для разработчиков на c++ и boost.
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.
:: Главная :: ::