Il problema che volevo risolvere
Uso un Waveshare PhotoPainter originale da 7,3 pollici, con display e-paper a 7 colori e risoluzione 800×480. :-D
È un oggetto che mi piace parecchio, soprattutto per utilizzarlo come cornice fotografica, ma dopo averci caricato un po’ di fotografie mi sono scontrato con un problema abbastanza pratico: preparare bene le immagini richiede molto più lavoro di quanto sembri.
Il display ha soltanto 800×480 pixel. Proprio per questo non voglio sprecarne neanche uno.
Con una fotografia orizzontale il problema è relativamente semplice. Con le fotografie verticali, invece, bisogna decidere cosa sacrificare: ritagliare aggressivamente la foto, lasciare dello spazio ai lati oppure trovare un compromesso.
E se le fotografie diventano 50, 100 o diverse centinaia, fare tutto manualmente diventa rapidamente noioso.
Da questa esigenza è nato PhotoPainter Cropper & Converter.
È un piccolo tool che gira interamente nel browser e che ho realizzato per:
- caricare interi gruppi di fotografie;
- scegliere velocemente il ritaglio di ogni foto;
- adattarle esattamente alla risoluzione dello schermo;
- gestire meglio le fotografie verticali;
- ricordare i crop già effettuati;
- convertire automaticamente le immagini nella palette del display e-paper;
- generare i BMP pronti per PhotoPainter;
- scaricare tutto in un unico ZIP.
La cosa importante è che tutta l’elaborazione avviene localmente nel browser: le fotografie non vengono inviate a nessun server.
Il tool è disponibile direttamente qui:
PhotoPainter Cropper & Converter
Prima di tutto: capire come convertiva le immagini PhotoPainter
Il primo problema non era realizzare l’interfaccia di crop.
Quella era la parte relativamente semplice.
Il problema vero era riuscire a generare un’immagine che il PhotoPainter interpretasse esattamente nello stesso modo di quella prodotta dagli strumenti che utilizzavo normalmente.
Ho quindi fatto un po’ di reverse engineering del processo di conversione, cercando di replicarne il comportamento.
Nel mio caso il display di riferimento è:
1 | Waveshare PhotoPainter originale / 7.3" HAT (F) |
La palette utilizzata dal tool è composta da:
1 | Nero |
Naturalmente una fotografia normale contiene milioni di possibili colori, mentre questo display può rappresentarne soltanto sette.
Serve quindi una fase di quantizzazione.
Nel tool ho replicato la conversione utilizzando il dithering Floyd–Steinberg.
In pratica, per ogni pixel viene cercato il colore più vicino disponibile nella palette del display. L’errore introdotto da questa approssimazione viene poi distribuito sui pixel vicini.
La distribuzione utilizzata è quella classica:
1 | X 7/16 |
Il risultato finale non aumenta ovviamente il numero reale di colori del pannello, ma sfrutta la disposizione dei pixel per ottenere una resa visiva molto più convincente rispetto a una semplice conversione al colore più vicino.
Dopo la quantizzazione, il tool genera direttamente un BMP 24 bit bottom-up, nel formato utilizzato dalla pipeline che volevo replicare.
Ho confrontato il risultato su decine e successivamente centinaia di fotografie e, nei miei test, sono riuscito ad arrivare allo stesso risultato della conversione originale, fino ad ottenere immagini con i pixel risultanti identici.
A quel punto potevo finalmente eliminare dal mio workflow la conversione manuale e inglobare tutto nello stesso strumento.
Dal crop alla conversione, tutto dentro una pagina HTML
La prima versione del mio workflow non era nemmeno un’applicazione web.
Avevo due script Python separati:
- uno script con interfaccia Tkinter per ritagliare manualmente le fotografie;
- uno script che effettuava la conversione nel BMP richiesto dal display.
Successivamente ho deciso di riunire tutto.
L’attuale PhotoPainter Cropper & Converter è quindi scritto in HTML, CSS e JavaScript ed è contenuto in un unico file statico.
Non richiede installazione.
Non richiede Python.
Non richiede un backend.
Non richiede l’upload delle fotografie.
Può essere pubblicato come una normale pagina statica oppure aperto direttamente dal computer.
Non è limitato al mio PhotoPainter
Anche se il progetto è nato principalmente per il mio PhotoPainter 800×480 a 7 colori, ho cercato di non legarlo esclusivamente a quel modello.
All’apertura è possibile scegliere il dispositivo di destinazione.
Tra i profili presenti ci sono, ad esempio:
- Waveshare PhotoPainter (B), 800×480, Spectra 6;
- Waveshare PhotoPainter originale / 7.3” HAT (F), 800×480, ACeP 7 colori;
- Waveshare 5.65” e-Paper (F), 600×448;
- Waveshare 4.01” e-Paper HAT (F), 640×400;
- Waveshare 4”/3.6” e-Paper HAT+ (E), 600×400;
- Waveshare 13.3” e-Paper HAT+ (E), 1600×1200;
- alcuni display Waveshare bianco/nero/rosso;
- bianco/nero/giallo;
- bianco e nero;
- display in scala di grigi.
Ho aggiunto inoltre dei profili generici, nei quali è possibile indicare manualmente larghezza e altezza e scegliere la tipologia di palette:
1 | Bianco/Nero |
Quindi il cropper può essere utilizzato anche con altri display, purché il formato di output sia adatto al proprio workflow.
Il crop in batch
Il workflow che utilizzo normalmente parte da una cartella contenente tutte le fotografie che voglio preparare.
Dal tool posso selezionare direttamente la cartella oppure aggiungere le immagini separatamente.
A quel punto si passa all’editor.
Per ogni fotografia viene visualizzato il rettangolo corrispondente esattamente al rapporto d’aspetto del display scelto.
Nel mio caso:
1 | 800 / 480 = 1,666... |
Posso quindi spostare e ridimensionare velocemente l’inquadratura fino a ottenere la composizione che voglio.
Questo è particolarmente utile quando preparo tante foto insieme: non voglio che sia un algoritmo a decidere automaticamente quale sia la parte importante della fotografia.
Se ci sono delle persone, ad esempio, voglio essere io a decidere chi deve rimanere al centro.
Mi è capitato anche di utilizzare la stessa fotografia in raccolte differenti con crop diversi. Per una raccolta destinata ai nonni, ad esempio, posso tranquillamente scegliere un’inquadratura maggiormente concentrata sui bambini piuttosto che sugli adulti.
È una piccola cosa, ma quando si preparano centinaia di immagini fa la differenza.
Le fotografie verticali e il riempimento sfocato
Questo è probabilmente l’aspetto che personalmente trovo più utile.
Una fotografia verticale e un display 800×480 orizzontale hanno rapporti d’aspetto completamente diversi.
Posso ovviamente ingrandire la fotografia fino a riempire lo schermo, ma in quel modo rischio di perdere una quantità enorme dell’immagine originale.
Oppure posso mantenere un’inquadratura più ampia.
A quel punto, però, alcune aree del frame rimangono fuori dalla fotografia.
Il tool permette di gestirle in due modi:
1 | white |
Con white viene utilizzato semplicemente uno sfondo bianco.
Con blur, invece, viene generato uno sfondo utilizzando la fotografia stessa, ingrandita e fortemente sfocata, mentre la parte selezionata rimane nitida in primo piano.
È lo stesso tipo di effetto che si vede spesso nei player video o nelle applicazioni social quando un contenuto verticale deve essere mostrato all’interno di uno spazio orizzontale.
Nel mio caso lo preferisco nettamente alle bande vuote.
Soprattutto su un piccolo display 800×480 permette di sfruttare l’intera superficie mantenendo comunque visibile una porzione più grande della fotografia originale.
Il raggio della sfocatura viene inoltre calcolato proporzionalmente alla larghezza del display, quindi non è legato rigidamente agli 800 pixel del mio PhotoPainter.
L’altra cosa che mi serviva: ricordare tutti i crop
Dopo aver preparato parecchie fotografie mi sono accorto di un altro problema.
Immaginiamo di avere una raccolta di 100 fotografie.
Le preparo tutte, le converto e le metto sul PhotoPainter.
Passano quattro mesi.
Nel frattempo trovo altre venti fotografie e voglio aggiungerle alla raccolta.
Potrei naturalmente elaborare soltanto quelle nuove, ma magari riguardando le vecchie mi accorgo che su alcune vorrei modificare leggermente l’inquadratura.
Senza conservare lo stato precedente dovrei praticamente ricominciare da capo.
Per questo, insieme a ogni fotografia, PhotoPainter Cropper genera un piccolo file:
1 | <nome>_ppcrop.txt |
Al suo interno vengono memorizzate le informazioni necessarie per ricostruire il ritaglio.
Il formato contiene dati come:
1 | image_name= |
Oltre alle coordinate assolute salvo anche le coordinate normalizzate rispetto alla dimensione dell’immagine.
Questo permette al programma di recuperare la selezione anche quando le dimensioni dell’immagine non coincidono più esattamente con quelle memorizzate, purché siano disponibili le coordinate normalizzate.
Quando seleziono nuovamente una cartella, il programma associa automaticamente:
1 | foto.jpg |
e ripristina l’inquadratura precedente.
Questa, nel mio utilizzo, è diventata una delle funzioni più importanti.
Posso conservare insieme:
1 | IMG_1234.jpg |
e considerare il file TXT quasi come un piccolo file di progetto della fotografia.
La foto originale rimane intatta.
Il TXT descrive semplicemente come voglio visualizzarla sul PhotoPainter.
Lavorare velocemente con la tastiera
Un’altra esigenza nata dall’elaborazione di molte fotografie era evitare di dover cliccare continuamente sui pulsanti.
Il crop può quindi essere controllato quasi interamente dalla tastiera.
Le scorciatoie principali sono:
1 | Frecce sposta il crop |
È possibile utilizzare anche la rotellina del mouse per cambiare la dimensione del ritaglio.
Nella parte inferiore dell’editor è inoltre presente una barra con le miniature.
In questo modo posso vedere dove mi trovo nella raccolta, quali immagini ho già confermato e tornare rapidamente su una fotografia precedente.
Quando bisogna sistemare cento foto, queste piccole scorciatoie fanno risparmiare parecchio tempo.
Esportazione
Una volta completata la selezione si passa alla fase di esportazione.
Per ogni fotografia confermata il programma genera tre elementi:
1 | <nome>_ppcrop.txt |
Il JPG contiene il risultato del crop.
Il BMP contiene invece l’immagine convertita nella palette del display selezionato con dithering Floyd–Steinberg.
È possibile scaricare i singoli file oppure generare direttamente:
1 | photopainter_export.zip |
All’interno dello ZIP viene mantenuta questa struttura:
1 | foto1_ppcrop.txt |
I file _ppcrop.txt possono poi essere riportati nella stessa cartella delle fotografie originali.
Al caricamento successivo il tool li riconoscerà e ripristinerà i crop.
Nessuna fotografia viene caricata online
Visto il tipo di dati che normalmente passo a questo strumento, per me era importante anche questo aspetto.
Le fotografie sono spesso foto personali e familiari.
PhotoPainter Cropper & Converter non necessita di inviarle da nessuna parte.
Il browser legge i file locali, effettua il crop, crea il canvas, esegue la quantizzazione, costruisce il BMP e infine crea anche lo ZIP.
Tutto avviene lato client.
Persino la generazione dello ZIP è implementata direttamente nella pagina, senza appoggiarsi a un servizio esterno.
Questo significa che posso utilizzare il programma anche semplicemente aprendo localmente il file HTML.
Un singolo file HTML
Alla fine il progetto è diventato volutamente molto semplice da distribuire.
Tutto è contenuto in un unico:
1 | index.html |
Al suo interno ci sono:
1 | HTML |
L’interfaccia è disponibile in:
1 | Italiano |
Il browser prova a scegliere automaticamente la lingua, che può comunque essere cambiata dall’interfaccia.
Questa scelta rende il progetto molto semplice da pubblicare: non c’è un’applicazione da installare o un servizio da mantenere.
È semplicemente una pagina statica.
Provare PhotoPainter Cropper & Converter
Il tool è pubblicato qui:
https://5m1.ovh/PhotoPainterCropper/index.html
La procedura completa è:
- aprire PhotoPainter Cropper & Converter;
- scegliere il proprio display e-paper;
- caricare la cartella contenente le fotografie;
- includere gli eventuali
_ppcrop.txtdi una sessione precedente; - iniziare il crop;
- posizionare e ridimensionare l’inquadratura;
- scegliere, quando necessario, tra riempimento bianco e sfocato;
- confermare le fotografie;
- passare all’esportazione;
- generare JPG e BMP;
- scaricare lo ZIP;
- conservare i file
_ppcrop.txtinsieme alle immagini originali.
Il codice sorgente sarà disponibile anche su GitHub:
[DA VERIFICARE: inserire URL repository GitHub]
Conclusioni
Questo progetto è nato semplicemente perché avevo un problema che continuava a ripresentarsi.
Volevo scegliere le mie fotografie preferite, visualizzarle sul PhotoPainter sfruttando al massimo quei 800×480 pixel e non perdere ogni volta tempo tra crop, fotografie verticali, conversioni e lavorazioni già fatte mesi prima.
Prima ho automatizzato il crop.
Poi la conversione.
Poi ho aggiunto il riempimento sfocato.
Poi mi sono accorto che avevo bisogno di ricordare le selezioni.
Alla fine tutto è finito in una singola pagina HTML che ormai utilizzo per elaborare intere raccolte di fotografie.
È esattamente il genere di progetto per cui esiste GeeGeek: qualcosa che mi serviva, che ho costruito per risolvere un mio problema concreto e che, una volta arrivato a funzionare come volevo, tanto vale condividere.
Se volete provarlo, lo trovate qui:
PhotoPainter Cropper & Converter
Spero possa essere utile anche a qualcun altro che utilizza un PhotoPainter, un display Waveshare o più in generale una cornice e-paper e si è trovato davanti allo stesso problema.