How to save image in-memory and upload using PIL?

2020-03-26 07:22发布

问题:

I'm fairly new to Python. Currently I'm making a prototype that takes an image, creates a thumbnail out of it and and uploads it to the ftp server.

So far I got the get image, convert and resize part ready.

The problem I run into is that using the PIL (pillow) Image library converts the image is a different type than that can be used when uploading using storebinary()

I already tried some approaches like using StringIO or BufferIO to save the image in-memory. But I'm getting errors all the time. Sometimes the image does get uploaded but the file appears to be empty (0 bytes).

Here is the code I'm working with:

import os
import io
import StringIO
import rawpy
import imageio
import Image
import ftplib

# connection part is working
ftp = ftplib.FTP('bananas.com')
ftp.login(user="banana", passwd="bananas")
ftp.cwd("/public_html/upload")

def convert_raw():
    files = os.listdir("/home/pi/Desktop/photos")

    for file in files:
        if file.endswith(".NEF") or file.endswith(".CR2"):
            raw = rawpy.imread(file)
            rgb = raw.postprocess()
            im = Image.fromarray(rgb)
            size = 1000, 1000
            im.thumbnail(size)

            ftp.storbinary('STOR Obama.jpg', img)
            temp.close()
    ftp.quit()

convert_raw()

What I tried:

temp = StringIO.StringIO
im.save(temp, format="png")
img = im.tostring()
temp.seek(0)
imgObj = temp.getvalue()

The error I'm getting lies on the line ftp.storbinary('STOR Obama.jpg', img).

Message:

buf = fp.read(blocksize)
attributeError: 'str' object has no attribute read

回答1:

Do not pass a string to storbinary. You should pass a file or file object (memory-mapped file) to it instead. Also, this line should be temp = StringIO.StringIO(). So:

temp = StringIO.StringIO() # this is a file object
im.save(temp, format="png") # save the content to temp
ftp.storbinary('STOR Obama.jpg', temp) # upload temp


回答2:

For Python 3.x use BytesIO instead of StringIO:

temp = BytesIO()
im.save(temp, format="png")
ftp.storbinary('STOR Obama.jpg', temp.getvalue())