3

I'm trying to save images from one webpage to the database of another.

Here is a cut down version of the code:

POSTER_SIZE = (200, 310)

LargePoster = urllib2.urlopen(PosterURL).read()
SmallPoster = LargePoster.resize(POSTER_SIZE, Image.ANTIALIAS)

conn = MySQLdb.connect(DB_HOST, DB_USER, DB_PASS, DB_NAME, charset='utf8')
cur = conn()
cur.execute("UPDATE `table` SET `poster`=%s WHERE `id`=%d", (SmallPoster, ID))
cur.close()

Note: I do NOT want to keep the aspect ratio, so do not suggest Image.thumbnail() unless it can stretch it.

As you can see, I retrieve the image using urlopen() and read() but it returns a string. I need this string to be of class Image so I can manipulate it using PIL/Pillow and then later have it output as a string so I can send it to the database.

I know for a fact that all the images are compressed using JPEG.

Updated code for Peter

LargePosterString = urllib2.urlopen(MovieMeta['poster']).read()
LargePosterImage = Image.open(StringIO(LargePosterString))

SmallPosterImage = LargePosterImage.resize(POSTER_SIZE, Image.ANTIALIAS)
SmallPosterString = StringIO()

Format = 'JPEG'
SmallPosterImage.save(SmallPosterString.getvalue(), Format)

2 Answers 2

2

The docs suggest various ways, of which the simplest is probably to make your string into a thing that looks like a file:

from PIL import Image
from StringIO import StringIO

LargeData = urllib2.urlopen(PosterURL).read()

# read data from string
LargePoster = Image.open(StringIO(LargeData))

# After editing the image, turn it back into a string
# for saving in the database:
result = StringIO()
format = 'JPEG' # or whatever you want
SmallPoster.save(result, format)
SmallPosterString = result.getvalue()
Sign up to request clarification or add additional context in comments.

4 Comments

This is a one-time script, so basically any working approach will do. StringIO seems like a good idea. How do I turn my modified image into a string again so I can import it to the database? Can I just use str()?
You can use another StringIO. I've edited the answer to show it.
Okay, so your edited answer is a bit off, but by trial and error I managed to correct it myself. Thank you for your answer, it was very helpful :)
That'll teach me not to edit in a hurry! Thanks for correcting it.
1

So yes you are receiving a string, but have you looked at the string contents? What you have is likely a binary string containing the file contents. Which you should be pretty easily reconstructed into an image. In fact you could probably put that string (as long as it is treated as binary) directly into a blob object or similar and then reconstruct it in whatever is rendering the image.

Check out the parser class as part of the PIL ImageClass

This should be able to reconstruct an image from a stream. As long as your bytes are valid image bytes (JPEG should start with the JFIF identifier).

import ImageFile
fp = open("lena.pgm", "rb")
p = ImageFile.Parser()
while 1:
    s = fp.read(1024)
    if not s:
        break
    p.feed(s)

im = p.close()
im.save("copy.jpg")

With this example it is fair enough to assume you can just use the parser and pass it your "String"

2 Comments

I have accepted Peter's answer because it was both shorter, simpler and didn't require any disk activity, but thank you for a working alternative :)
@TimeSheep this does not require disk activity either. This was a short example of how the parser works. Instead create p = ImageFile.Parser() and p.feed(your_web_string) should do the trick.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.