iPhone[iOS]で縦向きの写真がPCブラウザで横向きになってしまう話とJS/CSSでの解決方法【Exif】

html/css

iPhone[iOS]で撮影した画像をアップロードした際に縦向きの写真がPCのブラウザで確認すると横向きになってしまったことはないでしょうか。
今回はそんな話とフロントエンドでの解決方法になります。

はじめは以下みたいな画像投稿画面作成して、input[type=file]で受け取った写真をphpに投げてサーバに保存するという感じで組んでましたが…

別窓で開く(iframe表示されない場合はこちら)
※実際に投稿はされません。フロント画面のみ。

iPhone[iOS]で試したらちゃんと縦向きに
PCで試すと横向きになっちゃう

スマホで見ているときは縦向きなのにブラウザにのると横向きになってしまいます。これは困る。

縦向き写真が横向きになってしまう原因

原因はExifで横向きに表示される写真をiOSでは Exif で写真の回転方向を補正して表示してくれていて、現状のPCブラウザだと Exif をチェックせず、そのまま横向きに表示してしまっているかたちになります。

ブラウザの表示状況はこんな感じ。

ブラウザ Chrome Firefox IE Edge Mac
Safari
iOS
Safari
Chrome
縦横対応 × × × × ×

iOSの表示を他の環境と整えられないか?

<img>タグで配置するとiOSのみ縦向き表示されるのでiOSのみ調整できればその後は結構容易なんじゃないかと思って試してみたところ、読み込んだ画像を【background-image】で表示するようにするとiOSでも横向きの表示になります。

別窓で開く(iframe表示されない場合はこちら)

【EXIF.Orientation】は写真Exif情報に含まれる回転方向で
通常の向き:1
右回りに90度回転:8
左回りに90度 回転 :6
180度回転 :3
になります。
2、5、7、4の場合はそれぞれ反転も

Exifの回転情報を見て補正

iOSでも他のブラウザと表示を整えることができたので、あとは写真に含まれているExif【 Orientation 】をチェックして補正してあげると縦向き・横向きを正常に表示させることができました。

Exifの読み込みには、
exif.js【https://github.com/exif-js/exif-js
を採用しました。

var img = document.getElementById("img"); //読み込む画像(実際はinput[type=file]から参照)
var orientation; //画像の向き格納変数

EXIF.getData(img, function(){ //EXIF.getDataでEXIF情報を取得
    var exifData = EXIF.pretty(this);

    if(exifData){ //Exifデータのチェック Exifがない場合は、空が返ってきます
        orientation = EXIF.getTag(this, "Orientation"); //Orientation情報を格納

     //あとはOrientation情報で写真の向きを補正させる
    }
});

こんな感じで簡単に【Orientation】情報を取得できます。
またこちらGPSの位置情報等が埋め込まれていた場合にも取得できますので画像から地図を表示、といった場合にも使用可能です。

exif.jsで取得した情報をもとに【backgrond-image】で配置した写真を【transform: rotate(XXdeg)】で回転させることで横向きになってしまった縦向き写真も正常位置に表示させることができます。

別窓で開く(iframe表示されない場合はこちら)

※Exif情報のない写真があった場合にユーザーが写真を回転できるよう左右回転ボタン配置しています

次のブラウザリリース後は不要かも

今年の3月リリースのChrome/Webkit/Firefoxで【image-orientation: from-image】が初期値になるようで、そうするとブラウザ側でExif情報を読んで表示してくれるようになるので余計な実装なく解消されるかもしれないです。
※image-orientation = 画像の回転角度を指定するCSSプロパティ

ただIEで相変わらず対応してくれないと実装必須になってしまうのでその辺どうにかならないかなーという気持ち。

CSS3 image-orientation | Can I Use
https://caniuse.com/#feat=css-image-orientation

おしまい。

タイトルとURLをコピーしました