縦で撮影した画像が横に回転している
まずは『Exif情報』というものが何かを理解する
↓フロント系はこの記事が素晴らしかった
iPhoneからアップロードしたJPEG写真が横向きになる問題(EXIF, Orientation)
↓色々と全体を把握するために見た記事
http://www.glic.co.jp/blog/archives/88
https://qiita.com/uda0922/items/c83c239eb32ed295fca8
https://qiita.com/k-holy/items/2ed10bdcf53181bb695d
↓PHP側の最終解決策
前談
iPhoneで撮影した画像だと起きる現象と言われたので
SlackでMacに画像を送信してローカルで試してみると再現しない…
なにこれ!?
AirDropで送って見ると再現する。
画像の拡張子は.HEIC
…なにそれ!?!?
調べて見るとiOS11辺りで導入された.jpegよりも効率のいいファイル形式なのだとか、、、
そして対応OSがとても限られている…
HTMLの<input type="file" accept="image/*">
にすると
Mac上では.HEIC形式の画像を選択することすら出来ない始末…
じゃあ何でiPhoneだと選択できるんだよ!!
と思ったらモバイルSafariでは.HEICを自動で.JPEGによしなに変換してくれているのだそう。
ほーん。
それじゃあ、ローカルではaccept
指定外して.HEICもこのサイト
使って.JPEGに変換して実験してやろうじゃないの!!
Exif情報のorientationを見てみた
上のリンクの記事を見ればわかるのでざっくりいきます。
横向きに回転してしまう画像のOrientationは6になっていました。
$image = // 画像
$exif_data = @exif_read_data($image);
echo $exif_data['Orientation'];
// 6
Orientation = 1 は、Exif画像ファイルに保存されたデータの行0と、表示画面でのvisual topを、列0とvisual leftを、それぞれ一致させて表示する場合に記録する。
Orientation = 2 は、Orientation = 1 を左右反転したものに相当する。
Orientation = 3 は、Orientation = 6 を時計回りに90度回転したものに相当する。
Orientation = 4 は、Orientation = 3 を左右反転したものに相当する。
Orientation = 5 は、Orientation = 6 を左右反転したものに相当する。
Orientation = 6 は、Orientation = 1 を時計回りに90度回転したものに相当する。
Orientation = 7 は、Orientation = 8 を左右反転したものに相当する。
Orientation = 8 は、Orientation = 3 を時計回りに90度回転したものに相当する。
じゃあお手製で画像をクルクル回すコード書いてやればいいんやろ??
と思いImageMagickやらimagickやらを使ったパターンや
PHPのGDを使ったパターンなど一生懸命構想を練ったものを実装していたんですが…
Image::makeを使えばかんたん!
下記はこれのコードをそのまま移したものです。
$img = \Image::make($request->file('image_file')->getRealpath());
$img->orientate();
私がlaravelで実装した時はこんな感じ
<?php
namespace 省略
// 省略
use Image; // この子が活躍します。
class hogeController extends Controller
{
public function save(Request $request)
{
// 沢山省略
$orgImage = $request->image;
$image = Image::make($orgImage->getRealPath);
// サイズ変更したり、あんなことやこんなことをする
// ↓これでOK
$image->orientate();
// 省略
}
}
独自で書きたければ
一番上に並べてあるリンクのコードの抜粋です。
これなら自分でメソッド作って自由な処理を入れられますね!
$exif = exif_read_data($request->file('image_file'));
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']) {
case 8:
$image = imagerotate($image,90,0);
break;
case 3:
$image = imagerotate($image,180,0);
break;
case 6:
$image = imagerotate($image,-90,0);
break;
}
}