JS Client-seitige Exif-Ausrichtung: JPEG-Bilder drehen und spiegeln

154

Digitalkamera-Fotos werden häufig als JPEG mit einem EXIF-Tag "Orientierung" gespeichert. Um korrekt angezeigt zu werden, müssen Bilder je nach eingestellter Ausrichtung gedreht / gespiegelt werden. Browser ignorieren diese Informationen jedoch, um das Bild zu rendern. Selbst in großen kommerziellen Web-Apps kann die Unterstützung für die EXIF-Ausrichtung nur sporadisch sein 1 . Dieselbe Quelle bietet auch eine schöne Zusammenfassung der 8 verschiedenen Ausrichtungen, die ein JPEG haben kann:

Zusammenfassung der EXIF-Orientierungen

Beispielbilder sind unter 4 verfügbar .

Die Frage ist, wie das Bild auf der Clientseite gedreht / gespiegelt werden kann, damit es korrekt angezeigt wird und bei Bedarf weiterverarbeitet werden kann.

Zum Parsen von EXIF-Daten stehen JS-Bibliotheken zur Verfügung, einschließlich des Orientierungsattributs 2 . Flickr stellte ein mögliches Leistungsproblem beim Parsen großer Bilder fest, für das Webworker erforderlich sind 3 .

Konsolenwerkzeuge können die Bilder korrekt neu ausrichten 5 . Ein PHP-Skript zur Lösung des Problems finden Sie unter 6

flexponsiv
quelle

Antworten:

145

Das Github-Projekt JavaScript-Load-Image bietet eine vollständige Lösung für das EXIF-Orientierungsproblem, indem Bilder für alle 8 Exif-Orientierungen korrekt gedreht / gespiegelt werden. Siehe die Online-Demo der Javascript-Exif-Orientierung

Das Bild wird auf eine HTML5-Leinwand gezeichnet. Das korrekte Rendern wird in js / load-image-Orientierung.js durch Canvas-Operationen implementiert .

Hoffe, das spart jemand anderem etwas Zeit und bringt den Suchmaschinen etwas über dieses Open-Source-Juwel bei :)

flexponsiv
quelle
1
Ich habe diese Bibliothek benutzt, aber vor kurzem ist sie unter iOS 8.3 kaputt gegangen. Dort muss sie am meisten funktionieren :(
Gordon Sun
2
Ich kämpfe wirklich darum zu sehen, wie hilfreich das ist. Ich spiele damit herum und versuche es zu lernen, damit ich entweder eine Seite analysieren und Bilder drehen kann, wenn sie gedreht werden müssen, oder die Ausrichtung erkennen und die Datei (irgendwie) drehen kann, bevor ich sie tatsächlich hochlade. Die Demo macht beides nicht. Es nimmt einfach eine Datei aus einer Dateieingabe und zeigt sie richtig an. Wann ist dies in der realen Welt nützlich? Wenn ich meine Seite analysiere und die URLs von den Bild-Tags in die loadImage-Bibliothek einspeise, gibt es keine Exif-Daten, daher kann ich das nicht. Für den Upload wird ein Canvas-Objekt zurückgegeben, sodass ich das nicht an den Server senden kann.
Igneosaurier
3
@igneosaur: Sie können base64-codierte Daten mit an den Server senden canvas.toDataURL()und diese serverseitig dekodieren und speichern.
Br4nnigan
1
Anstatt das Load-Image-Projekt zu verwenden, können Sie einen Teil seiner Codebasis zum Backen Ihres eigenen verwenden. Schauen Sie einfach in github.com/blueimp/JavaScript-Load-Image/blob/master/js/… nach .
Andy Lorenz
1
Gibt es eine Möglichkeit, die von dieser Bibliothek erzeugte Zeichenfläche wie ein normales <img>Tag ansprechend zu gestalten ?
Erik Berkun-Drevnig
103

Mederrs Kontexttransformation funktioniert perfekt. Wenn Sie die Orientierung extrahieren müssen, verwenden Sie nur diese Funktion - Sie benötigen keine EXIF-Lesebibliotheken. Unten finden Sie eine Funktion zum Zurücksetzen der Ausrichtung im base64-Bild. Hier ist eine Geige dafür . Ich habe auch eine Geige mit Orientierungs-Extraktions-Demo vorbereitet .

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;
};
WunderBart
quelle
7
Der Standardfall in der Ausrichtung switchwird nicht benötigt, da diese Transformation nichts bewirkt. Ziehen Sie auch die Verwendung von srcOrientation > 4 && srcOrientation < 9anstelle von in Betracht [5,6,7,8].indexOf(srcOrientation) > -1, da diese schneller und weniger ressourcenintensiv ist (sowohl RAM als auch CPU). Es ist nicht erforderlich, dort ein Array zu haben. Dies ist wichtig, wenn viele Bilder gestapelt werden, wobei jedes Bit zählt. Ansonsten ziemlich gute Antwort. Upvoted!
Ryan Casas
4
@ RyanCasas Mir war nicht bewusst, wie schwer das sein kann indexOf, was Sie vorgeschlagen haben. Ich habe eine einfache Schleife mit 10 Millionen Iterationen ausgeführt und sie war 1400% schneller. Schön: D Vielen Dank!
WunderBart
1
Ich habe diese Antwort in einem Android-WebView verwendet und es stellte sich heraus, dass es einige Android-Geräte gibt, die WebGL in einem WebView nicht unterstützen (siehe bugs.chromium.org/p/chromium/issues/detail?id=555116 ) Die Drehung kann bei solchen Geräten je nach Bildgröße sehr lange dauern.
Ndreisg
1
Bei Verwendung mit dem referenzierten getOrientationbin ich gespannt, ob dies in Bezug auf die Leistung effizient ist. getOrientationruft auf fileReader.readAsArrayBuffer, und dann rufen wir auf URL.createObjectURLund übergeben das Ergebnis resetOrientation, wodurch diese URL als Bild geladen wird. Bedeutet dies, dass die Bilddatei nicht nur einmal, sondern zweimal vom Browser "geladen" / gelesen wird, oder verstehe ich das falsch?
Oliver Joseph Ash
1
Was tun bei Browsern, bei denen die Ausrichtung bereits beachtet wird? Ich glaube, dass dies bei iOS Safari und in Browsern der Fall ist, die CSS unterstützen, image-orientation: from-imagewenn es verwendet wird.
Oliver Joseph Ash
40

