Orientasi Exif Sisi Klien JS: Memutar dan Mencerminkan Gambar JPEG


154

Foto kamera digital sering disimpan sebagai JPEG dengan tag "orientasi" EXIF. Untuk menampilkan dengan benar, gambar perlu diputar / dicerminkan tergantung pada orientasi mana yang diatur, tetapi browser mengabaikan informasi ini membuat gambar. Bahkan dalam aplikasi web komersial besar, dukungan untuk orientasi EXIF ​​bisa sangat sulit 1 . Sumber yang sama juga memberikan ringkasan yang bagus tentang 8 orientasi berbeda yang dapat dimiliki JPEG:

Ringkasan Orientasi EXIF

Contoh gambar tersedia di 4 .

Pertanyaannya adalah bagaimana memutar / mirror gambar pada sisi klien sehingga ditampilkan dengan benar dan dapat diproses lebih lanjut jika perlu?

Ada pustaka JS yang tersedia untuk mem-parsing data EXIF, termasuk atribut orientasi 2 . Flickr mencatat kemungkinan masalah kinerja saat mem-parsing gambar besar, membutuhkan penggunaan webworkers 3 .

Alat konsol dapat dengan benar mengarahkan ulang gambar 5 . Skrip PHP yang memecahkan masalah tersedia di 6

Jawaban:


145

Proyek github, JavaScript-Load-Image, memberikan solusi lengkap untuk masalah orientasi EXIF, dengan memutar / mirroring gambar dengan benar untuk semua 8 orientasi exif. Lihat demo online orientasi javascript exif

Gambar digambar di atas kanvas HTML5. Render yang benar diimplementasikan dalam js / load-image-orient.js melalui operasi kanvas.

Semoga ini menghemat waktu orang lain, dan ajarkan mesin pencari tentang permata open source ini :)


1
Saya telah menggunakan perpustakaan ini tetapi baru-baru ini rusak di iOS 8.3 yang mana saya paling membutuhkannya untuk bekerja :(
Gordon Sun

2
Saya benar-benar berjuang untuk melihat bagaimana ini membantu. Saya bermain-main dengannya mencoba mempelajarinya sehingga saya dapat mengurai halaman dan memutar gambar ketika mereka perlu diputar, atau mendeteksi orientasi dan memutar file (entah bagaimana) sebelum benar-benar mengunggahnya. Demo tidak melakukan keduanya. Ini hanya mengambil file dari input file dan menampilkannya dengan cara yang benar, kapan ini berguna di dunia nyata? Ketika saya mem-parsing halaman saya dan memasukkan URL dari tag gambar ke perpustakaan loadImage tidak ada data exif jadi tidak bisa melakukan itu. Untuk unggahan, ia mengembalikan objek kanvas sehingga saya tidak dapat mengirimnya ke server atau apa pun.
igneosaur

3
@igneosaur: Anda dapat mengirim data yang disandikan base64 ke server dengan canvas.toDataURL()dan mendekode dan menyimpannya sisi server.
br4nnigan

1
daripada menggunakan proyek load-image, Anda dapat menggunakan beberapa basis kode untuk memanggang sendiri - cukup lihat di github.com/blueimp/JavaScript-Load-Image/blob/master/js/… .
Andy Lorenz

1
Apakah ada cara untuk membuat kanvas yang dihasilkan pustaka ini responsif seperti <img>tag biasa ?
Erik Berkun-Drevnig

103

Transformasi konteks Mederr bekerja dengan sempurna. Jika Anda perlu mengekstrak orientasi, gunakan saja fungsi ini - Anda tidak memerlukan libs pembacaan EXIF. Di bawah ini adalah fungsi untuk mengatur ulang orientasi pada gambar base64. Ini biola untuk itu . Saya juga menyiapkan biola dengan demo ekstraksi orientasi .

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

7
Kasus default dalam orientasi switchtidak diperlukan, karena transformasi itu tidak melakukan apa-apa. Juga, pertimbangkan untuk menggunakan srcOrientation > 4 && srcOrientation < 9alih-alih [5,6,7,8].indexOf(srcOrientation) > -1, karena lebih cepat dan kurang intensif sumber daya (baik RAM & CPU). Tidak perlu memiliki array di sana. Ini penting ketika mengelompokkan banyak gambar, di mana setiap bit dihitung. Kalau tidak, jawabannya cukup bagus. Terpilih!
Ryan Casas

4
@RyanCasas Saya tidak tahu seberapa berat dapat indexOfmembandingkan dengan apa yang Anda usulkan. Saya menjalankan loop sederhana dengan iterasi 10M dan 1400% lebih cepat. Bagus: D Terima kasih banyak!
WunderBart

1
Saya menggunakan jawaban ini di Android WebView dan ternyata, ada beberapa perangkat Android, yang tidak mendukung WebGL dalam WebView (lihat bugs.chromium.org/p/chromium/issues/detail?id=555116 ) rotasi dapat memakan waktu sangat lama pada perangkat tersebut tergantung pada ukuran gambar.
ndreisg

1
Saat digunakan dengan referensi getOrientation, saya ingin tahu apakah ini efisien dalam hal kinerja. getOrientationpanggilan fileReader.readAsArrayBuffer, lalu kami panggil URL.createObjectURLdan berikan hasilnya resetOrientation, yang memuat URL ini sebagai gambar. Apakah ini berarti file gambar akan "dimuat" / dibaca oleh browser tidak hanya sekali tetapi dua kali, atau apakah saya salah paham?
Oliver Joseph Ash

1
Juga, apa yang harus dilakukan tentang browser yang orientasinya sudah dihormati? Saya percaya ini adalah kasus untuk iOS Safari, dan di browser yang mendukung CSS image-orientation: from-imagesaat digunakan.
Oliver Joseph Ash

40

Jika

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

Kemudian Anda dapat menggunakan transformasi ini untuk mengubah gambar ke orientasi 1

Dari orientasi:

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

Sebelum menggambar gambar pada ctx


58
apa yang terjadi di sini?
Muhammad Umer

1
Dengan ini, Anda hanya perlu mengetahui orientasi (mis. Via EXIF) dan kemudian memutar sesuai kebutuhan. Setengah dari yang saya cari.
Brenden

2
transformasi ini tidak bekerja untuk saya - sebagai gantinya saya menggunakan kode dari proyek load-image di github.com/blueimp/JavaScript-Load-Image/blob/master/js/… untuk mendapatkan apa yang saya yakini sebagai kode yang sudah terbukti baik yang menggunakan kedua penerjemahan, putar operasi pada konteks kanvas plus pertukaran lebar / tinggi. Memberi saya hasil 100% setelah banyak jam bereksperimen dengan upaya lain untuk mengubah dll
Andy Lorenz

1
Mengapa itu penting ketika Anda menggambar gambar di ctx? Anda tidak dapat memutar kanvas setelah menggambar gambar di atasnya?
AlxVallejo

Rotasi untuk orientasi 8 berfungsi seperti ini untuk saya: ctx.transform (0, -1, 1, 0, 0, tinggi);
Giorgio Barchiesi

24

ok selain jawaban @ user3096626 saya pikir akan lebih membantu jika seseorang memberikan contoh kode, contoh berikut ini akan menunjukkan kepada Anda bagaimana cara memperbaiki orientasi gambar berasal dari url (gambar jarak jauh):


Solusi 1: menggunakan javascript (disarankan)

  1. karena pustaka load-image tidak mengekstraksi tag exif hanya dari gambar url (file / blob), kami akan menggunakan pustaka javascript exif-js dan load-image , jadi pertama-tama tambahkan pustaka ini ke halaman Anda sebagai berikut:

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

    Perhatikan bahwa versi 2.2 dari exif-js tampaknya memiliki masalah sehingga kami menggunakan 2.1

  2. maka pada dasarnya apa yang akan kita lakukan adalah

    a - memuat gambar menggunakan window.loadImage()

    b - baca tag exif menggunakan window.EXIF.getData()

    c - ubah gambar menjadi kanvas dan perbaiki orientasi gambar menggunakan window.loadImage.scale()

    d - tempatkan kanvas ke dalam dokumen

ini dia :)

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

    });
  }
});

