0
votes

I currently am working on a program that pastes two images together with PIL, but PIL is weird, so I had to do a bunch of extra stuff so that I could use links. Anyways, now I can't use what PIL outputted because: AttributeError: 'Image' object has no attribute 'getvalue'

here's the important chunk of my code:

async with aiohttp.ClientSession() as session:
    async with session.get(avurl) as second_image:
        image_bytes = await second_image.read()

with Image.open(BytesIO(image_bytes)).convert("RGB") as first_image:
    output_buffer = BytesIO()
    first_image.save(output_buffer, "png")
    output_buffer.seek(0)

async with aiohttp.ClientSession() as session:
    async with session.get("https://i.imgur.com/dNS0WJO.png") as second_image:
        image_bytes = await second_image.read()

with Image.open(BytesIO(image_bytes)) as second_image:
    output_buffer = BytesIO()
    second_image.save(output_buffer, "png")
    output_buffer.seek(0)

first_image.paste(second_image, (0, 0))
buf = io.BytesIO()
first_image.save(buf, "png")
first_image = first_image.getvalue()

could anyone tell me what line of code i'm missing to fix this? or maybe what i did incorrectly?

2

2 Answers

1
votes

Image objects indeed do not have a getvalue method, it's BytesIO instances that do. Here you should be calling buf.getvalue instead of first_image.getvalue.

buf = io.BytesIO()
first_image.save(buf, "png")
first_image = first_image.getvalue()

Your code looks a bit like this: https://stackoverflow.com/a/33117447/7051394 ; but if you look at the last three lines of that snipper, imgByteArr is still a BytesIO, so imgByteArr.getvalue() is valid.

0
votes

Here's a simpler and possibly faster reformulation of your code:

async with aiohttp.ClientSession() as session:
    image1data = await session.get(avurl).read()
    image2data = await session.get("https://i.imgur.com/dNS0WJO.png").read()

image1 = Image.open(BytesIO(image1data)).convert("RGB")
image2 = Image.open(BytesIO(image2data))

image1.paste(image2, (0, 0))
buf = BytesIO()
image1.save(buf, "png")
composite_image_data = buf.getvalue()

You'll end up with composite_image_data containing PNG data for the composited image.