Wenn

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

Mit diesen Transformationen können Sie das Bild dann auf Ausrichtung 1 drehen

Aus der Orientierung:

  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);

Vor dem Zeichnen des Bildes auf ctx

Mederr
quelle
58
Was passiert hier überhaupt?
Muhammad Umer
1
Dazu müssen Sie nur die Ausrichtung kennen (z. B. über EXIF) und dann nach Bedarf drehen. Die Hälfte von dem, wonach ich suche.
Brenden
2
Diese Transformationen haben bei mir nicht funktioniert. Stattdessen habe ich den Code aus dem Load-Image-Projekt unter github.com/blueimp/JavaScript-Load-Image/blob/master/js/… verwendet , um den meiner Meinung nach bewährten Code zu erhalten Dabei werden sowohl Übersetzungs- als auch Rotationsvorgänge im Canvas-Kontext sowie ein Breiten- / Höhen-Swap verwendet. Hat mir nach vielen Stunden des Experimentierens mit anderen Transformationsversuchen 100% Ergebnisse gebracht
Andy Lorenz
1
Warum ist es wichtig, wenn Sie das Bild auf ctx zeichnen? Sie können die Leinwand nicht drehen, nachdem Sie ein Bild darauf gezeichnet haben?
AlxVallejo
Die Drehung zur Orientierung 8 funktioniert für mich folgendermaßen: ctx.transform (0, -1, 1, 0, 0, Höhe);
Giorgio Barchiesi
24

ok zusätzlich zu @ user3096626 Antwort Ich denke, es ist hilfreicher, wenn jemand ein Codebeispiel zur Verfügung stellt. Das folgende Beispiel zeigt Ihnen, wie die Bildorientierung von der URL (Remote-Bilder) korrigiert wird:


Lösung 1: Verwenden von Javascript (empfohlen)

  1. da Last-Bild Bibliothek EXIF - Tags aus url Bildern nur (Datei- / Blob) nicht extrahiert, werden wir beide verwenden Exif-js und Last-Bild Javascript - Bibliotheken, so zuerst diese Bibliotheken als folgen zu Ihrer Seite hinzufügen:

    <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>

    Beachten Sie, dass die Version 2.2 von exif-js Probleme zu haben scheint, also haben wir 2.1 verwendet

  2. dann werden wir im Grunde genommen tun

    a - Laden Sie das Bild mit window.loadImage()

    b - Exif-Tags mit lesen window.EXIF.getData()

    c - Konvertieren Sie das Bild in Leinwand und korrigieren Sie die Bildausrichtung mit window.loadImage.scale()

    d - Platzieren Sie die Leinwand im Dokument