tentu saja Anda juga bisa mendapatkan gambar sebagai base64 dari objek kanvas dan letakkan di atribut img src, jadi dengan menggunakan jQuery Anda bisa melakukannya;)

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

di sini adalah kode lengkap di: github: https://github.com/digital-flowers/loadimage-exif-example


Solusi 2: menggunakan html (peretasan browser)

ada peretasan yang sangat cepat dan mudah, sebagian besar peramban menampilkan gambar dalam orientasi yang benar jika gambar dibuka di dalam tab baru secara langsung tanpa html (LOL saya tidak tahu mengapa), jadi pada dasarnya Anda dapat menampilkan gambar Anda menggunakan iframe dengan menempatkan atribut iframe src sebagai url gambar secara langsung:

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

Solusi 3: menggunakan css (hanya firefox & safari di ios)

ada atribut css3 untuk memperbaiki orientasi gambar tetapi masalahnya hanya bekerja pada firefox dan safari / ios masih layak disebutkan karena segera akan tersedia untuk semua browser (Info dukungan browser dari caniuse )

img {
   image-orientation: from-image;
}

Solusi 1 tidak berhasil untuk saya. Itu kembali window.loadImage tidak ditentukan
Perry

Ini terjadi jika Anda tidak menyertakan perpustakaan yang saya sebutkan di langkah 1
Fareed Alnamrouti

Saya termasuk perpustakaan. Saya suka kesederhanaan contoh Anda, tetapi saya terus menerima pesan kesalahan itu.
Perry,

1
tampaknya exif-js rusak, silakan periksa edit saya, saya juga telah menambahkan kode lengkap pada github: github.com/digital-flowers/loadimage-exif-example
Fareed Alnamrouti

1
ok checkout proyek github ada file baru "upload.html", Anda dipersilakan :)
Fareed Alnamrouti

10

