Comment l'application de retouche d'images Photopea utilise l'API File Handling pour permettre aux utilisateurs d'ouvrir des fichiers depuis leur explorateur de fichiers

L'API File Handling permet aux applications Web de s'enregistrer en tant que gestionnaire de fichiers pour les formats de fichiers qu'elles peuvent prendre en charge. Découvrez comment l'application de retouche d'images Photopea utilise cette API.

Introduction

(Cet article est également disponible sous forme de vidéo.)

Photopea est un éditeur d'images en ligne sans frais développé par Ivan Kutskir. Ivan a commencé à travailler sur l'application en 2012 et tient un blog sur lequel il partage les principales fonctionnalités qu'il ajoute à Photopea. Photopea est compatible avec les formats PSD (Adobe Photoshop), XCF (GIMP), Sketch (Sketch App), XD (Adobe XD) et CDR (CorelDRAW).

L'application Photopea.

Gestion des fichiers dans Photopea

En tant que PWA installable, Photopea s'exécute dans une fenêtre autonome lorsque l'utilisateur choisit d'installer l'application. Cela permet de débloquer une super-fonctionnalité des PWA, que Photopea utilise de manière intensive : la gestion des fichiers.

La partie déclarative de l'API de gestion de fichiers

Après l'installation, Photopea s'enregistre en tant que gestionnaire de fichiers auprès du système d'exploitation pour les différents formats de fichiers qu'il prend en charge. Pour ce faire, ajoutez le champ file_handlers au fichier manifeste de l'application Web. Chaque type de fichier accepté est un objet, action a une URL relative comme valeur, et l'objet accept est un mappage des types MIME et des extensions de fichier associées. Par exemple, {"image/jpeg": [".jpeg", ".jpg"]}. Le code suivant est le fichier manifeste d'application Web de Photopea en production, avec les parties pertinentes mises en surbrillance.

{
    "name": "Photopea",
    "short_name": "Photopea",
    "display": "standalone",
    "icons": [
        {  "src": "promo/icon512.png",     "type": "image/png", "sizes": "512x512"  },
        {  "src": "promo/maskable512.png", "type": "image/png", "sizes": "512x512", "purpose":"maskable"  }
    ],
    "start_url": "/?utm_source=homescreen",
    "background_color":"#0f171d",
    "theme_color": "#474747",
    "file_handlers": [
        { "action": "/", "accept": {  "image/psd" : [ ".psd" ]  } },
        { "action": "/", "accept": {  "image/jpeg": [ ".jpeg", ".jpg" ]  } },
        { "action": "/", "accept": {  "image/png" : [ ".png" ]  } },
        { "action": "/", "accept": {  "image/webp": [ ".webp" ]  } },
        { "action": "/", "accept": {  "image/bmp" : [ ".bmp" ]  } },
        { "action": "/", "accept": {  "image/gif" : [ ".gif" ]  } },
        { "action": "/", "accept": {  "image/svg+xml": [ ".svg" ]  } },
        { "action": "/", "accept": {  "image/pdf" : [ ".pdf" ]  } },
        { "action": "/", "accept": {  "image/tiff": [ ".tif", ".tiff" ]  } },
        { "action": "/", "accept": {  "image/ai"  : [ ".ai"  ]  } },
        { "action": "/", "accept": {  "image/psb": [ ".psb" ]  } },
        { "action": "/", "accept": {  "image/xcf": [ ".xcf" ]  } },
        { "action": "/", "accept": {  "image/sketch": [ ".sketch" ]  } },
        { "action": "/", "accept": {  "image/xd" : [ ".xd"  ]  } },
        { "action": "/", "accept": {  "image/pxd": [ ".pxd" ]  } },
        { "action": "/", "accept": {  "image/cdr": [ ".cdr" ]  } },
        { "action": "/", "accept": {  "image/eps": [ ".eps", ".ps" ]  } },
        { "action": "/", "accept": {  "image/x-icon": [ ".ico" ]  } },
        { "action": "/", "accept": {  "image/jpx": [ ".jpx" ]  } },
        { "action": "/", "accept": {  "image/jp2": [ ".jp2" ]  } },
        { "action": "/", "accept": {  "image/x-tga": [ ".tga" ]  } },
        { "action": "/", "accept": {  "image/vnd-ms.dds": [ ".dds" ]  } }
    ],
    "share_target": {
        "action": "/",
        "method": "POST",
        "enctype": "multipart/form-data",
        "params": {
            "files": [
            {
                "name": "image",
                "accept": ["image/jpeg", "image/png", "image/webp", "image/gif"]
            }
          ]
        }
    }
}

Le Finder macOS avec l'utilisateur effectuant un clic droit sur un fichier, puis sélectionnant "Ouvrir avec" Photopea.

La partie impérative de l'API de gestion de fichiers

La partie impérative de l'API gère ensuite le traitement des fichiers que le système d'exploitation transmet à la PWA. Le code de Photopea est évidemment fortement réduit et obscurci, mais l'essentiel de l'extrait ci-dessous n'est pas si difficile à comprendre. L'interface LaunchQueue (minifiée en N) dispose d'une méthode setConsumer(), qui accepte une fonction comme argument. Cette fonction utilise à son tour un objet LaunchParams (minimisé en W) . Cet objet LaunchParams possède une propriété files qui pointe vers un tableau en lecture seule d'objets FileSystemHandle. Le reste du code effectue ensuite une boucle sur ces objets et obtient pour chacun d'eux l'objet File (minifié en G) en appelant getFile(). Ce fichier est ensuite transmis à une autre logique dans Photopea, qui se charge de l'afficher.

var N = window.launchQueue;
if (N) {
  var $ = this.UA;
  N.setConsumer(function (W) {
    var O = W.files;
    console.log(O);
    for (var Y = 0; Y < O.length; Y++) {
      var T = O[Y];
      T.getFile().then(function (G) {
        $.YO([G], null, null, null, [T]);
      });
    }
  });
}

Conclusions

Les utilisateurs demandent depuis longtemps que Photopea devienne un gestionnaire de fichiers pour les images. En 2020, lorsque la question est apparue, cette fonctionnalité était complètement impensable, mais un utilisateur enthousiaste a découvert l'API de gestion de fichiers à ses débuts, début 2022, alors qu'elle était encore derrière un flag. La gestion des fichiers a finalement été intégrée à Chrome 102 et est devenue une fonctionnalité très appréciée de Photopea, utilisée quotidiennement par ses utilisateurs, certains la qualifiant même de révolutionnaire. N'hésitez pas à essayer Photopea, à l'installer sur votre ordinateur, puis à ouvrir l'un des formats de fichiers compatibles. Bonne retouche d'images !