api pour gerer les images

Bonjour,

Aujourd’hui j’ai eu a faire une api qui devait gérer des images pour un client, mettre en place le serveur et gérer le cache pour les images.

On traitera dans cet article que l’api.

Version 1

La première version était simple :

/test : affiche un formulaire pour envoyer une image. Cette page n’existera pas dans la version finale, c’est juste pour insérer des images manuellement.

/change : permet d’insérer une image. Les données sont envoyées en POST. C’est vers cette page que /test envoie le formulaire.

/get/{id} : permet de donner une image au format jpeg

Les images données sont transformées en png et stockées, si la convertion ne retourne aucune erreur, avec un nom modifié, un hash de {id} en l’occurence. Ainsi on évite de stocker des images qui n’en sont pas et on a des noms qui sont de longueur fixe et avec des caractères acceptés par le système d’exploitation. Le choix du png en stockage est pour éviter de perdre de l’information et le choix du jpg en sortie est pour contrôler la taille et la qualité.

Version 2

Il y a beaucoup de choses que le client fait et qui devrait être fait par le serveur. Par exemple redimensionner l’image. Ca tombe bien c’est le sujet de la version 2.

En réfléchissant, j’ai trouvé 2 façons de redimensionner une image :

  • On donne x, on calcule y.
  • On donne y, on calcule x.

J’ai donc 2 nouvelles entrées dans mon api :

  • /width/{id}/{x}
  • /height/{id}/{y}

Comme pour /get, on récolte une image au format jpeg

Version 3

Après une réflexion un peu plus poussée, j’ai vu que dans la majorité des cas j’ai besoin de spécifier x et y. Le serveur donnera une image aux dimensions voulues.

  • /stretch/{id}/{x}/{y}

Version 4

Etirer une image n’est pas très esthétique. Il faut donc renvoyer une image aux bonnes proportions mais dans les limites x et y données. C’est ce que j’appelle l’image inscrite dans le rectangle x,y.

On peut aussi renvoyer l’image circonscrite, c’est à dire que le rectangle x,y est inscrit dans l’image renvoyée.

Les images que j’appelle inscrite et circonscrite sont des noms empruntés aux cercles mathématiques. Si quelqu’un connait leur véritable nom, qu’il n’hésite pas à laisser un commentaire.

Les 2 fonctionnalités sont les suivantes

  • /in/{id}/{x}/{y} : On donne x et y, on calcule l’image inscrite dans le rectangle de taille x,y.
  • /out/{id}/{x}/{y} : On donne x et y, on calcule l’image circonscrite au rectangle de taille x,y.

Version 5

Des fois, j’ai besoin d’avoir une image aux dimensions données, mais on a écrit plus haut que l’étirement n’est pas bien. Il faut donc envoyer une image inscrite avec des bordures pour remplir le vide. Ce serait bien de pouvoir choisir la couleur des bordures. Qu’a cela ne tienne, c’est moi qui fait l’api, donc, c’est moi qui décide.

  • /pad/{id}/{x}/{y}/{couleur}

La couleur est au format rvb, comme pour le web mais sans dièse (#, le même symbole que hashtag).

Version 6

La dernière fonctionnalité de l’api dont j’avais besoin est la suivante :
Je veux une image aux dimensions spécifiées mais sans bordure, il faut découper l’image plutôt que de rajouter du vide.
Si on fait comme pour les bordures, on découpe deux morceaux égaux pour que l’image soit au bon format. On a un petit problème de cadrage qui peut arriver.
Pour palier au problème, on fournit les coordnnées du point chaud de l’image. C’est à dire le point au centre du sujet de l’image.

Voici le prototype de l’entrée dans l’api

  • /crop/{id}/{x}/{y} : Découpe l’image autour de son centre
  • /crop2/{id}/{x}/{y}/{x2}/{y2} : Découpe l’image autour du point x2,y2

Version 7

J’avais dit que la version 6 intégrait la dernière fonctionnalité voulue. Alors c’est quoi cette version de trop.

Je vais donner ici des fonctionnalité dont je n’ai pas besoin, et donc, pas implémentées mais intéressantes.

  • /cut : coupe un rectangle dans l’image

Beaucoup de filtres peuvent être implémenté, comme emboss et blur. Certains découpages spéciaux, comme une image ronde, ou un rectangle aux coins arrondis, une étoile.

On peut même imaginer une api qui peut enchaîner les fonctionnalités.