Bitte schön :)

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);

    });
  }
});

Natürlich können Sie das Bild auch als base64 vom Canvas-Objekt abrufen und in das Attribut img src einfügen, sodass Sie dies mit jQuery tun können;)

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

Hier ist der vollständige Code unter: github: https://github.com/digital-flowers/loadimage-exif-example


Lösung 2: Verwenden von HTML (Browser-Hack)

Es gibt einen sehr schnellen und einfachen Hack. Die meisten Browser zeigen das Bild in der richtigen Ausrichtung an, wenn das Bild in einem neuen Tab direkt ohne HTML geöffnet wird (LOL, ich weiß nicht warum). Sie können Ihr Bild also grundsätzlich mit iframe anzeigen indem Sie das iframe src-Attribut direkt als Bild-URL einfügen:

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

Lösung 3: Verwenden von CSS (nur Firefox & Safari auf iOS)

Es gibt ein CSS3-Attribut zum Korrigieren der Bildausrichtung, aber das Problem, dass es nur auf Firefox und Safari / iOS funktioniert, ist immer noch erwähnenswert, da es bald für alle Browser verfügbar sein wird (Browser-Support-Informationen von caniuse ).

img {
   image-orientation: from-image;
}
Fareed Alnamrouti
quelle
Lösung 1 hat bei mir nicht funktioniert. Es gibt window.loadImage zurück ist undefiniert
Perry
Dies geschah, wenn Sie die Bibliotheken, die ich in Schritt 1
Fareed Alnamrouti
Ich habe die Bibliotheken aufgenommen. Ich mag die Einfachheit Ihres Beispiels, aber ich erhalte immer wieder diese Fehlermeldung.
Perry
1
Es scheint, dass exif-js kaputt war. Bitte überprüfen Sie meine Bearbeitung. Ich habe auch den vollständigen Code auf github hinzugefügt: github.com/digital-flowers/loadimage-exif-example
Fareed Alnamrouti
1
ok checkout das github projekt gibt es eine neue datei "upload.html", du bist willkommen :)
Fareed Alnamrouti
10

Für diejenigen, die eine Datei von einem Eingabesteuerelement haben, nicht wissen, wie sie ausgerichtet ist, etwas faul sind und keine große Bibliothek hinzufügen möchten, ist der von @WunderBart bereitgestellte Code mit der Antwort verschmolzen, auf die er verweist ( https://stackoverflow.com/a/32490603 ), der die Ausrichtung findet.

function getDataUrl(file, callback2) {
        var callback = function (srcOrientation) {
            var reader2 = new FileReader();
            reader2.onload = function (e) {
                var srcBase64 = e.target.result;
                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
                    callback2(canvas.toDataURL());
                };

                img.src = srcBase64;
            }

            reader2.readAsDataURL(file);
        }

        var reader = new FileReader();
        reader.onload = function (e) {

            var view = new DataView(e.target.result);
            if (view.getUint16(0, false) != 0xFFD8) return callback(-2);
            var length = view.byteLength, offset = 2;
            while (offset < length) {
                var marker = view.getUint16(offset, false);
                offset += 2;
                if (marker == 0xFFE1) {
                    if (view.getUint32(offset += 2, false) != 0x45786966) return callback(-1);
                    var little = view.getUint16(offset += 6, false) == 0x4949;
                    offset += view.getUint32(offset + 4, little);
                    var tags = view.getUint16(offset, little);
                    offset += 2;
                    for (var i = 0; i < tags; i++)
                        if (view.getUint16(offset + (i * 12), little) == 0x0112)
                            return callback(view.getUint16(offset + (i * 12) + 8, little));
                }
                else if ((marker & 0xFF00) != 0xFF00) break;
                else offset += view.getUint16(offset, false);
            }
            return callback(-1);
        };
        reader.readAsArrayBuffer(file);
    }

was leicht so genannt werden kann

