Les photos des appareils photo numériques sont souvent enregistrées au format JPEG avec une balise «d'orientation» EXIF. Pour s'afficher correctement, les images doivent être pivotées / reflétées en fonction de l'orientation définie, mais les navigateurs ignorent ces informations pour rendre l'image. Même dans les grandes applications Web commerciales, la prise en charge de l'orientation EXIF peut être irrégulière 1 . La même source fournit également un joli résumé des 8 orientations différentes qu'un JPEG peut avoir:
Des exemples d'images sont disponibles à l'adresse 4 .
La question est de savoir comment faire pivoter / refléter l'image du côté client afin qu'elle s'affiche correctement et puisse être traitée ultérieurement 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 webworkers 3 .
Les outils de la console peuvent réorienter correctement les images 5 . Un script PHP résolvant le problème est disponible à 6
la source
canvas.toDataURL()
, les décoder et les enregistrer côté serveur.<img>
balise ordinaire ?La transformation de contexte de Mederr fonctionne parfaitement. Si vous avez besoin d'extraire l'orientation, utilisez uniquement cette fonction - vous n'avez pas besoin de bibliothèques de lecture EXIF. Vous trouverez ci-dessous une fonction pour réinitialiser l'orientation dans l'image base64. Voici un violon pour cela . J'ai également préparé une démo d'extraction de violon avec orientation .
la source
switch
n'est pas nécessaire, car cette transformation ne fait rien. Pensez également à utilisersrcOrientation > 4 && srcOrientation < 9
au lieu de[5,6,7,8].indexOf(srcOrientation) > -1
, car il est plus rapide et moins gourmand en ressources (à la fois RAM et CPU). Il n'est pas nécessaire d'avoir un tableau là-bas. Ceci est important lors du groupage de lots d'images, où chaque bit compte. Sinon, très bonne réponse. Vote positif!indexOf
être lourd par rapport à ce que vous proposiez. J'ai couru une boucle simple avec 10 millions d'itérations et c'était 1400% plus rapide. Nice: D Merci beaucoup!getOrientation
, je suis curieux de savoir si cela est efficace en termes de performances.getOrientation
appelsfileReader.readAsArrayBuffer
, puis nous appelonsURL.createObjectURL
et transmettons le résultat àresetOrientation
, qui charge cette URL en tant qu'image. Cela signifie-t-il que le fichier image sera "chargé" / lu par le navigateur non pas une mais deux fois, ou ai-je mal compris?image-orientation: from-image
lorsqu'il est utilisé.Si
Ensuite, vous pouvez utiliser ces transformations pour transformer l'image en orientation 1
De l'orientation:
ctx.transform(1, 0, 0, 1, 0, 0);
ctx.transform(-1, 0, 0, 1, width, 0);
ctx.transform(-1, 0, 0, -1, width, height);
ctx.transform(1, 0, 0, -1, 0, height);
ctx.transform(0, 1, 1, 0, 0, 0);
ctx.transform(0, 1, -1, 0, height, 0);
ctx.transform(0, -1, -1, 0, height, width);
ctx.transform(0, -1, 1, 0, 0, width);
Avant de dessiner l'image sur ctx
la source
ok en plus de la réponse @ user3096626, je pense que ce sera plus utile si quelqu'un a fourni un exemple de code, l'exemple suivant vous montrera comment corriger l'orientation de l'image provient de l'url (images distantes):
Solution 1: utiliser javascript (recommandé)
car la bibliothèque load-image n'extrait pas les balises exif des images url uniquement (fichier / blob), nous utiliserons à la fois les bibliothèques javascript exif-js et load-image , alors ajoutez d'abord ces bibliothèques à votre page comme suit:
Notez que la version 2.2 d'exif-js semble avoir des problèmes, nous avons donc utilisé 2.1
alors fondamentalement ce que nous ferons est
a - charger l'image en utilisant
window.loadImage()
b - lire les balises exif en utilisant
window.EXIF.getData()
c - convertir l'image en canevas et fixer l'orientation de l'image en utilisant
window.loadImage.scale()
d - placez le canevas dans le document
Voici :)
bien sûr, vous pouvez également obtenir l'image en base64 à partir de l'objet canvas et la placer dans l'attribut img src, donc en utilisant jQuery, vous pouvez le faire;)
voici le code complet sur: github: https://github.com/digital-flowers/loadimage-exif-example
Solution 2: utiliser 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 aucun html (LOL je ne sais pas pourquoi), donc en gros, vous pouvez afficher votre image en utilisant iframe en mettant directement l'attribut iframe src comme URL de l'image:
Solution 3: utiliser le CSS (uniquement Firefox et Safari sur iOS)
il y a un attribut css3 pour corriger l'orientation de l'image, mais le problème, il ne fonctionne que sur Firefox et Safari / ios, cela vaut toujours la peine d'être mentionné car bientôt il sera disponible pour tous les navigateurs (Informations sur le support du navigateur de caniuse )
la source
Pour ceux qui ont un fichier d'un contrôle d'entrée, ne savent pas quelle est son orientation, sont un peu paresseux et ne veulent pas inclure une grande bibliothèque ci-dessous est le code fourni par @WunderBart fusionné avec la réponse à laquelle il renvoie ( https://stackoverflow.com/a/32490603 ) qui trouve l'orientation.
qui peut facilement être appelé comme tel
la source
image/jpeg
au lieu de la valeur par défautimage/png
et le redimensionnement de l'image de sortie à une largeur maximale (400 px dans mon cas) a fait une énorme différence. (cela fonctionne bien pour les vignettes, mais si vous devez afficher l'image complète, je vous suggère d'éviter base64 et d'injecter simplement l'élément canvas directement dans la page ...)La réponse de WunderBart était la meilleure pour moi. Notez que vous pouvez l'accélérer beaucoup si vos images sont souvent dans le bon sens, simplement en testant l'orientation d'abord et en contournant le reste du code si aucune rotation n'est requise.
Rassembler toutes les informations de wunderbart, quelque chose comme ça;
la source
-2
et le-1
retour degetOrientation
afin de ne pas essayer de faire pivoter des images ou des images non jpgs sans données de rotation.file.slice()
optimisation également, mais le vrai coup de pouce vient de l'utilisation d'images plus petites et d'unimage/jpeg
format de sortie pour créer des URL de données plus petites. (il n'y a pas de retard notable, même pour les images de 10 mégapixels.)file.slice()
, car vous éviterez la prise en charge des sources d'images base64.Un seul paquebot?
Je n'ai vu personne mentionner la
browser-image-compression
bibliothèque . Il a une fonction d'assistance parfaite pour cela.Usage:
const orientation = await imageCompression.getExifOrientation(file)
Un outil aussi utile à bien d'autres égards.
la source
File
objets pour autant que je sache. La meilleure chose à faire serait ensuite d'envoyer l'image et l'orientation au serveur, et d'y faire des manipulations de fichiers. Ou vous pouvez générer une chaîne base64 en utilisantcanvas
et latoDataURL
méthode.J'ai créé une classe enveloppée dans un module ES6 qui résout exactement cela.
Il s'agit de 103 lignes, sans dépendances, et assez bien structurées et documentées, censées être faciles à modifier / réutiliser.
Gère les 8 orientations possibles et est basé sur la promesse.
Voilà, j'espère que cela aide encore quelqu'un: https://gist.github.com/vdavid/3f9b66b60f52204317a4cc0e77097913
la source
J'utilise une solution mixte (php + css).
Des conteneurs sont nécessaires pour:
div.imgCont2
conteneur nécessaire pour tourner;div.imgCont1
conteneur nécessaire pour zoomer -width:150%
;div.imgCont
conteneur nécessaire pour les barres de défilement, lorsque l'image est zoomOut..
la source
En plus de la réponse de @fareed namrouti,
Cela doit être utilisé si l'image doit être parcourue à partir d'un élément d'entrée de fichier
la source
J'ai écrit un petit script php qui fait pivoter l'image. Assurez-vous de stocker l'image en faveur de la recalculer simplement à chaque demande.
À votre santé
la source