Search code examples
python-3.xpython-imaging-libraryplpython

How to access images with plpython using the pillow libary and saving on postgresql bytea column?


I have a problem accessing an image procesed from database stored as a bytea here is my pl to resize an image.

CREATE OR REPLACE FUNCTION public.ajustar(randstring bytea)
 RETURNS bytea
 LANGUAGE plpythonu
AS $function$
    from io import BytesIO
    import PIL
    from PIL import Image
    basewidth = 300
    mem_file = BytesIO()
    mem_file.write(randstring)
    img = Image.open(mem_file)
    wpercent = (basewidth/float(img.size[0]))
    hsize = int((float(img.size[1])*float(wpercent)))
    img = img.resize((basewidth,hsize), PIL.Image.ANTIALIAS)
    img.close()
    return img
$function$;

So my problem is returning a bytea but get an adress, How I can get the image rather than the adress?. The only way it works is saving the img to a file with img.save('/home/postgres/imagen.jpg'), instead I need to put in a object to replace the image in the database.

pruebas=# select encode(ajustar(foto), 'escape') from personal where id=193;
                           encode                           
------------------------------------------------------------
 <PIL.Image.Image image mode=RGB size=300x347 at 0x1895990>
(1 fila)

Thanks in advance


Solution

  • With this function you can process images on the database (jpeg format). This are made with plpython and if you are using Linux update the pillow library on Centos 7 with

    $sudo pip install Pillow
    

    or

    $sudo pip update Pillow
    

    This is the function.

    CREATE FUNCTION ajustar(randstring bytea) RETURNS bytea
        LANGUAGE plpythonu
        AS $$
        from io import BytesIO
        import PIL
        from PIL import Image
        basewidth = 300
        mem_file = BytesIO()
        mem_file.write(randstring)
        img = Image.open(mem_file)
        wpercent = (basewidth/float(img.size[0]))
        hsize = int((float(img.size[1])*float(wpercent)))
        img = img.resize((basewidth,hsize), PIL.Image.ANTIALIAS)
        salida = BytesIO()
        img.save(salida, format='JPEG')
        hex_data = salida.getvalue()
        img.close()
        return hex_data
    $$;