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 <mapnik/config.hpp>
00030 #include <mapnik/graphics.hpp>
00031
00032
00033 #include <boost/algorithm/string.hpp>
00034
00035
00036 #include <string>
00037
00038 namespace mapnik {
00039
00040 class ImageWriterException : public std::exception
00041 {
00042 private:
00043 std::string message_;
00044 public:
00045 ImageWriterException(const std::string& message)
00046 : message_(message) {}
00047
00048 ~ImageWriterException() throw() {}
00049
00050 virtual const char* what() const throw()
00051 {
00052 return message_.c_str();
00053 }
00054 };
00055
00056 template <typename T>
00057 MAPNIK_DECL void save_to_file(T const& image,
00058 std::string const& filename,
00059 std::string const& type);
00060
00061 template <typename T>
00062 MAPNIK_DECL void save_to_file(T const& image,
00063 std::string const& filename);
00064
00065 template <typename T>
00066 void save_as_png(T const& image,
00067 std::string const& filename);
00068
00069 template <typename T>
00070 void save_as_jpeg(std::string const& filename,
00071 int quality,
00072 T const& image);
00073
00074 inline bool is_png (std::string const& filename)
00075 {
00076 return boost::algorithm::iends_with(filename,std::string(".png"));
00077 }
00078
00079 inline bool is_jpeg (std::string const& filename)
00080 {
00081 return boost::algorithm::iends_with(filename,std::string(".jpg")) ||
00082 boost::algorithm::iends_with(filename,std::string(".jpeg"));
00083 }
00084
00085 inline bool is_tiff (std::string const& filename)
00086 {
00087 return boost::algorithm::iends_with(filename,std::string(".tif")) ||
00088 boost::algorithm::iends_with(filename,std::string(".tiff"));
00089 }
00090
00091 inline std::string type_from_filename(std::string const& filename)
00092 {
00093 if (is_png(filename)) return "png";
00094 if (is_jpeg(filename)) return "jpeg";
00095 if (is_tiff(filename)) return "tiff";
00096 return "unknown";
00097 }
00098
00099 template <typename T>
00100 double distance(T x0,T y0,T x1,T y1)
00101 {
00102 double dx = x1-x0;
00103 double dy = y1-y0;
00104 return sqrt(dx * dx + dy * dy);
00105 }
00106
00107 template <typename Image>
00108 inline void scale_down2(Image& target,const Image& source)
00109 {
00110 int source_width=source.width();
00111 int source_height=source.height();
00112
00113 int target_width=target.width();
00114 int target_height=target.height();
00115 if (target_width<source_width/2 || target_height<source_height/2)
00116 return;
00117 int y1,x1;
00118 for (int y=0;y<target_height;++y)
00119 {
00120 y1=2*y;
00121 for(int x=0;x<target_width;++x)
00122 {
00123 x1=2*x;
00124
00125 target(x,y)=source(x1,y1);
00126 }
00127 }
00128 }
00129
00130 template <typename Image,int scale>
00131 struct image_op
00132 {
00133 static void scale_up(Image& target,const Image& source)
00134 {
00135 if (scale<3) return;
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 struct image_op<Image,2>
00158 {
00159 static void scale_up(Image& target,const Image& source)
00160 {
00161 int source_width=source.width();
00162 int source_height=source.height();
00163
00164 int target_width=target.width();
00165 int target_height=target.height();
00166 if (target_width<2*source_width || target_height<2*source_height)
00167 return;
00168 for (int y=0;y<source_height;++y)
00169 {
00170 for(int x=0;x<source_width;++x)
00171 {
00172 target(2*x,2*y)=source(x,y);
00173 target(2*x+1,2*y)=source(x,y);
00174 target(2*x+1,2*y+1)=source(x,y);
00175 target(2*x,2*y+1)=source(x,y);
00176 }
00177 }
00178 }
00179 };
00180
00181 namespace
00182 {
00183 template <typename Image>
00184 inline void scale_up(Image& target,const Image& source,unsigned scale)
00185 {
00186 int source_width=source.width();
00187 int source_height=source.height();
00188
00189 int target_width=target.width();
00190 int target_height=target.height();
00191 if (target_width<scale*source_width || target_height<scale*source_height)
00192 return;
00193 for (int y=0;y<source_height;++y)
00194 {
00195 for(int x=0;x<source_width;++x)
00196 {
00197 unsigned p=source(x,y);
00198 for (int i=0;i<scale;++i)
00199 for (int j=0;j<scale;++j)
00200 target(scale*x+i,scale*y+j)=p;
00201 }
00202 }
00203 }
00204 }
00205
00206 template <typename Image>
00207 void scale_image(Image& target,const Image& source,unsigned scale)
00208 {
00209 if (scale==2)
00210 {
00211 image_op<Image,2>::scale_up(target,source);
00212 }
00213 else
00214 {
00215 scale_up<Image>(target,source,scale);
00216 }
00217 }
00218
00219 template <typename Image>
00220 inline void scale_image (Image& target,const Image& source)
00221 {
00222
00223 int source_width=source.width();
00224 int source_height=source.height();
00225
00226 int target_width=target.width();
00227 int target_height=target.height();
00228
00229 if (source_width<1 || source_height<1 ||
00230 target_width<1 || target_height<1) return;
00231 int int_part_y=source_height/target_height;
00232 int fract_part_y=source_height%target_height;
00233 int err_y=0;
00234 int int_part_x=source_width/target_width;
00235 int fract_part_x=source_width%target_width;
00236 int err_x=0;
00237 int x=0,y=0,xs=0,ys=0;
00238 int prev_y=-1;
00239 for (y=0;y<target_height;++y)
00240 {
00241 if (ys==prev_y)
00242 {
00243 target.setRow(y,target.getRow(y-1),target_width);
00244 }
00245 else
00246 {
00247 xs=0;
00248 for (x=0;x<target_width;++x)
00249 {
00250 target(x,y)=source(xs,ys);
00251 xs+=int_part_x;
00252 err_x+=fract_part_x;
00253 if (err_x>=target_width)
00254 {
00255 err_x-=target_width;
00256 ++xs;
00257 }
00258 }
00259 prev_y=ys;
00260 }
00261 ys+=int_part_y;
00262 err_y+=fract_part_y;
00263 if (err_y>=target_height)
00264 {
00265 err_y-=target_height;
00266 ++ys;
00267 }
00268 }
00269 }
00270
00271 inline MAPNIK_DECL void save_to_file (Image32 const& image,
00272 std::string const& file,
00273 std::string const& type)
00274 {
00275 save_to_file<ImageData32>(image.data(),file,type);
00276 }
00277
00278 inline MAPNIK_DECL void save_to_file(Image32 const& image,
00279 std::string const& file)
00280 {
00281 save_to_file<ImageData32>(image.data(),file);
00282 }
00283
00284 #ifdef _MSC_VER
00285 template MAPNIK_DECL void save_to_file<ImageData32>(ImageData32 const&,
00286 std::string const&,
00287 std::string const&);
00288 template MAPNIK_DECL void save_to_file<ImageData32>(ImageData32 const&,
00289 std::string const&);
00290
00291 template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (image_view<ImageData32> const&,
00292 std::string const&,
00293 std::string const&);
00294
00295 template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (image_view<ImageData32> const&,
00296 std::string const&);
00297
00298 #endif
00299
00300 }
00301
00302 #endif //IMAGE_UTIL_HPP