Skip to content

Instantly share code, notes, and snippets.

@cameronp98
Last active December 16, 2021 16:11
Show Gist options
  • Save cameronp98/88ee235d6c85bd1df5b8deeef404e1c8 to your computer and use it in GitHub Desktop.
Save cameronp98/88ee235d6c85bd1df5b8deeef404e1c8 to your computer and use it in GitHub Desktop.
Create a collage of 4 random images from the unsplash api
import aiohttp
import asyncio
import aiofiles
import io
from PIL import Image
# put your access key here or change "us_api_url" to omit it
ACCESS_KEY = "_"
class ImageData:
def __init__(self, id: str, url: str, image):
self.image = image
self.id = id
self.url = url
# get unsplash api url for given args
def us_api_url(args: str) -> str:
return f"https://api.unsplash.com/{args}?client_id={ACCESS_KEY}"
async def fetch(session: aiohttp.ClientSession, url: str):
async with session.get(url) as response:
return await response.json()
async def fetch_random_image(session: aiohttp.ClientSession) -> ImageData:
image_json = await fetch(session, us_api_url("/photos/random"))
url = image_json["urls"]["thumb"]
async with session.get(url) as resp:
contents = await resp.read()
image = Image.open(io.BytesIO(contents))
image_data = ImageData(image_json["id"], url, image)
return image_data
class Collage:
def __init__(self, image: Image, images: list[ImageData]):
self.image = image
self.images = images
# create a collage of 4 random images requested from the unsplash api and return its generated path ("collages/$.jpg")
async def create_collage(session: aiohttp.ClientSession, sec_size: tuple[int, int] = (200, 200)) -> str:
images = await asyncio.gather(*[fetch_random_image(session) for _ in range(4)])
sections = [image.image.resize(sec_size) for image in images]
collage = Image.new("RGB", (sec_size[0] * 2, sec_size[1] * 2))
# top left
collage.paste(sections[0], (0, 0))
# top right
collage.paste(sections[1], (sec_size[0], 0))
# bottom left
collage.paste(sections[2], (0, sec_size[1]))
# bottom right
collage.paste(sections[3], (sec_size[0], sec_size[1]))
image_ids = [image.id for image in images]
path = f"collages/{'_'.join(image_ids)}.jpg"
collage.save(path)
return path
async def main():
async with aiohttp.ClientSession() as session:
collage_path = await create_collage(session)
print("created collage at:", collage_path)
if __name__ == "__main__":
# see: https://stackoverflow.com/a/66772242
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
asyncio.run(main())
aiofiles==0.8.0
aiohttp==3.8.1
aiosignal==1.2.0
async-timeout==4.0.1
attrs==21.2.0
autopep8==1.6.0
charset-normalizer==2.0.9
frozenlist==1.2.0
idna==3.3
multidict==5.2.0
Pillow==8.4.0
pycodestyle==2.8.0
toml==0.10.2
typing_extensions==4.0.1
yarl==1.7.2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment