added support for saving images into Python String object

(NOTE: some methods have different signitures now- API changed)
This commit is contained in:
Artem Pavlenko 2008-01-25 14:40:48 +00:00
parent e268660ecc
commit 651cdbe968
10 changed files with 135 additions and 92 deletions

View file

@ -29,10 +29,11 @@ prefix = env['PYTHON_PREFIX'] + '/' + env['LIBDIR_SCHEMA'] + '/python' + env['PY
install_prefix = env['DESTDIR'] + '/' + prefix
linkflags = ''
libraries = ['mapnik','png','jpeg']
if env['THREADING'] == 'multi':
libraries = ['mapnik', 'boost_python%s-mt' % env['BOOST_APPEND']]
libraries.append('boost_python%s-mt' % env['BOOST_APPEND'])
else :
libraries = ['mapnik', 'boost_python%s' % env['BOOST_APPEND']]
libraries.append('mapnik', 'boost_python%s' % env['BOOST_APPEND'])
if env['PLATFORM'] == 'Darwin':
if env['THREADING'] == 'multi':

View file

@ -21,24 +21,43 @@
*****************************************************************************/
//$Id$
// boost
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
// mapnik
#include <mapnik/graphics.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/jpeg_io.hpp>
#include <mapnik/png_io.hpp>
#include <sstream>
using mapnik::Image32;
using namespace boost::python;
using mapnik::save_to_file;
PyObject* rawdata( Image32 const& im)
// output 'raw' pixels
PyObject* tostring1( Image32 const& im)
{
int size = im.width() * im.height() * 4;
return ::PyString_FromStringAndSize((const char*)im.raw_data(),size);
}
void (*save_to_file1)(std::string const&,std::string const&, mapnik::Image32 const&) = mapnik::save_to_file;
void (*save_to_file2)(std::string const&, mapnik::Image32 const&) = mapnik::save_to_file;
// encode (png,jpeg)
PyObject* tostring2(Image32 const & im, std::string const& format)
{
std::ostringstream ss(std::ios::out|std::ios::binary);
if (format == "png") save_as_png(ss,im.data());
else if (format == "png256") save_as_png256(ss,im.data());
else if (format == "jpeg") save_as_jpeg(ss,85,im.data());
else throw mapnik::ImageWriterException("unknown format: " + format);
return ::PyString_FromStringAndSize((const char*)ss.str().c_str(),ss.str().size());
}
void (*save_to_file1)( mapnik::Image32 const&, std::string const&,std::string const&) = mapnik::save_to_file;
void (*save_to_file2)( mapnik::Image32 const&, std::string const&) = mapnik::save_to_file;
void blend (Image32 & im, unsigned x, unsigned y, Image32 const& im2, float opacity)
{
@ -48,7 +67,7 @@ void blend (Image32 & im, unsigned x, unsigned y, Image32 const& im2, float opac
void export_image()
{
using namespace boost::python;
class_<Image32>("Image","This class represents a 32 bit image.",init<int,int>())
class_<Image32>("Image","This class represents a 32 bit RGBA image.",init<int,int>())
.def("width",&Image32::width)
.def("height",&Image32::height)
.def("view",&Image32::get_view)
@ -56,8 +75,9 @@ void export_image()
(&Image32::getBackground,return_value_policy<copy_const_reference>()),
&Image32::setBackground, "The background color of the image.")
.def("blend",&blend)
.def("tostring",&tostring1)
.def("tostring",&tostring2)
.def("save", save_to_file1)
.def("save", save_to_file2)
;
def("rawdata",&rawdata); // FIXME : I dont think we need this one anymore
def("save_to_file", save_to_file1);
def("save_to_file", save_to_file2);
}

View file

@ -24,13 +24,34 @@
#include <boost/python.hpp>
#include <mapnik/image_util.hpp>
#include <mapnik/image_view.hpp>
#include <mapnik/jpeg_io.hpp>
#include <mapnik/png_io.hpp>
#include <sstream>
using mapnik::ImageData32;
using mapnik::image_view;
using mapnik::save_to_file;
void (*view_to_file1)(std::string const&,std::string const&, image_view<ImageData32> const&) = mapnik::save_to_file;
void (*view_to_file2)(std::string const&, image_view<ImageData32> const&) = mapnik::save_to_file;
// output 'raw' pixels
PyObject* view_tostring1(image_view<ImageData32> const& view)
{
int size = view.width() * view.height() * 4;
return ::PyString_FromStringAndSize((const char*)view.data().getBytes(),size);
}
// encode (png,jpeg)
PyObject* view_tostring2(image_view<ImageData32> const & view, std::string const& format)
{
std::ostringstream ss(std::ios::out|std::ios::binary);
if (format == "png") save_as_png(ss,view.data());
else if (format == "png256") save_as_png256(ss,view.data());
else if (format == "jpeg") save_as_jpeg(ss,85,view.data());
else throw mapnik::ImageWriterException("unknown format: " + format);
return ::PyString_FromStringAndSize((const char*)ss.str().c_str(),ss.str().size());
}
void (*save_view1)(image_view<ImageData32> const&, std::string const&,std::string const&) = mapnik::save_to_file;
void (*save_view2)(image_view<ImageData32> const&, std::string const&) = mapnik::save_to_file;
void export_image_view()
{
@ -38,8 +59,9 @@ void export_image_view()
class_<image_view<ImageData32> >("ImageView","A view into an image.",no_init)
.def("width",&image_view<ImageData32>::width)
.def("height",&image_view<ImageData32>::height)
.def("tostring",&view_tostring1)
.def("tostring",&view_tostring2)
.def("save",save_view1)
.def("save",save_view2)
;
def("save_to_file",view_to_file1);
def("save_to_file",view_to_file2);
}

View file

@ -84,7 +84,7 @@ void render_tile_to_file(const mapnik::Map& map,
{
mapnik::Image32 image(width,height);
render(map,image,offset_x, offset_y);
image.saveToFile(file,format);
mapnik::save_to_file(image.data(),file,format);
}
void render_to_file1(const mapnik::Map& map,
@ -93,7 +93,7 @@ void render_to_file1(const mapnik::Map& map,
{
mapnik::Image32 image(map.getWidth(),map.getHeight());
render(map,image,0,0);
mapnik::save_to_file(filename,format,image);
mapnik::save_to_file(image,filename,format);
}
void render_to_file2(const mapnik::Map& map,
@ -101,7 +101,7 @@ void render_to_file2(const mapnik::Map& map,
{
mapnik::Image32 image(map.getWidth(),map.getHeight());
render(map,image,0,0);
mapnik::save_to_file(filename,image);
mapnik::save_to_file(image,filename);
}

View file

@ -307,10 +307,10 @@ m.zoom_to_box(Envelope(1405120.04127408,-247003.813399447,1706357.31328276,-2509
im = Image(m.width,m.height)
render(m, im)
# Save image to file
save_to_file('demo.png', 'png',im) # true-colour RGBA
save_to_file('demo256.png', 'png256',im) # save to palette based (max 256 colours) png
save_to_file('demo.jpg', 'jpeg',im)
# Save image to files
im.save('demo.png', 'png') # true-colour RGBA
im.save('demo256.png', 'png256') # save to palette based (max 256 colours) png
im.save('demo.jpg', 'jpeg')
print """\n\nThree maps have been rendered in the current directory:
- demo.jpg

View file

@ -72,8 +72,6 @@ namespace mapnik
return image_view<ImageData32>(x,y,w,h,data_);
}
void saveToFile(const std::string& file,const std::string& format="auto");
private:
inline bool checkBounds(unsigned x, unsigned y) const

View file

@ -54,17 +54,17 @@ namespace mapnik {
};
template <typename T>
MAPNIK_DECL void save_to_file(std::string const& filename,
std::string const& type,
T const& image);
MAPNIK_DECL void save_to_file(T const& image,
std::string const& filename,
std::string const& type);
// guess type from file extension
template <typename T>
MAPNIK_DECL void save_to_file(std::string const& filename,
T const& image);
MAPNIK_DECL void save_to_file(T const& image,
std::string const& filename);
template <typename T>
void save_as_png(std::string const& filename,
T const& image);
void save_as_png(T const& image,
std::string const& filename);
template <typename T>
void save_as_jpeg(std::string const& filename,
@ -268,32 +268,32 @@ namespace mapnik {
}
}
inline MAPNIK_DECL void save_to_file (std::string const& file,
std::string const& type,
Image32 const& image)
inline MAPNIK_DECL void save_to_file (Image32 const& image,
std::string const& file,
std::string const& type)
{
save_to_file<ImageData32>(file,type,image.data());
save_to_file<ImageData32>(image.data(),file,type);
}
inline MAPNIK_DECL void save_to_file(std::string const& file,
Image32 const& image)
inline MAPNIK_DECL void save_to_file(Image32 const& image,
std::string const& file)
{
save_to_file<ImageData32>(file,image.data());
save_to_file<ImageData32>(image.data(),file);
}
#ifdef _MSC_VER
template MAPNIK_DECL void save_to_file<ImageData32>(std::string const&,
std::string const& ,
ImageData32 const&);
template MAPNIK_DECL void save_to_file<ImageData32>(std::string const&,
ImageData32 const&);
template MAPNIK_DECL void save_to_file<ImageData32>(ImageData32 const&,
std::string const&,
std::string const&);
template MAPNIK_DECL void save_to_file<ImageData32>(ImageData32 const&,
std::string const&);
template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (std::string const&,
std::string const& ,
image_view<ImageData32> const&);
template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (image_view<ImageData32> const&,
std::string const&,
std::string const&);
template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (std::string const&,
image_view<ImageData32> const&);
template MAPNIK_DECL void save_to_file<image_view<ImageData32> > (image_view<ImageData32> const&,
std::string const&);
#endif

View file

@ -28,75 +28,83 @@
namespace mapnik {
template <typename T>
class image_view
{
public:
typedef typename T::pixel_type pixel_type;
template <typename T>
class image_view
{
public:
typedef typename T::pixel_type pixel_type;
image_view(unsigned x, unsigned y, unsigned width, unsigned height, T const& data)
image_view(unsigned x, unsigned y, unsigned width, unsigned height, T const& data)
: x_(x),
y_(y),
width_(width),
height_(height),
data_(data)
{
{
if (x_ >= data_.width()) x_=data_.width()-1;
if (y_ >= data_.height()) x_=data_.height()-1;
if (x_ + width_ > data_.width()) width_= data_.width() - x_;
if (y_ + height_ > data_.height()) height_= data_.height() - y_;
}
}
~image_view() {}
~image_view() {}
image_view(image_view<T> const& rhs)
image_view(image_view<T> const& rhs)
: x_(rhs.x_),
y_(rhs.y_),
width_(rhs.width_),
height_(rhs.height_),
data_(rhs.data_) {}
image_view<T> & operator=(image_view<T> const& rhs)
{
image_view<T> & operator=(image_view<T> const& rhs)
{
if (&rhs==this) return *this;
x_ = rhs.x_;
y_ = rhs.y_;
width_ = rhs.width_;
height_ = rhs.height_;
data_ = rhs.data_;
}
}
inline unsigned x() const
{
inline unsigned x() const
{
return x_;
}
}
inline unsigned y() const
{
inline unsigned y() const
{
return y_;
}
}
inline unsigned width() const
{
inline unsigned width() const
{
return width_;
}
inline unsigned height() const
{
}
inline unsigned height() const
{
return height_;
}
}
inline const pixel_type* getRow(unsigned row) const
{
inline const pixel_type* getRow(unsigned row) const
{
return data_.getRow(row + y_) + x_;
}
private:
unsigned x_;
unsigned y_;
unsigned width_;
unsigned height_;
T const& data_;
};
}
inline T& data()
{
return data_;
}
inline T const& data() const
{
return data_;
}
private:
unsigned x_;
unsigned y_;
unsigned width_;
unsigned height_;
T const& data_;
};
}
#endif // IMAGE_VIEW_HPP

View file

@ -38,7 +38,7 @@ namespace mapnik {
JOCTET * buffer;
} dest_mgr;
void init_destination( j_compress_ptr cinfo)
inline void init_destination( j_compress_ptr cinfo)
{
dest_mgr * dest = reinterpret_cast<dest_mgr*>(cinfo->dest);
dest->buffer = (JOCTET*) (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
@ -47,7 +47,7 @@ namespace mapnik {
dest->pub.free_in_buffer = BUFFER_SIZE;
}
boolean empty_output_buffer (j_compress_ptr cinfo)
inline boolean empty_output_buffer (j_compress_ptr cinfo)
{
dest_mgr * dest = reinterpret_cast<dest_mgr*>(cinfo->dest);
dest->out->write((char*)dest->buffer, BUFFER_SIZE);
@ -57,7 +57,7 @@ namespace mapnik {
return true;
}
void term_destination( j_compress_ptr cinfo)
inline void term_destination( j_compress_ptr cinfo)
{
dest_mgr * dest = reinterpret_cast<dest_mgr*>(cinfo->dest);
size_t size = BUFFER_SIZE - dest->pub.free_in_buffer;

View file

@ -60,10 +60,4 @@ namespace mapnik
{
return background_;
}
void Image32::saveToFile(const std::string& file,const std::string& format)
{
//TODO: image writer factory
save_to_file(file,format,data_);
}
}