Search code examples
python-3.xfolium

Object of type PngImageFile is not JSON serializable


I'm trying to do an image overlay. I'm using satellite data to study a phenomenon over Argentina, but I really wanted to use the interactive map through folium. So far, when creating an image, I'm getting an output. But, when I try to overlay the satellite image on to the base map, I'm getting an error message:

Object of type PngImageFile is not JSON serializable

I don't have a clue of how to fix it.

from PIL import Image

fig.savefig('GS.png', transparent=True)

img = Image.open("GS.png")


import folium
from folium import plugins


m = folium.Map(location=[-31.416016, -64.188929],  tiles = 'Stamen Terrain')

folium.raster_layers.ImageOverlay(img,
                     [[ya.min(), xa.min()], [ya.max(), xa.max()]],
                     opacity=0.5).add_to(mapa)

mapa

Solution

  • From the documentation for folium.raster_layers.ImageOverlay, the image parameter must be a "string, file or array-like object":

    image (string, file or array-like object) – The data you want to draw on the map. * If string, it will be written directly in the output file. * If file, it’s content will be converted as embedded in the output file. * If array-like, it will be converted to PNG base64 string and embedded in the output.

    In your code, you passed a PIL Image.

    img = Image.open("GS.png")
    

    and an Image is not JSON serializable.

    Try passing the path to the image file instead:

    import os
    img = os.path.abspath("GS.png")
    
    folium.raster_layers.ImageOverlay(
                         img,
                         [[ya.min(), xa.min()], [ya.max(), xa.max()]],
                         opacity=0.5).add_to(mapa)
    

    Or, if you really need the PIL Image, and since you already have numpy (because it's a dependency of folium), you can also convert the Image to a numpy array before passing to ImageOverlay:

    img = Image.open("GS.png")
    
    folium.raster_layers.ImageOverlay(
                         numpy.array(img),
                         [[ya.min(), xa.min()], [ya.max(), xa.max()]],
                         opacity=0.5).add_to(mapa)