getDataUrl(input.files[0], function (imgBase64) {
      vm.user.BioPhoto = imgBase64;
});
runxc1 Bret Ferrier
quelle
2
Vielen Dank nach über 2 Stunden Suche von Google finde ich die richtige Lösung.
Mr.Trieu
2
Warum sollte jemand faul sein, eine viel leichtere Lösung zu bevorzugen?
Tau
4
Auf Typescript portiert und von ca. 4 Sekunden auf ~ 20 Millisekunden optimiert . Die Base64-Codierung war der Engpass - die Verwendung image/jpeganstelle der Standardeinstellung image/pngund die Größenänderung des Ausgabebilds auf eine maximale Breite (in meinem Fall 400 Pixel) machten einen großen Unterschied. (Dies funktioniert gut für Miniaturansichten, aber wenn Sie das vollständige Bild anzeigen müssen, würde ich empfehlen, base64 zu vermeiden und einfach das Canvas-Element direkt in die Seite
einzufügen
8

WunderBarts Antwort war die beste für mich. Beachten Sie, dass Sie es erheblich beschleunigen können, wenn Ihre Bilder häufig richtig herum sind, indem Sie einfach zuerst die Ausrichtung testen und den Rest des Codes umgehen, wenn keine Drehung erforderlich ist.

Alle Informationen von wunderbart zusammenstellen, so etwas;

var handleTakePhoto = function () {
    let fileInput: HTMLInputElement = <HTMLInputElement>document.getElementById('photoInput');
    fileInput.addEventListener('change', (e: any) => handleInputUpdated(fileInput, e.target.files));
    fileInput.click();
}

var handleInputUpdated = function (fileInput: HTMLInputElement, fileList) {
    let file = null;

    if (fileList.length > 0 && fileList[0].type.match(/^image\//)) {
        isLoading(true);
        file = fileList[0];
        getOrientation(file, function (orientation) {
            if (orientation == 1) {
                imageBinary(URL.createObjectURL(file));
                isLoading(false);
            }
            else 
            {
                resetOrientation(URL.createObjectURL(file), orientation, function (resetBase64Image) {
                    imageBinary(resetBase64Image);
                    isLoading(false);
                });
            }
        });
    }

    fileInput.removeEventListener('change');
}


// from http://stackoverflow.com/a/32490603
export function getOrientation(file, callback) {
    var reader = new FileReader();

    reader.onload = function (event: any) {
        var view = new DataView(event.target.result);

        if (view.getUint16(0, false) != 0xFFD8) return callback(-2);

        var length = view.byteLength,
            offset = 2;

        while (offset < length) {
            var marker = view.getUint16(offset, false);
            offset += 2;

            if (marker == 0xFFE1) {
                if (view.getUint32(offset += 2, false) != 0x45786966) {
                    return callback(-1);
                }
                var little = view.getUint16(offset += 6, false) == 0x4949;
                offset += view.getUint32(offset + 4, little);
                var tags = view.getUint16(offset, little);
                offset += 2;

                for (var i = 0; i < tags; i++)
                    if (view.getUint16(offset + (i * 12), little) == 0x0112)
                        return callback(view.getUint16(offset + (i * 12) + 8, little));
            }
            else if ((marker & 0xFF00) != 0xFF00) break;
            else offset += view.getUint16(offset, false);
        }
        return callback(-1);
    };

    reader.readAsArrayBuffer(file.slice(0, 64 * 1024));
};

export 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;
}
statler
quelle
1
Toller Ansatz. Sie sollten auch in Betracht ziehen, das zu behandeln -2und -1von zurückzukehren, getOrientationdamit Sie nicht versuchen, Nicht-JPGs oder Bilder ohne Rotationsdaten zu drehen.
Steven Lambert
Ich habe weitere Optimierungen vorgenommen, siehe meinen Kommentar oben - ich habe gerade auch Ihre file.slice()Optimierung hinzugefügt , aber der eigentliche Schub liegt in der Verwendung kleinerer Bilder und des image/jpegAusgabeformats zum Erstellen kleinerer Daten-URLs. (Selbst bei 10-Megapixel-Bildern ist keine Verzögerung erkennbar.)
mindplay.dk
Vorsicht file.slice(), da Sie die Unterstützung von base64-Bildquellen verhindern.
Mark
Danke, Mark - möchten Sie eine Alternative bearbeiten?
Statler
7

Ein Liner jemand?

Ich habe niemanden gesehen, der die browser-image-compressionBibliothek erwähnt hat . Es hat eine Helferfunktion, die perfekt dafür ist.

Verwendung: const orientation = await imageCompression.getExifOrientation(file)

Solch ein nützliches Werkzeug auch auf viele andere Arten.

Gilbert-v
quelle
Dies erhält die Orientierung. Aber wie erstelle ich mit diesen Informationen ein neues JPG-Dateiobjekt auf der Clientseite?
Masterxilo
FileSoweit ich weiß, können Sie keine Objekte erstellen . Das nächstbeste wäre, das Bild und die Ausrichtung an den Server zu senden und dort die Datei zu bearbeiten. Oder Sie können mit canvasund die toDataURLMethode einen base64-String generieren .
Gilbert-v
1
Nein, Sie können ein Dateiobjekt aus einem Blob erstellen. Datei Datei (Array-Teile, String-Dateiname, BlobPropertyBag-Eigenschaften); developer.mozilla.org/de/docs/Web/API/File
masterxilo
2
Goldaufkleber! @masterxilo
Gilbert-v
2
Das hat bei mir super geklappt! Ich hatte in den letzten 2 Tagen mit Orientierungen zu kämpfen! Alle veröffentlichten Transformationsschalteranweisungen würden aus irgendeinem Grund keine Porträtbilder von meinem Telefon verarbeiten, es würden schwarze Balken angezeigt. Wahrscheinlich, weil ich versucht habe, gleichzeitig zu komprimieren und zu drehen.
cjd82187
2

Ich habe eine Klasse erstellt, die in ein ES6-Modul eingebunden ist, das genau dieses Problem löst.

Es besteht aus 103 Zeilen, keine Abhängigkeiten und ist recht gut strukturiert und dokumentiert. Es soll einfach zu ändern / wiederzuverwenden sein.

Behandelt alle 8 möglichen Ausrichtungen und basiert auf Versprechen.

Ich hoffe, das hilft noch jemandem: https://gist.github.com/vdavid/3f9b66b60f52204317a4cc0e77097913

Dávid Veszelovszki
quelle
1

Ich benutze gemischte Lösung (PHP + CSS).

Container werden benötigt für:

  • div.imgCont2 Behälter zum Drehen benötigt;
  • div.imgCont1Container zum Zoomen benötigt - width:150%;
  • div.imgCont Container, der für Bildlaufleisten benötigt wird, wenn das Bild zoomOut ist.

.

<?php
    $image_url = 'your image url.jpg';
    $exif = @exif_read_data($image_url,0,true);
    $orientation = @$exif['IFD0']['Orientation'];
?>

<style>
.imgCont{
    width:100%;
    overflow:auto;
}
.imgCont2[data-orientation="8"]{
    transform:rotate(270deg);
    margin:15% 0;
}
.imgCont2[data-orientation="6"]{
    transform:rotate(90deg);
    margin:15% 0;
}
.imgCont2[data-orientation="3"]{
    transform:rotate(180deg);
}
img{
    width:100%;
}
</style>

<div class="imgCont">
  <div class="imgCont1">
    <div class="imgCont2" data-orientation="<?php echo($orientation) ?>">
      <img src="<?php echo($image_url) ?>">
    </div>
  </div>
</div>
Sergey S.
quelle
Danke, dies scheint die beste Lösung für meine Bedürfnisse zu sein. Keine Notwendigkeit für externe Bibliotheken und keine langen Blöcke unnötigen Codes. Bestimmen Sie einfach die Ausrichtung des Exif mit PHP, senden Sie es an die Ansicht und lösen Sie damit CSS-Klassen aus, die sich um die entsprechende Gradzahl drehen. Schön und sauber! Bearbeiten: Dadurch werden Bilder in Browsern, die die Exif-Daten tatsächlich lesen, übermäßig gedreht und entsprechend gedreht. AKA es wird das Problem auf dem Desktop beheben, aber ein neues auf ios safari erstellen.
Cwal
0

Zusätzlich zu der Antwort von @fareed namrouti

Dies sollte verwendet werden, wenn das Bild von einem Dateieingabeelement aus durchsucht werden muss

<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>
Perry
quelle
0

Ich habe ein kleines PHP-Skript geschrieben, das das Bild dreht. Stellen Sie sicher, dass Sie das Bild speichern, um es bei jeder Anforderung neu zu berechnen.

<?php

header("Content-type: image/jpeg");
$img = 'IMG URL';

$exif = @exif_read_data($img,0,true);
$orientation = @$exif['IFD0']['Orientation'];
if($orientation == 7 || $orientation == 8) {
    $degrees = 90;
} elseif($orientation == 5 || $orientation == 6) {
    $degrees = 270;
} elseif($orientation == 3 || $orientation == 4) {
    $degrees = 180;
} else {
    $degrees = 0;
}
$rotate = imagerotate(imagecreatefromjpeg($img), $degrees, 0);
imagejpeg($rotate);
imagedestroy($rotate);

?>

Prost

Thom
quelle