|
Generic Image Library: color_convert.hpp Source FileBoost , ,
color_convert.hppGo 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.
:: Главная :: ::
|
|
|
|
|