Bagi mereka yang memiliki file dari kontrol input, tidak tahu apa orientasinya, agak malas dan tidak ingin memasukkan perpustakaan besar di bawah ini adalah kode yang disediakan oleh @WunderBart menyatu dengan jawaban yang ia tautkan ( https://stackoverflow.com/a/32490603 ) yang menemukan orientasi.

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

yang bisa dengan mudah disebut seperti itu

getDataUrl(input.files[0], function (imgBase64) {
      vm.user.BioPhoto = imgBase64;
});

2
Terima kasih setelah pencarian lebih dari 2 jam oleh google Saya menemukan solusi yang tepat.
Mr.Trieu

2
mengapa seseorang menjadi malas untuk memilih solusi yang jauh lebih ringan?
dewd

4
Diterjemahkan ke TypeScript dan dioptimalkan dari sekitar 4 detik hingga ~ 20 milidetik. Pengkodean Base64 adalah hambatan - menggunakan image/jpegalih-alih default image/png, dan mengubah ukuran gambar output ke lebar maksimum (400px dalam kasus saya) membuat perbedaan besar. (ini berfungsi dengan baik untuk thumbnail, tetapi jika Anda harus menampilkan gambar penuh, saya sarankan menghindari base64 dan cukup menyuntikkan elemen kanvas langsung ke halaman ...)
mindplay.dk

8

Jawaban WunderBart adalah yang terbaik untuk saya. Perhatikan bahwa Anda dapat mempercepatnya banyak jika gambar Anda sering berada di jalur yang benar, cukup dengan menguji orientasi terlebih dahulu dan melewati sisa kode jika tidak diperlukan rotasi.

Menyatukan semua info dari wunderbart, sesuatu seperti ini;

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

1
Pendekatan yang bagus. Anda juga harus mempertimbangkan untuk menangani -2dan -1kembali dari getOrientationsehingga Anda tidak mencoba untuk memutar non-jpg atau gambar tanpa data rotasi.
Steven Lambert

Saya membuat lebih banyak pengoptimalan, lihat komentar saya di atas - Saya baru saja menambahkan file.slice()pengoptimalan Anda , tetapi dorongan sebenarnya berasal dari penggunaan gambar yang lebih kecil dan image/jpegformat keluaran untuk membuat URL data yang lebih kecil. (tidak ada penundaan nyata bahkan untuk gambar 10-megapiksel.)
mindplay.dk

Hati-hati dengan file.slice(), karena Anda akan mencegah dukungan sumber gambar base64.
Markus

Terima kasih tandai - peduli untuk memberikan suntingan sebagai alternatif?
statler

7

Satu liner, siapa pun?

Saya belum melihat ada yang menyebutkan browser-image-compressionperpustakaan . Ada fungsi pembantu yang sempurna untuk ini.

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

Alat yang bermanfaat dalam banyak hal juga.


Ini mendapat orientasi. Tetapi bagaimana saya menghasilkan objek file .jpg baru di sisi klien menggunakan informasi ini?
masterxilo

Anda tidak dapat membuat Fileobjek sejauh yang saya tahu. Hal terbaik berikutnya adalah mengirim gambar dan orientasi ke server, dan melakukan manipulasi file di sana. Atau Anda bisa membuat string base64 menggunakan canvasdan toDataURLmetode.
gilbert-v

1
Tidak, Anda dapat membuat objek File dari Blob saja. File File (Array parts, String filename, properti BlobPropertyBag); developer.mozilla.org/de/docs/Web/API/File
masterxilo

2
Stiker emas! @masterxilo
gilbert-v

2
Ini bekerja dengan baik untuk saya! Saya telah berjuang dengan orientasi selama 2 hari terakhir! Semua pernyataan saklar transformasi yang diposting tidak akan menangani gambar potret dari ponsel saya karena alasan tertentu, akan ada bilah hitam. Mungkin karena saya mencoba mengompres dan memutar pada waktu yang bersamaan.
cjd82187


1

Saya menggunakan solusi campuran (php + css).

Wadah diperlukan untuk:

  • div.imgCont2 wadah yang dibutuhkan untuk memutar;
  • div.imgCont1wadah yang diperlukan untuk zoomout - width:150%;
  • div.imgCont diperlukan wadah untuk scrollbar, ketika gambar zoomOut.

.

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

Terima kasih, ini sepertinya solusi terbaik, untuk kebutuhan saya. Tidak perlu pustaka eksternal dan tidak ada blok panjang kode yang tidak perlu. Cukup tentukan orientasi dari exif dengan php, kirimkan ke tampilan dan gunakan untuk memicu kelas CSS yang memutar jumlah derajat yang sesuai. Bagus dan bersih! Sunting: ini akan memutar gambar di browser yang benar-benar membaca data exif dan memutar sesuai. AKA akan memperbaiki masalah di desktop tetapi membuat yang baru di ios safari.
cwal

0

Selain jawaban @fareed namrouti,

Ini harus digunakan jika gambar harus diakses dari elemen input file

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

0

Saya telah menulis skrip php kecil yang memutar gambar. Pastikan untuk menyimpan gambar demi hanya menghitung ulang setiap permintaan.

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

?>

Bersulang

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.