Reputation: 113
I am trying to stitch together (too) many images -- for what it's worth, PNG map tiles downloaded from a Tile Map Service -- into one large image. Perhaps naïvely, I'm using Python Pillow. It worked up to zoom level 9, but now I'm getting a MemoryError. What is a better way to do this? My system has 16 GB of RAM, and ought to be able to do this in virtual memory I supposed, but I guess not.
The code I'm using (this is from Stamen's the-ultimate-tile-stitcher):
out_img = Image.new('RGBA', (out_w, out_h), (0, 0, 255, 0))
for filepath in tqdm.tqdm(filepaths):
x, y = xy(filepath)
x, y = x - x_0, y - y_0
tile = Image.open(filepath)
out_img.paste(tile, box=(x * tile_w, y * tile_h, (x + 1) * tile_w, (y + 1) * tile_h))
At zoom level 9, I have 512 x 512 tiles, each 512 x 512 pixels -- resulting in a 131,072 x 131,072-pixel image. The stack trace for the error I get:
Traceback (most recent call last):
File "stitcher.py", line 65, in <module>
main()
File "stitcher.py", line 53, in main
out_img = Image.new('RGBA', (out_w, out_h), (0, 0, 255, 0))
File "C:\Anaconda3\envs\gis\lib\site-packages\PIL\Image.py", line 2671, in new
return im._new(core.fill(mode, size, color))
MemoryError
Is there some way to make PIL swallow this huge pill? Or some better way to do what I'm trying to do?
Upvotes: 1
Views: 856
Reputation: 59302
My system has 16 GB of RAM, and ought to be able to do this in virtual memory I supposed, but I guess not.
You are mixing two concepts here: 16 GB of RAM is physical RAM and is only barely related to virtual memory. Your virtual memory may be as small as 2 GB (for a 32 bit application that is not large address aware) or as big as 8 TB, if your pagefile has a large enough disk to expand to.
131,072 x 131,072-pixel image
The calculation is easy: 131072 * 131072 pixels * 4 bytes/pixel = 68719476736 bytes = 64 GB, because you need at least 4 bytes to store R, G, B and A.
So, along with your 16 GB physical RAM, you need at least 48 GB of additional memory in the pagefile. This calculation does neither include the size for the 260000 small images nor other applications or the operating system.
What is a better way to do this?
It's hard to say and depends on what you want to do with that image. Saving it as a file will hardly be possible, because many image formats have limits for the amout of pixels.
BMP version 2 allows a maximum of 32k pixels in size. JPG is limited to 64k pixels. BMP version 3 should be 2G pixels and PNG should go up to 4G pixels, but you'll really have trouble finding an application that smoothly displays those images. IMHO, GDI on Windows will start complaining at 2 GB.
Basically that's one of the reasons why tiles are used.
Upvotes: 1