Methodology
Méthodologie formats d'image
Canvas API + encodeurs natifs du navigateur. L'image ne quitte jamais votre appareil.
By Buğra SözeriPublished
Le cluster Imageconvertit entre PNG, JPG et WebP en utilisant l’API Canvas native du navigateur. Il n’y a pas d’étape d’upload, pas de traitement côté serveur, et aucun service d’imagerie tiers dans le chemin — ce qui a des implications à la fois pour la confidentialité et la qualité.
Le pipeline de conversion
- L’utilisateur choisit un fichier par glisser-déposer ou sélecteur de fichier.
- Le fichier est lu comme ImageBitmap via
createImageBitmap(file). - Un canvas hors écran est créé aux dimensions natives du bitmap.
- Le bitmap est dessiné sur le canvas.
- Le canvas est exporté via
canvas.toBlob(callback, mimeType, quality)— la qualité s’applique uniquement aux cibles avec perte. - Le Blob résultant est proposé en téléchargement.
Chaque étape s’exécute dans le navigateur. Le fichier n’est envoyé nulle part — il n’y a pas de fetch, pas de FormData, pas d’upload XHR. La même chose s’applique à l’outil Image vers Base64, qui utilise l’API FileReader au lieu du canvas mais suit le même principe réservé au navigateur.
Gestion de la qualité
Sans perte → avec perte (PNG/WebP → JPG)
En passant d’un format sans perte à JPG, nous exposons un curseur de qualité (par défaut 0,85) qui contrôle l’agressivité de quantification de l’encodeur JPG. À 0,85, le fichier est généralement 80-95 % plus petit que le PNG source sans différence visuelle perceptible pour les photographies. En dessous de 0,7, des artefacts deviennent visibles ; nous limitons la borne inférieure à 0,5 pour éviter de produire accidentellement une sortie visiblement dégradée.
Avec perte → sans perte (JPG → PNG)
Passer d’un JPG à un PNG ne restaure pas la qualité que le JPG a déjà supprimée. La sortie est bit-parfaite de ce que le JPG a décodé, mais les pertes d’arrondi du JPG sont intégrées. C’est rarement utile en pratique ; le meilleur chemin est de trouver une source de meilleure qualité.
Avec perte → avec perte (JPG → WebP, etc.)
Chaque sauvegarde avec perte introduit de nouvelles erreurs de quantification en plus de celles existantes de la source. Pour les fichiers qui ont déjà subi plusieurs sauvegardes, cela peut provoquer une dégradation composite visible. Toujours réencoder depuis la source de la plus haute qualité disponible.
Ce que nous ne gérons pas
- HEIC / HEIF. Le format par défaut d’Apple depuis iOS 11. La prise en charge du navigateur est essentiellement nulle en dehors de l’écosystème Apple, donc nous aurions besoin de regrouper un décodeur de 1+ Mo. Pas intéressant.
- Formats RAW (DNG, CR2, NEF, ARW). Même problème — décodeurs lourds pour un public faible. Utilisez Lightroom / darktable / RawTherapee.
- SVG ↔ raster. Possible via canvas, mais vecteur → raster perd l’évolutivité et l’inverse perd la fidélité. Conversation différente.
- Conversion par lot. Notre interface gère un fichier à la fois. Pour les traitements par lot, utilisez l’endpoint REST ou un outil de bureau.
Le pipeline d’encodeur, en code
La conversion est suffisamment courte pour être écrite. Avec un Fileprovenant d’une saisie de fichier, le pipeline complet tient en environ six lignes :
const bitmap = await createImageBitmap(file);
const canvas = new OffscreenCanvas(bitmap.width, bitmap.height);
const ctx = canvas.getContext("2d");
ctx.drawImage(bitmap, 0, 0);
const blob = await canvas.convertToBlob({ type: "image/webp", quality: 0.85 });
// blob est la sortie convertie, prête à téléchargerChaque étape est native du navigateur : createImageBitmap décode le format source (défini dans le HTML Living Standard), OffscreenCanvas fournit une surface de dessin sans rendu, et convertToBlobinvoque l’encodeur WebP / JPEG / PNG intégré du navigateur avec le paramètre de qualité défini par la spécification (0-1 pour les formats avec perte, ignoré pour PNG). Le même encodeur est celui que Chrome utilise pour sauvegarder les canvas via toDataURL; nous routons simplement le résultat vers un téléchargement au lieu d’une chaîne. Il n’y a pas de WASM, pas de bibliothèque tierce et pas d’appel réseau — le pipeline entier tourne en environ 40-200 ms pour une entrée 4K sur un ordinateur portable de classe 2023.
Sources & références
Le comportement d’encodage est défini dans le HTML Living Standard pour la sérialisation du canvas. JPEG baseline DCT provient d’ITU-T T.81 ; PNG de l’IETF RFC 2083 ; WebP de RFC 9649. La sémantique de qualité — le paramètre quality entre 0 et 1 pour les encodeurs avec perte — est normative dans la spécification HTML.
Hypothèses & limites
- Un fichier à la fois.L’interface prend un seul fichier par session. Le réencodage en lot nécessite un script contre l’API REST ou un outil de bureau.
- Encodeurs natifs du navigateur.La qualité de sortie dépend du navigateur de l’utilisateur. L’encodeur WebP de Chromium est libwebp ; Firefox utilise le sien. Des différences d’artefacts subtiles entre moteurs existent à quality < 0,7.
- Pas de décodage HEIC/HEIF/RAW. Les saisies dans ces formats ne peuvent pas être ouvertes via
createImageBitmapdans la plupart des navigateurs sans un shim WASM que nous ne livrons pas. - Pas d’encodage AVIF.La lecture est prise en charge dans les navigateurs modernes ; l’écriture nécessite WASM (libaom), ce qui pousserait le bundle au-delà d’une taille acceptable.
- Sans perte ↔ avec perte est à sens unique.Le réencodage d’un JPG en PNG ne restaure pas les informations ; le PNG réencodé est bit-parfait du JPG décodé, avec ses pertes de quantification intégrées.
- Profil ICC préservé uniquement pour les réécritures dans le même format.La conversion inter-format (PNG → JPG) peut supprimer le profil ICC intégré selon l’implémentation du navigateur.
- Limité par la mémoire. Les très grandes saisies (40+ mégapixels) peuvent provoquer un manque de mémoire sur Safari mobile.
Plancher de compatibilité navigateur
L’encodage WebP via canvas.toBlobnécessite Chromium 23+, Firefox 65+, Safari 14+, Edge 79+. En 2026, cela représente >97 % du trafic mondial. L’encodage AVIF n’est pas pris en charge dans l’API canvas du navigateur ; il nous faudrait un encodeur WASM pour livrer cette cible, ce qui est au programme.
Frequently asked questions
- Comment Convertitive convertit-il entre les formats d'image ?
- Le pipeline : (1) charger le fichier source dans un élément Image du navigateur ; (2) le dessiner sur un Canvas HTML aux dimensions cibles ; (3) appeler canvas.toBlob(callback, mimeType, quality) avec le format et le paramètre de qualité souhaités. Le codec intégré du navigateur gère l'encodage réel. La prise en charge des formats dépend donc de l'appareil : le décodage WebP nécessite Chrome/Firefox/Edge (Safari 14+) ; AVIF nécessite Chrome 85+/Firefox 93+.
- Quel algorithme de compression l'encodeur JPEG utilise-t-il ?
- JPEG utilise la compression avec perte par Transformée en Cosinus Discrète (DCT) telle que spécifiée dans ISO/IEC 10918-1:1994 (baseline JPEG). Le paramètre de qualité de l'encodeur du navigateur correspond à la mise à l'échelle de la table de quantification DCT — quality=1.0 utilise une quantification minimale (quasi sans perte), quality=0 utilise une quantification maximale (très compressé). Les tables de quantification exactes sont spécifiques à l'implémentation selon la spécification HTML canvas.toBlob() (WHATWG HTML §15.4.13).
- La conversion d'image est-elle sans perte pour PNG vers PNG ?
- PNG utilise la compression sans perte DEFLATE (RFC 2083, §2.1). Le réencodage d'un PNG via l'API Canvas réexécute DEFLATE, ce qui peut produire un fichier plus grand ou plus petit que l'original selon l'implémentation DEFLATE du navigateur et les paramètres de niveau de compression. Les valeurs de pixels sont identiques ; seule la taille du fichier compressé change. Les données du canal alpha sont préservées exactement.
- L'image quitte-t-elle mon appareil ?
- Non. Tout le traitement d'image utilise l'API Canvas et l'API FileReader du navigateur — JavaScript purement côté client sans requête serveur. L'onglet Réseau dans les outils de développement du navigateur ne montre aucune requête sortante lors de la conversion d'images. Cela est vérifiable indépendamment ; le code source est public sur github.com/convertitive.
- Quelles sont les limites de précision et de qualité du convertisseur d'images ?
- Trois limites : (1) profil de couleur : Canvas dessine les images dans l'espace de couleur interne du navigateur (sRGB sur la plupart des appareils), donc les profils ICC intégrés dans les images source peuvent être supprimés ; (2) EXIF/métadonnées : canvas.toBlob() supprime toutes les métadonnées EXIF, IPTC et XMP — orientation, GPS, modèle d'appareil photo sont perdus ; (3) la qualité est subjective — le paramètre de qualité est mappé différemment selon les implémentations des encodeurs JPEG et WebP des navigateurs, donc un JPEG quality=0.8 de Chrome peut différer en taille et en apparence d'un généré par Firefox au même paramètre.
Related
Published May 14, 2026