[GUIDE] Comment prévisualiser des images encodées en Base64 dans le navigateur
Cinq façons éprouvées d'afficher des images encodées en Base64 sur la page — affectation directe à src, FileReader, canvas, conversion blob et patrons spécifiques aux frameworks. Inclut des conseils de débogage.
// LA RÉPONSE EN 30 SECONDES
Si vous disposez d'une chaîne d'image encodée en Base64 et que vous voulez simplement la voir sur la page, le chemin le plus court est de l'affecter en tant qu'URI data: à img.src. Trois lignes de JavaScript :
const img = new Image();
img.src = 'data:image/png;base64,' + base64String;
document.body.appendChild(img);
// If the string already starts with 'data:image/...;base64,'
// — just assign it directly without prepending anything:
img.src = base64StringWithDataUriPrefix;
// MÉTHODE 1 : img.src — L'APPROCHE DIRECTE
Chaque élément <img> traite une URI de données comme une URL classique. Affectez l'URI à src et le navigateur gère le décodage, la détection du format et le rendu pour vous.
Cela fonctionne pour tout format d'image pris en charge nativement par le navigateur : PNG, JPEG, GIF (animé et statique), WebP, SVG, BMP, ICO. La chaîne Base64 peut provenir de n'importe où — une réponse d'API, le localStorage, un collage depuis le presse-papiers, une ligne de base de données.
Le type MIME dans l'URI de données importe pour les anciens navigateurs et certains WebViews intégrés. Si vous n'avez qu'une charge utile Base64 brute (pas de préfixe data:) et que vous ne connaissez pas le format, vous pouvez soit sonder les octets magiques (voir Méthode 5) soit utiliser par défaut image/png — la plupart des navigateurs renifleront et récupéreront même si le type MIME est incorrect.
// Plain HTML — no JavaScript needed if the string is static
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUg..." alt="preview">
// Dynamic JavaScript — load from a variable, fetch, or input field
function renderBase64Image(base64, mimeType = 'image/png', containerId = 'preview') {
const container = document.getElementById(containerId);
const img = new Image();
img.onload = () => {
container.innerHTML = '';
container.appendChild(img);
};
img.onerror = () => {
container.textContent = 'Invalid image data';
};
// Tolerate both raw Base64 and full data: URIs
img.src = base64.startsWith('data:')
? base64
: `data:${mimeType};base64,${base64}`;
}
renderBase64Image(myBase64String, 'image/jpeg');
// MÉTHODE 2 : FILEREADER POUR LES FICHIERS TÉLÉVERSÉS PAR L'UTILISATEUR
Si l'utilisateur téléverse une image via <input type="file">, vous n'avez pas besoin de l'encoder manuellement en Base64. FileReader.readAsDataURL() vous donne une URI de données complète que vous pouvez injecter directement dans img.src :
<input type="file" id="fileInput" accept="image/*">
<img id="preview" alt="">
<script>
document.getElementById('fileInput').addEventListener('change', (e) => {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = (event) => {
// event.target.result is a complete data URI
// e.g. 'data:image/png;base64,iVBORw0KGgo...'
document.getElementById('preview').src = event.target.result;
};
reader.onerror = () => {
console.error('FileReader failed:', reader.error);
};
reader.readAsDataURL(file);
});
</script>
// MÉTHODE 3 : CANVAS POUR LES IMAGES GÉNÉRÉES OU MODIFIÉES
Lorsque vous dessinez ou traitez une image sur un <canvas>, canvas.toDataURL() exporte le résultat sous forme d'URI de données en un seul appel. Utile pour : captures d'écran de graphiques, pavés de signature, codes QR, filigranes ou tout ce qui est généré côté client que vous souhaitez afficher ou télécharger comme image.
// 1. Draw on canvas
const canvas = document.createElement('canvas');
canvas.width = 200;
canvas.height = 200;
const ctx = canvas.getContext('2d');
ctx.fillStyle = '#00FF41';
ctx.fillRect(0, 0, 200, 200);
ctx.fillStyle = '#000';
ctx.font = '20px monospace';
ctx.fillText('Hello, Base64!', 20, 100);
// 2. Export to data URI
const pngDataURL = canvas.toDataURL('image/png');
// pngDataURL === 'data:image/png;base64,iVBORw0KGgo...'
// 3. Display directly
const img = new Image();
img.src = pngDataURL;
document.body.appendChild(img);
// JPEG with quality control (0–1)
const jpegDataURL = canvas.toDataURL('image/jpeg', 0.85);
// WebP if supported
const webpDataURL = canvas.toDataURL('image/webp', 0.9);
// MÉTHODE 4 : FETCH + BLOB POUR LES CHARGES UTILES BASE64 DISTANTES
Si la charge utile Base64 est volumineuse (plus de 50 Ko) ou que vous l'afficherez plusieurs fois, la convertir en URL Blob via URL.createObjectURL() est plus efficace en mémoire que de conserver l'URI de données complète dans le DOM. L'URL blob est courte (blob:https://example.com/12345-abcde), peut être révoquée lorsqu'elle n'est plus nécessaire et évite le surcoût Base64 de 33 % dans les chaînes du DOM.
// Convert a Base64 string to a Blob, then to a blob: URL
function base64ToBlobURL(base64, mimeType = 'image/png') {
// Strip the data: prefix if present
const payload = base64.includes(',') ? base64.split(',')[1] : base64;
// Decode Base64 to binary string
const binary = atob(payload);
// Convert binary string to Uint8Array
const bytes = new Uint8Array(binary.length);
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i);
}
// Wrap in a Blob and create an object URL
const blob = new Blob([bytes], { type: mimeType });
return URL.createObjectURL(blob);
}
// Usage
const blobURL = base64ToBlobURL(myBase64, 'image/jpeg');
const img = new Image();
img.src = blobURL;
document.body.appendChild(img);
// IMPORTANT: free the memory when you're done with the image
img.onload = () => URL.revokeObjectURL(blobURL);
// MÉTHODE 5 : DÉTECTION AUTOMATIQUE DU FORMAT À PARTIR DES OCTETS MAGIQUES
Si vous recevez une charge utile Base64 brute (pas de préfixe data:) et que vous ne savez pas s'il s'agit de PNG, JPEG, GIF ou WebP, jetez un œil aux premiers octets décodés — chaque format a une signature unique.
function detectImageFormat(base64) {
// Look at the first ~12 characters of the Base64 string
const head = base64.replace(/^data:[^,]+,/, '').slice(0, 16);
if (head.startsWith('iVBORw0KGgo')) return 'image/png';
if (head.startsWith('/9j/')) return 'image/jpeg';
if (head.startsWith('R0lGOD')) return 'image/gif';
if (head.startsWith('UklGR')) return 'image/webp';
if (head.startsWith('PHN2Zy') ||
head.startsWith('PD94bWw')) return 'image/svg+xml';
if (head.startsWith('Qk')) return 'image/bmp';
if (head.startsWith('AAABAA')) return 'image/x-icon';
return 'application/octet-stream'; // unknown
}
// Build a correct data URI even when the user only gave us the payload
function toDataURI(base64) {
if (base64.startsWith('data:')) return base64; // already complete
const mime = detectImageFormat(base64);
return `data:${mime};base64,${base64}`;
}
// REACT — AFFICHER DES IMAGES BASE64 DANS DES COMPOSANTS
Dans React, traitez l'URI de données comme n'importe quelle autre propriété de chaîne. Mémorisez la conversion si l'entrée change rarement :
import { useMemo } from 'react';
function Base64Image({ base64, mimeType = 'image/png', alt }) {
const src = useMemo(() => {
if (!base64) return '';
return base64.startsWith('data:')
? base64
: `data:${mimeType};base64,${base64}`;
}, [base64, mimeType]);
if (!src) return <div>No image</div>;
return <img src={src} alt={alt} loading="lazy" />;
}
// Usage
<Base64Image
base64={apiResponse.avatar}
mimeType="image/jpeg"
alt="User avatar"
/>
// For large images, prefer blob URLs (Method 4) and useEffect for cleanup:
function LargeBase64Image({ base64 }) {
const [blobURL, setBlobURL] = useState('');
useEffect(() => {
const url = base64ToBlobURL(base64, 'image/png');
setBlobURL(url);
return () => URL.revokeObjectURL(url); // cleanup on unmount
}, [base64]);
return blobURL ? <img src={blobURL} alt="" /> : null;
}
// VUE 3 — EXEMPLE EN COMPOSITION API
Même idée, syntaxe Vue :
<script setup>
import { computed } from 'vue';
const props = defineProps({
base64: String,
mimeType: { type: String, default: 'image/png' },
alt: { type: String, default: '' }
});
const src = computed(() => {
if (!props.base64) return '';
return props.base64.startsWith('data:')
? props.base64
: `data:${props.mimeType};base64,${props.base64}`;
});
</script>
<template>
<img v-if="src" :src="src" :alt="alt" loading="lazy" />
<div v-else>No image</div>
</template>
// SVELTE — INSTRUCTION RÉACTIVE
<script>
export let base64 = '';
export let mimeType = 'image/png';
export let alt = '';
$: src = base64
? (base64.startsWith('data:') ? base64 : `data:${mimeType};base64,${base64}`)
: '';
</script>
{#if src}
<img {src} {alt} loading="lazy" />
{:else}
<div>No image</div>
{/if}
// GESTION DES ERREURS — CE QUI CASSE ET POURQUOI
L'image se charge sous forme d'icône brisée. La charge utile Base64 est tronquée, contient des espaces blancs au milieu de la chaîne ou utilise des caractères sécurisés pour URL (-_) à l'intérieur d'une URI de données standard. Supprimez les espaces blancs avec str.replace(/\s+/g, '') ; reconvertissez les caractères sécurisés pour URL en standard avec str.replace(/-/g, '+').replace(/_/g, '/') ; et vérifiez que la longueur est correcte (la longueur Base64 doit être un multiple de 4 avec un remplissage = approprié).
L'image s'affiche mais dans le mauvais format. Le préfixe data:image/png;base64, indique PNG, mais les octets réels sont JPEG. Le navigateur renifle les octets magiques et l'affiche correctement quand même — mais certains navigateurs sans tête et WebViews intégrés ne le font pas. Utilisez la Méthode 5 pour détecter le format réel à partir des octets.
L'image est énorme dans le DOM et la page semble lente. Une chaîne Base64 de 1 Mo dans un composant React est rendue à nouveau à chaque mise à jour d'état. Passez à une URL blob: (Méthode 4) — c'est une chaîne de 50 caractères dans le DOM, quelle que soit la taille de l'image.
L'image fonctionne dans Chrome mais pas dans Safari. Safari a des paramètres CSP par défaut plus stricts et rejette les URI data: dans certains contextes (<a download>, requêtes des service workers). Testez dans Safari et repliez-vous sur une URL blob: si nécessaire.
La chaîne Base64 elle-même est invalide. Parfois, le « Base64 » que vous recevez est doublement encodé, encodé en hexadécimal ou tout simplement corrompu. Collez-le d'abord dans notre décodeur Base64 vers image pour confirmer qu'il est valide avant de déboguer votre code.
// PERFORMANCE : URI data: VS URL blob: — UN BENCHMARK RAPIDE
Pour un JPEG de 500 Ko affiché dans <img> :
• URI data: dans src : chaîne de 668 Ko dans le DOM (33 % de surcoût Base64). Le navigateur analyse l'URI, décode le Base64, décode le JPEG. ~80 ms pour le premier rendu sur un ordinateur portable de milieu de gamme.
• URL blob: via URL.createObjectURL : chaîne de 56 caractères dans le DOM. Le navigateur récupère le blob en mémoire, décode le JPEG. ~40 ms pour le premier rendu. ~50 % d'économies de mémoire.
Pour une icône de 5 Ko, la différence est invisible — les deux s'affichent en moins de 5 ms. À retenir : sous environ 50 Ko, utilisez ce qui est pratique. Au-dessus, préférez les URL blob.
// TESTER VOTRE APERÇU DE FAÇON ISOLÉE
Si vous suspectez un bug, isolez d'abord la chaîne Base64 du code de votre application. Trois vérifications rapides :
1. Collez-la dans notre outil en ligne. Déposez la chaîne dans le convertisseur Base64 vers image. Si l'image s'affiche correctement là, les données sont bonnes et le bug est dans votre code. Si elle ne s'affiche pas non plus là, les données sont corrompues en amont.
2. Ouvrez-la comme URL dans un nouvel onglet. Copiez l'URI de données (y compris le préfixe data:image/png;base64,), collez dans un nouvel onglet de navigateur, appuyez sur Entrée. Les navigateurs modernes afficheront l'image directement. (Certains bloquent data: dans la barre d'adresse — utilisez le test intégré à l'étape 1 si c'est le cas.)
3. Vérifiez la longueur. Une chaîne Base64 valide a une longueur divisible par 4 (après suppression des espaces blancs). Le remplissage (=) compense la différence : 0 à 2 caractères = en fin de chaîne. Si votre longueur n'est pas divisible par 4, la chaîne est tronquée ou étendue.
// Quick validation snippet
function looksLikeValidBase64(str) {
const cleaned = str.replace(/^data:[^,]+,/, '').replace(/\s+/g, '');
if (cleaned.length === 0) return false;
if (cleaned.length % 4 !== 0) return false;
if (!/^[A-Za-z0-9+/]+={0,2}$/.test(cleaned)) return false;
return true;
}
// AIDE-MÉMOIRE EN 30 SECONDES
Le plus rapide : affectez l'URI de données à img.src. Terminé.
Depuis un téléversement de fichier : FileReader.readAsDataURL(file).
Depuis un canvas : canvas.toDataURL('image/png').
Pour les images grandes ou répétées : convertissez en blob et utilisez URL.createObjectURL(blob).
Format inconnu : reniflez les octets magiques (iVBORw0KGgo = PNG, /9j/ = JPEG, etc.) avant de construire l'URI de données.
Débogage : collez d'abord dans le convertisseur Base64 vers image — cela élimine la question de savoir si les données sont le problème.
Lectures associées : Comprendre les URI de données · Intégration d'images Base64 · Base64 en JavaScript : navigateur et Node