J Freebird
J Freebird

Reputation: 3910

Python PIL Save Image to Memory in Binary Mode

I'm reading in an image file from URL and use PIL to add a watermark to it. Then I need to upload the processed image to a FTP server. But after successful uploading, I only see a corrupted image (a "?" in the blank). The FTP server requires binary mode uploading. But I think I'm already using binary mode. I have the following code:

from PIL import Image
import ftplib
import urllib2
import StringIO

try:
    img_file = urllib2.urlopen(img_url)
except Exception, e:
    print 'Warn: image cannot be downloaded

# get the image as file in memory and make video
try:
    im = Image.open(img_file)
except Exception, e:
    print 'Warn: image not valid

# paste_im = Image.open("../asset/logo.png")
# if paste_im is None:
#     print 'Error: paste_im is None'
#     return
# im = watermark(im, paste_im, position=(20, 16), opaque=0.5)

id = 'myID'
pw = 'myPw'
output = StringIO.StringIO()
im.save(output, format='JPEG')
try:
    session = ftplib.FTP('FTP_server_url', id, pw)
    session.storbinary('STOR image.jpg', output)
except ftplib.all_errors as e:
        print '%s' % e 
output.close()
session.quit()
print 'upload succeeded'

I later commented out:

# paste_im = Image.open("../asset/logo.png")
# if paste_im is None:
#     print 'Error: paste_im is None'
#     return
# im = watermark(im, paste_im, position=(20, 16), opaque=0.5)

In order not to introduce extra complexity here, but it still fails. I wonder in which step I might be wrong.

The old code works perfect:

img_file = urllib.urlopen(img_url)
try:
    session = ftplib.FTP('FTP_server_url', id, pw)
    session.storbinary('STOR image.jpg', img_file)
except ftplib.all_errors as e:
    print 'error'
img_file.close()
session.quit()

But now I need to pass it to PIL first to do some processing. Thanks a lot.

Upvotes: 1

Views: 1982

Answers (1)

J Freebird
J Freebird

Reputation: 3910

So as Klaus pointed out, im.save(output, format='JPEG' will set the write pointer to the end of the file, thus the next read (storbinary here) will return 0 bytes. So we should add output.seek(0) to rewind the file object before reading it.

Upvotes: 2

Related Questions