Application Light Phone III : coder un appareil photo tramé

Entrée des artistes de l'opéra de Lausanne en version tramée halftone noir et blanc (trame PT)

Sur mon site photo « a slow vision », j’ai raconté pourquoi je photographie désormais avec Trame : des images en noir et blanc tramé, qui pèsent quelques centaines de kilo-octets. Ici, je raconte comment j’ai fabriqué cette application Light Phone III : d’où elle vient, ce qu’elle fait de chaque photo, et pourquoi ses fichiers sont si légers.

Comme pour mon mode lecture e-ink sous Asahi, je n’ai pas codé seule. Je n’ai toujours pas de compétences en développement : j’ai mené ce projet avec Claude, dans la démarche >slow_prompt. Claude a écrit le code ; j’ai testé chaque version sur mon téléphone, signalé ce qui n’allait pas, et tranché.

Photo tramée prise avec Trame, application Light Phone III : trame PT (Points)
Photo au Light Phone III avec Trame - trame PT (Points)
Photo tramée prise avec Trame, application Light Phone III : trame PX (Pixels)
Photo au Light Phone III avec Trame - trame PX (Pixels)

Ne pas réinventer la roue

Première surprise : le kit de développement officiel de Light, son SDK, ne donne pas accès à l’appareil photo. Impossible, donc, de créer un « outil » Light classique qui photographie.

Mais le Light Phone III fait tourner Android sous LightOS, et il accepte des applications Android ordinaires, à condition de les installer soi-même. C’est ce que fait déjà Zero, l’appareil photo de Vandam Dinh pour le Light Phone III. Zero utilise le vrai déclencheur du téléphone, applique un traitement d’image minimal (pas de réduction du bruit, pas d’accentuation des contours) et propose un mode hyperfocale, avec une mise au point fixe à 2,2 m pour déclencher instantanément.

Surtout, Zero est publié sous licence MIT. J’ai donc le droit de partir de son code, de le modifier et même de le redistribuer, à condition de conserver la mention de copyright de son auteur. Trame est donc un fork de Zero : une version dérivée, qui s’installe à côté de l’original sans le remplacer.

C’est, à mes yeux, l’un des plus beaux arguments du logiciel libre : on ne part jamais de zéro (sans jeu de mots :D).

D’abord savoir ce que je veux

