Python: download e ridimensionamento delle immagini dalle API di Unsplash

In questo articolo vedremo come effettuare il download ed il ridimensionamento di un'immagine usando le API di Unsplash con Python.

Per il nostro scopo sono necessari tre moduli aggiuntivi:

  1. requests per effettuare le richieste HTTP.
  2. python-dotenv per leggere la chiave API di Unsplash che memorizzeremo in un file .env.
  3. Pillow per la manipolazione delle immagini.

Dopo aver impostato l'ambiente virtuale e installato i moduli richiesti, salviamo la chiave API di Unsplash in un file .env.

ACCESS_KEY=chiave_API

Quindi invochiamo la funzione load_dotenv() all'inizio del nostro codice in modo da caricare in memoria il file appena creato che andrà a popolare le nostre variabili d'ambiente.

import sys
import os
import requests
from dotenv import load_dotenv
from PIL import Image

load_dotenv()

Ora possiamo creare una funzione per il download dell'immagine remota.

def download_image(url=None, name='image.jpg'):
    if url is None:
        return None
    try:
        res = requests.get(url, allow_redirects=True)
        data = res.content
        with open(name, 'wb') as img:
            img.write(data)
        return True
    except requests.exceptions.RequestException:
        return False

Il contenuto della risposta, la proprietà content, contiene i dati binari dell'immagine che andremo a salvare in locale con il nome specificato.

Ora con il modulo Pillow dobbiamo creare una funzione che effettui il ridimensionamento dell'immagine.

def resize_image(img=None, dimensions=(2000, 850)):
    if img is None:
        return False
    with Image.open(img) as im:
        im.resize(dimensions)
        im.save(f'./resized/{img}')
    os.unlink(img)
    return True

L'immagine da ridimensionare è l'immagine salvata in precedenza. La tuple dimensions specifica l'altezza e la larghezza che verranno usate dal metodo resize(). Quindi l'immagine viene salvata in una nuova destinazione e l'immagine scaricata viene eliminata.

A questo punto non ci resta che definire una funzione che, dato come argomento un termine di ricerca, effettui una richiesta alle API di Unsplash e restituisca l'URL dell'immagine contenuta nel primo risultato della ricerca.

def unsplash_api_search(query=None):
    if query is None:
        return None
    api_url = 'https://api.unsplash.com/search/photos'
    params = {'query': query, 'client_id': os.getenv('ACCESS_KEY')}

    try:
        res = requests.get(api_url, params=params, allow_redirects=True)
        data = res.json()
        if not data.get('total'):
            return None
        return data['results'][0]['urls']['raw']

    except requests.exceptions.RequestException:
        return None

Possiamo usare le funzioni che abbiamo definito direttamente dalla shell con un minimo di interazione da parte dell'utente nella scelta del termine di ricerca.

def main():
    search_query = input('Query: ')
    if not search_query:
        print('Invalid query.')
        sys.exit(1)
    results_url = unsplash_api_search(search_query)
    if results_url is None:
        print('Request error.')
        sys.exit(1)
    print('Got a result from the API.')
    img_name = f'{search_query.strip()}.jpg'
    print('Downloading image...')
    is_image_downloaded = download_image(results_url, img_name)
    if not is_image_downloaded:
        print('Download error.')
        sys.exit(1)
    print(f'Downloaded {img_name}')
    resized_img = resize_image(img_name)
    if not resized_img:
        print('Resize error')
        os.unlink(img_name)
        sys.exit(1)
    print(f'Resized image in ./resized/{img_name}')


if __name__ == '__main__':
    main()
Torna su