[OSM-dev] NOT-saving empty Mapnik tiles

Igor Podolskiy igor.podolskiy at vwi-stuttgart.de
Mon Aug 15 09:08:51 BST 2011


Hi Markus,

> unfortunately, this line did not work:
>
>> im.save(buf, 'png256')
>
> I tried im.tostring() too, did not work either. This is the error message:
>
>
> Traceback (most recent call last):
>    File "./mapnik_tile.py", line 143, in<module>
>      im.save(buf, 'png256')
> Boost.Python.ArgumentError: Python argument types in
>      Image.save(Image, instance, str)
> did not match C++ signature:
>      save(mapnik::Image32, std::string)
>      save(mapnik::Image32, std::string, std::string)
>
>
> Do you have an idea what went wrong?
Yes - I've again missed what mapnik.Image can and can't :( The problem 
is that mapnik.Image doesn't support saving to a buffer. The tostring() 
method return the raw data as a string, not the PNG data, so testing 
this for length is useless. You can use that to convert a mapnik.Image 
to a PIL image which is much more versatile. I've got it to work now 
with the following code:

import PIL.Image
import mapnik
import StringIO

w, h = 100, 100
mapnik_image = mapnik.Image(w, h)
# <render to the image>
pil_image = PIL.Image.fromstring(
             'RGBA', (w, h), mapnik_image.tostring())
buf = StringIO.StringIO()
# PIL supports saving to a buffer
pil_image.save(buf, 'png')
print buf.len # yields 119 on my machine
# check the length, write the image to disk etc.

I don't really know how it behaves performance-wise on your application. 
As of mapnik 0.7.1, it seems to me to be the only way to get a 
mapnik.Image into a buffer.

BTW, now that you converted the mapnik.Image to a PIL.Image, you can use 
all the PIL methods to analyze it in some other way, of course.

Hope that helps
Igor



More information about the dev mailing list