00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef IMAGE_UTIL_HPP
00026 #define IMAGE_UTIL_HPP
00027
00028
00029 #include <string>
00030
00031 #include <mapnik/config.hpp>
00032 #include <mapnik/graphics.hpp>
00033
00034 namespace mapnik {
00035
00036 template <typename T>
00037 void save_to_file(std::string const& filename,
00038 std::string const& type,
00039 T const& image);
00040 template <typename T>
00041 void save_as_png(std::string const& filename,
00042 T const& image);
00043
00044 template <typename T>
00045 void save_as_jpeg(std::string const& filename,
00046 int quality,
00047 T const& image);
00048
00049 template <typename T>
00050 double distance(T x0,T y0,T x1,T y1)
00051 {
00052 double dx = x1-x0;
00053 double dy = y1-y0;
00054 return sqrt(dx * dx + dy * dy);
00055 }
00056
00057 template <typename Image>
00058 inline void scale_down2(Image& target,const Image& source)
00059 {
00060 int source_width=source.width();
00061 int source_height=source.height();
00062
00063 int target_width=target.width();
00064 int target_height=target.height();
00065 if (target_width<source_width/2 || target_height<source_height/2)
00066 return;
00067 int y1,x1;
00068 for (int y=0;y<target_height;++y)
00069 {
00070 y1=2*y;
00071 for(int x=0;x<target_width;++x)
00072 {
00073 x1=2*x;
00074
00075 target(x,y)=source(x1,y1);
00076 }
00077 }
00078 }
00079
00080 template <typename Image,int scale>
00081 struct image_op
00082 {
00083 static void scale_up(Image& target,const Image& source)
00084 {
00085 if (scale<3) return;
00086 int source_width=source.width();
00087 int source_height=source.height();
00088
00089 int target_width=target.width();
00090 int target_height=target.height();
00091 if (target_width<scale*source_width || target_height<scale*source_height)
00092 return;
00093 for (int y=0;y<source_height;++y)
00094 {
00095 for(int x=0;x<source_width;++x)
00096 {
00097 unsigned p=source(x,y);
00098 for (int i=0;i<scale;++i)
00099 for (int j=0;j<scale;++j)
00100 target(scale*x+i,scale*y+j)=p;
00101 }
00102 }
00103 }
00104 };
00105
00106 template <typename Image>
00107 struct image_op<Image,2>
00108 {
00109 static void scale_up(Image& target,const Image& source)
00110 {
00111 int source_width=source.width();
00112 int source_height=source.height();
00113
00114 int target_width=target.width();
00115 int target_height=target.height();
00116 if (target_width<2*source_width || target_height<2*source_height)
00117 return;
00118 for (int y=0;y<source_height;++y)
00119 {
00120 for(int x=0;x<source_width;++x)
00121 {
00122 target(2*x,2*y)=source(x,y);
00123 target(2*x+1,2*y)=source(x,y);
00124 target(2*x+1,2*y+1)=source(x,y);
00125 target(2*x,2*y+1)=source(x,y);
00126 }
00127 }
00128 }
00129 };
00130
00131 namespace
00132 {
00133 template <typename Image>
00134 inline void scale_up(Image& target,const Image& source,unsigned scale)
00135 {
00136 int source_width=source.width();
00137 int source_height=source.height();
00138
00139 int target_width=target.width();
00140 int target_height=target.height();
00141 if (target_width<scale*source_width || target_height<scale*source_height)
00142 return;
00143 for (int y=0;y<source_height;++y)
00144 {
00145 for(int x=0;x<source_width;++x)
00146 {
00147 unsigned p=source(x,y);
00148 for (int i=0;i<scale;++i)
00149 for (int j=0;j<scale;++j)
00150 target(scale*x+i,scale*y+j)=p;
00151 }
00152 }
00153 }
00154 }
00155
00156 template <typename Image>
00157 void scale_image(Image& target,const Image& source,unsigned scale)
00158 {
00159 if (scale==2)
00160 {
00161 image_op<Image,2>::scale_up(target,source);
00162 }
00163 else
00164 {
00165 scale_up<Image>(target,source,scale);
00166 }
00167 }
00168
00169 template <typename Image>
00170 inline void scale_image (Image& target,const Image& source)
00171 {
00172
00173 int source_width=source.width();
00174 int source_height=source.height();
00175
00176 int target_width=target.width();
00177 int target_height=target.height();
00178
00179 if (source_width<1 || source_height<1 ||
00180 target_width<1 || target_height<1) return;
00181 int int_part_y=source_height/target_height;
00182 int fract_part_y=source_height%target_height;
00183 int err_y=0;
00184 int int_part_x=source_width/target_width;
00185 int fract_part_x=source_width%target_width;
00186 int err_x=0;
00187 int x=0,y=0,xs=0,ys=0;
00188 int prev_y=-1;
00189 for (y=0;y<target_height;++y)
00190 {
00191 if (ys==prev_y)
00192 {
00193 target.setRow(y,target.getRow(y-1),target_width);
00194 }
00195 else
00196 {
00197 xs=0;
00198 for (x=0;x<target_width;++x)
00199 {
00200 target(x,y)=source(xs,ys);
00201 xs+=int_part_x;
00202 err_x+=fract_part_x;
00203 if (err_x>=target_width)
00204 {
00205 err_x-=target_width;
00206 ++xs;
00207 }
00208 }
00209 prev_y=ys;
00210 }
00211 ys+=int_part_y;
00212 err_y+=fract_part_y;
00213 if (err_y>=target_height)
00214 {
00215 err_y-=target_height;
00216 ++ys;
00217 }
00218 }
00219 }
00220
00221 #ifdef _MSC_VER
00222 template MAPNIK_DECL void save_to_file<ImageData32>(std::string const&,
00223 std::string const& ,
00224 ImageData32 const&);
00225 template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (std::string const&,
00226 std::string const& ,
00227 image_view<ImageData32> const&);
00228 #endif
00229
00230 }
00231
00232 #endif //IMAGE_UTIL_HPP