Avant la première ligne de code, j’ai posé quatre règles. C’est la première question du >slow_prompt : « Ai-je d’abord réfléchi par moi-même ? »

  • Noir et blanc uniquement. Pas de bouton couleur, pas de mode RAW.
  • La trame dès la prise de vue. Pas de version « normale » cachée quelque part.
  • Des fichiers légers. C’est la raison d’être du projet.
  • Aucun réseau. Trame ne demande pas l’accès à Internet : les photos restent sur le téléphone.
  • Et une contrainte esthétique : le rendu des illustrations de hu-tech.ch, de l’encre noire sur un papier blanc cassé (#f4f1eb).

Ce que j’ai retiré de Zero, ce que j’ai ajouté

Trame a connu une quinzaine de versions en deux jours. En résumé :

  • Retiré : le bouton couleur / noir et blanc et le mode RAW. Le viseur est toujours en noir et blanc.
  • Conservé : deux modes de prise de vue, AF (mise au point automatique, flash possible) et HF (hyperfocale). La stabilisation optique reste active.
  • Ajouté : la conversion en trame, un bouton pour choisir parmi trois trames, l’enregistrement en PNG et la date de prise de vue dans chaque fichier.

Tout le travail de la trame tient dans un seul nouveau fichier, HalftoneConverter.kt, écrit en Kotlin, le langage d’Android.

Le cœur : ce que Trame fait de chaque photo

À chaque déclenchement, la photo passe par la même chaîne :

    1. Zero capture l’image en niveaux de gris.
    2. Trame la réduit, à environ 2000 pixels sur le grand côté. Une trame n’a pas besoin de 12 millions de pixels pour être lisible.
    3. Le contraste est légèrement renforcé.
    4. Les noirs sont éclaircis : l’encre ne couvre jamais plus de 82 % d’une zone, pour que la trame reste visible dans les ombres au lieu de se boucher en aplat noir.
    5. L’image est tramée, puis enregistrée en PNG.

Trois trames sont proposées, de la plus à la moins texturée.

Trame Principe Rendu
PT, Points Points ronds sur une grille inclinée à 45°, espacés de 7 pixels Vieux journal imprimé
MC, Macintosh Diffusion d’erreur d’Atkinson, grain de 2 pixels Écran des premiers Macintosh
PX, Pixels Diffusion d’erreur d’Atkinson, grain de 1 pixel Liseuse e-ink
Entrée des artistes de l'opéra de Lausanne en version tramée halftone noir et blanc (trame PT)
1 : photo de l'opéra de Lausanne avec trame PT
Photo tramée prise avec Trame, application Light Phone III : trames Points et Pixels côte à côte - Trame MC
2 : photo de l'opéra de Lausanne avec trame MC
Photo tramée prise avec Trame, application Light Phone III : trames Points et Pixels côte à côte - trame PX
3 : photo de l'opéra de Lausanne avec trame PX
Opéra de Lausanne, détail photo tramée PT à 100%
1 : détail à 100% de la trame PT
Opéra de Lausanne, détail photo tramée MC à 100%
2 : détail à 100% de la trame MC
3 : détail à 100% de la trame PX

Les Points, ou la leçon du moiré

La trame Points imite l’imprimerie : plus une zone est sombre, plus le point est gros. Sur le papier, c’est simple. Sur un écran fait de pixels carrés, beaucoup moins.

Première version : des motifs parasites en quinconce sont apparus, ce qu’on appelle un moiré. Les points, espacés d’un nombre de pixels qui ne « tombait » pas juste sur la grille de l’écran, n’étaient jamais dessinés deux fois de la même façon. La solution a été d’aligner exactement chaque point sur les pixels et de le faire grossir pixel par pixel.

Deuxième défaut : dans les gris moyens, les points se touchaient et formaient des lignes diagonales. Trame utilise désormais des points dits « euclidiens » : au-delà de 50 % d’encre, ce ne sont plus des points noirs qui grossissent, mais des trous blancs qui rétrécissent.

Macintosh et Pixels : le dithering de Bill Atkinson

Les deux autres trames reposent sur un algorithme plus ancien : la diffusion d’erreur d’Atkinson (en anglais, Atkinson dithering), mise au point par Bill Atkinson chez Apple pour l’écran noir et blanc du premier Macintosh, en 1984.

Le principe : l’image est parcourue pixel par pixel, de haut en bas et de gauche à droite. Chaque pixel devient soit noir, soit papier. L’écart entre le gris voulu et le résultat (l’« erreur ») est réparti sur six pixels voisins, à raison d’un huitième chacun. Les deux huitièmes restants sont volontairement perdus. C’est cette perte qui donne aux images Atkinson leurs blancs et leurs noirs francs, au prix de quelques détails dans les zones très claires ou très sombres.

Résultat : un grain irrégulier, sans motif répété, donc sans moiré. Avec un grain de 2 pixels, on retrouve l’écran du Macintosh ; avec 1 pixel, l’aspect d’une liseuse.

Pourquoi le PNG change tout

C’est la découverte la plus contre-intuitive du projet. Au départ, Trame enregistrait ses images tramées en JPEG, comme Zero. Elles pesaient entre 2,4 et 3,4 Mo : autant, voire plus, qu’une photo ordinaire.

L’explication tient au fonctionnement du JPEG. Ce format est conçu pour les photographies, faites de dégradés continus ; il comprime mal les bords nets, et une image tramée n’est faite que de cela : des milliers de transitions franches entre deux couleurs.

Le PNG, lui, compresse sans perte et excelle sur les motifs répétitifs à peu de couleurs. Sur mes photos de test, une image pèse environ 100 Ko avec la trame Points et 300 Ko avec la trame Pixels, soit huit à trente fois moins qu’en JPEG. Lors de ma balade à Lausanne, mes 18 images pesaient ensemble 6,7 Mo.

La date, inscrite dans le fichier

En rangeant mes photos dans digiKam (sous Asahi Linux), j’ai remarqué un problème : elles étaient toutes datées de l’heure du transfert, pas de la prise de vue. Les PNG ne contenaient aucune date.

Désormais, Trame écrit dans chaque fichier un bloc EXIF, le même type de métadonnées que celles d’un appareil photo, avec la date de prise de vue et le nom de la trame utilisée. Le PNG prévoit pour cela un emplacement dédié, le bloc « eXIf », décrit dans les extensions officielles du format.

Aucune position GPS, en revanche : Trame n’enregistre que ce dont j’ai besoin.

Installer une application Light Phone III : ce que ça demande

Trame n’est pas signé par Light et ne figure pas dans sa bibliothèque d’outils. Pour l’installer, il faut :

  • activer le mode développeur depuis le tableau de bord Light ;
  • activer le débogage USB dans un menu caché du téléphone, documenté non pas par Light mais par la communauté (lightphone-dev, yarosz) ;
  • autoriser l’affichage de tous les outils, sans quoi l’application s’installe mais reste invisible ;
  • installer l’application depuis un ordinateur, avec l’outil adb de Google.

Je ne détaille pas ces manipulations ici, et pour cause : ces menus ne sont pas documentés par Light, certains réglages voisins ont déjà fait redémarrer des téléphones, et une mise à jour de LightOS peut tout déplacer. Si vous vous lancez, faites-le en connaissance de cause.

Petite déception au passage : j’aurais aimé tout faire sous Asahi Linux. La compilation y fonctionne en théorie, mais mon Mac M3 n’arrivait pas à garder la connexion USB avec le téléphone. J’ai donc développé sous macOS, avec Android Studio.

Écran de l'app Trame sur Light Phone III

Partager Trame ?

Á ce jour, je n’ai pas encore mis en place le partage de Trame. Pour cela, j’ai 2 options : soit déposer les fichiers via cet article, soit créer un compte GitHub et y déposer la première release. L’avenir nous dira quel aura été mon choix final.

Ce que je retiens

  • Le logiciel libre permet de transformer un outil existant pour qu’il colle exactement à ses valeurs, au lieu d’attendre qu’un fabricant le fasse.
  • La sobriété se joue parfois dans un détail invisible : un format de fichier.
  • L’IA a écrit le code, mais les décisions (les quatre règles, les trois trames, le refus des options en plus) sont restées les miennes.

Points de controverse

  • Sortir du cadre de Light. Installer une application Android classique contourne les garde-fous du SDK officiel. C’est une liberté, et une responsabilité.
  • Des outils pas si neutres. Le développement passe par les outils de Google (Android Studio, adb) et d’Apple (macOS).
  • Coder avec une IA. Le projet a demandé beaucoup d’allers-retours avec Claude, donc du calcul et de l’énergie. Je ne saurais les chiffrer.

Sources

Share the Post:

Related Posts