JS Orientation Exif du côté client: faire pivoter et miroir des images JPEG

Les photos de caméras numériques sont souvent enregistrées sous forme de JPEG avec une étiquette "orientation" EXIF. Pour afficher correctement, les images doivent être tournées / miroir en fonction de l'orientation définie, mais les navigateurs ignorent cette information qui rend l'image. Même dans les grandes applications Web commerciales, le support de l'orientation EXIF ​​peut être un problème 1 . La même source fournit également un bon résumé des 8 orientations différentes qu'un JPEG peut avoir:

Résumé des orientations EXIF

Des exemples d'images sont disponibles à 4 .

La question est de savoir comment faire pivoter / réfléchir l'image du côté client afin qu'elle s'affiche correctement et qu'elle puisse être traitée si nécessaire?

Il existe des bibliothèques JS disponibles pour analyser les données EXIF, y compris l'attribut d'orientation 2 . Flickr a noté un problème de performance possible lors de l'analyse de grandes images, nécessitant l'utilisation de travailleur web 3 .

Les outils de la console peuvent réorienter correctement les images 5 . Un script PHP résolvant le problème est disponible à 6

    Le projet github JavaScript-Load-Image fournit une solution complète au problème d'orientation EXIF, des images correctement tournantes / en miroir pour toutes les 8 orientations exif. Voir la démo en ligne de javascript exif orientation

    L'image est dessinée sur une toile HTML5. Son rendu correct est implémenté dans js / load-image-orientation.js à travers des opérations de toile.

    J'espère que cela sauve quelqu'un d'autre pendant un certain temps, et enseigne aux moteurs de recherche sur ce bijou open source 🙂

    Si

     width = img.width; height = img.height; var ctx = canvas.getContext('2d'); 

    Ensuite, vous pouvez utiliser ces transformations pour transformer l'image en orientation 1

    De l'orientation:

    1. ctx.transform(1, 0, 0, 1, 0, 0);
    2. ctx.transform(-1, 0, 0, 1, width, 0);
    3. ctx.transform(-1, 0, 0, -1, width, height );
    4. ctx.transform(1, 0, 0, -1, 0, height );
    5. ctx.transform(0, 1, 1, 0, 0, 0);
    6. ctx.transform(0, 1, -1, 0, height , 0);
    7. ctx.transform(0, -1, -1, 0, height , width);
    8. ctx.transform(0, -1, 1, 0, 0, width);

    Avant de dessiner l'image sur ctx

    La transformation du contexte de Mederr fonctionne parfaitement. Si vous devez extraire l'orientation, utilisez cette fonction uniquement – vous n'avez pas besoin de bibliothèques de lecture EXIF. Voici une fonction pour rétablir l'orientation dans l'image base64. Voici un violon pour ça . J'ai également préparé un violon avec une démo d'extraction d'orientation .

     function resetOrientation(srcBase64, srcOrientation, callback) { var img = new Image(); img.onload = function() { var width = img.width, height = img.height, canvas = document.createElement('canvas'), ctx = canvas.getContext("2d"); // set proper canvas dimensions before transform & export if (4 < srcOrientation && srcOrientation < 9) { canvas.width = height; canvas.height = width; } else { canvas.width = width; canvas.height = height; } // transform context before drawing image switch (srcOrientation) { case 2: ctx.transform(-1, 0, 0, 1, width, 0); break; case 3: ctx.transform(-1, 0, 0, -1, width, height ); break; case 4: ctx.transform(1, 0, 0, -1, 0, height ); break; case 5: ctx.transform(0, 1, 1, 0, 0, 0); break; case 6: ctx.transform(0, 1, -1, 0, height , 0); break; case 7: ctx.transform(0, -1, -1, 0, height , width); break; case 8: ctx.transform(0, -1, 1, 0, 0, width); break; default: break; } // draw image ctx.drawImage(img, 0, 0); // export base64 callback(canvas.toDataURL()); }; img.src = srcBase64; }; 

    Ok en plus de @ user3096626 réponse, je pense qu'il sera plus utile si quelqu'un a fourni un exemple de code, l'exemple suivant vous montrera comment réparer l'orientation de l'image provient de l'URL (images distantes):


    Solution 1: utilisant javascript (recommandé)

    1. Car la bibliothèque d' image de chargement n'absence pas les étiquettes exif des images url uniquement (fichier / blob), nous utiliserons les bibliothèques exif-j et charge- javascript image , d'abord, ajoutez ces bibliothèques à votre page comme suit:

       <script src="https://cdnjs.cloudflare.com/ajax/libs/exif-js/2.1.0/exif.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-load-image/2.12.2/load-image.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-load-image/2.12.2/load-image-scale.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/blueimp-load-image/2.12.2/load-image-orientation.min.js"></script> 

      Notez que la version 2.2 de exif-js semble avoir des problèmes, donc nous avons utilisé 2.1

    2. Alors, fondamentalement, ce que nous allons faire, c'est

      A – chargez l'image à l'aide de window.loadImage()

      B – lire des tags window.EXIF.getData() aide de window.EXIF.getData()

      C – convertissez l'image en toile et corrigez l'orientation de l'image à l'aide de window.loadImage.scale()

      D – placez le canevas dans le document

    Voici 🙂

     window.loadImage("/your-image.jpg", function (img) { if (img.type === "error") { console.log("couldn't load image:", img); } else { window.EXIF.getData(img, function () { var orientation = EXIF.getTag(this, "Orientation"); var canvas = window.loadImage.scale(img, {orientation: orientation || 0, canvas: true}); document.getElementById("container").appendChild(canvas); // or using jquery $("#container").append(canvas); }); } }); 

    Bien sûr, vous pouvez également obtenir l'image en tant que base64 à partir de l'objet canvas et la placer dans l'attribut src img; donc, utilisez jQuery, vous pouvez le faire;)

     $("#my-image").attr("src",canvas.toDataURL()); 

    Voici le code complet sur: github: https://github.com/digital-flowers/loadimage-exif-example


    Solution 2: utilisant html (piratage de navigateur)

    Il y a un hack très rapide et facile, la plupart des navigateurs affichent l'image dans la bonne orientation si l'image est ouverte dans un nouvel onglet directement sans html (LOL, je ne sais pas pourquoi), donc, fondamentalement, vous pouvez afficher votre image en utilisant iframe En mettant l'attribut src iframe comme l'URL de l'image directement:

     <iframe src="/my-image.jpg"></iframe> 

    Solution 3: utilisation de css (uniquement firefox et safari sur ios)

    Il y a un attribut css3 pour corriger l'orientation de l'image, mais le problème ne fonctionne que sur Firefox et safari / ios il vaut la peine d'être mentionné car bientôt il sera disponible pour tous les navigateurs (les informations de support du navigateur à partir de caniuse )

     img { image-orientation: from-image; } 

    En plus de la réponse de @passed namrouti,

    Cela devrait être utilisé si l'image doit être parcourue à partir d'un élément de saisie de fichier

     <input type="file" name="file" id="file-input"><br/> image after transform: <br/> <div id="container"></div> <script> document.getElementById('file-input').onchange = function (e) { var image = e.target.files[0]; window.loadImage(image, function (img) { if (img.type === "error") { console.log("couldn't load image:", img); } else { window.EXIF.getData(image, function () { console.log("load image done!"); var orientation = window.EXIF.getTag(this, "Orientation"); var canvas = window.loadImage.scale(img, {orientation: orientation || 0, canvas: true, maxWidth: 200}); document.getElementById("container").appendChild(canvas); // or using jquery $("#container").append(canvas); }); } }); }; </script>