Saving BytesIO to Django ImageField
Asked Answered
D

1

7

I have a web scraper that I want to download an image of the page it's scraping and save it as a "screenshot" ImageField in a Django model. I am using this code:

def save_screenshot(source,screenshot):
    box = (0, 0, 1200, 600)
    im = Image.open(io.BytesIO(screenshot))
    region = im.crop(box)
    tempfile_io = io.BytesIO()
    region.save(tempfile_io, 'JPEG', optimize=True, quality=70)
    source.screenshot.save(source.slug_name+"-screenshot",ContentFile(tempfile_io.getvalue()),save=True)

It saves the screenshot to the /media/news_source_screenshots/ directory but doesn't save it to the model. The model field is defined as:

screenshot = models.ImageField(upload_to='news_source_screenshots',blank=True,null=True)

What am I missing?

Diallage answered 30/12, 2016 at 22:29 Comment(5)
I see that you're saving the tempfile without data, you must be save the region... in source.screenshot.save(source.slug_name+"-screenshot", ContentFile(region.get_value()), save=True), remember that region os now your tempfile, cause tempfile_io is a void bufferMosher
thanks @german-alzate-martinez but when I tried your fix I got: code TypeError: 'Image' does not support the buffer interface code and the image is not longer saved in the /media/news_source_screenshost/ directoryDiallage
Try change the buffer to string io, what return region?Mosher
I changed the line tempfile_io = io.BytesIO() to tempfile_io = io.StringIO() and got TypeError: string argument expected, got 'bytes' referring to the region.save line of code @german-alzate-martinezDiallage
What return region with your original code?Mosher
D
3

So it turns out the above code works great! The issue was that I was calling the above method using a piece of code like this:

source = NewsSource.objects.get(name=name)
html,screenshot = get_url(source.url)
save_screenshot(source,screenshot)
source.save()

So the save_sceenshot method worked but then the work it had done was overwritten by my source.save() call. Go figure!

Diallage answered 2/1, 2017 at 3:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.