[OSM-dev] NOT-saving empty Mapnik tiles
Igor Podolskiy
igor.podolskiy at vwi-stuttgart.de
Mon Aug 15 19:56:10 BST 2011
Hi Markus,
now that I've had time to look into the mapnik code for more than 3
minutes, it is somewhat clearer to me.
> 1. Mapnik internals
> I would guess that Mapnik stored every tile in an array of 256 x 256 Bytes. If you could check such an array's bytes if they all had the same value, this would indicate either strictly monochromacity or complete transparency. In my case there are no monochrome tiles, so I could conclude these tiles to be transparent.
Yes, it does something like that. It is an array of 256 * 256 * 4 bytes
(one byte for each of R, G, B and A channels, so four bytes per pixel).
This is known internally as mapnik::image_32 and is basically an array
of 32-bit integers, one per pixel. Pretty straightforward. What you see
on the Python side is the Python wrapper around this class which exposes
some methods as the Python API. Sadly, no direct access to raw data
(that integer array).
Those tostring() methods (there are two of them) give you access to a
copy of the raw or encoded image data, though. After all, a "string"
(str) is an array of bytes in Python, albeit Python pretends those are
"characters" (as opposed to an "unicode string" which is an array of
proper, possibly multibyte characters). Anyway, you can check for a
fully transparent mapnik.Image with:
def is_transparent(mapnik_image_array):
# starting with the fourth byte, every fourth byte
# represents the alpha value of a pixel
for i in xrange(3, len(mapnik_image_array), 4):
if mapnik_image_array[i] != '\x00':
return False
return True
im = mapnik.Image(256, 256)
print(is_transparent(im.tostring())) # should print True here
Actually, mapnik _can_ save a PNG to a buffer. My accusation from the
previous mail that it couldn't do it was totally wrong, sorry for that
:( Here is how it works:
def is_empty_by_size(mapnik_image):
return im.tostring('png256') == 116
mapnik.Image.tostring() is overloaded, and you can pass a parameter for
the encoding.
Of course, you can go with tmpfs but the above way for storing a PNG in
memory should be simpler (and now you don't need PIL any more).
Bye
Igor
More information about the dev
mailing list