写真画像を操作する時のOrientation+Rotateの扱い方

2019年9月22日

テクノロジー プログラミング

スマホで撮影したjpeg画像にはExif情報が含まれていますが、その情報の中のOrientation値というのが若干やっかいな値だったので、サービス構築の際に困らないように、情報のまとめと、簡単なスニペットを作っておきました。 orientationという値は、スマホで撮影する時に縦サイズ(Vertical)と横サイズ(Horizontal)というモードが切り替わるんですが、要するに縦で撮影するか横で撮影するかで、写真の向きが自動に変わりますが、スマホで撮影された写真素材は縦長データでのみ保存されます。 その時にorientationに回転した情報が格納されて、その写真を表示するアプリ側で写真素材を回転して表示するという流れなのですが、WEBサービスで同じ素材を使う時に、サーバー側か、CSSで、orientationの値を元に回転処理を行わなければいけません。 回転と言っても90度回転させるだけでなく、スマホを横向きにする時に、右倒しじゃなく、左倒しにすると、270度の回転が必要になるし、天地を逆にしたら180度の処理をしないといけないのですが、こうしたことからorientation特性のflip処理などがあるので、ややこしさ半端無く感じてしまいます。

orientationについて

色々なサイトでorientationの値を紹介していますが、以下のような情報になります。
Orientation内容
1標準 : default
2flip width : 上下反転
3rotate 180deg : 180度回転
4flip height : 左右反転
5flip width + rotate 270deg : 上下反転、時計周りに270度回転
6rotate 90deg : 時計周りに90度回転
7flip height + rotate 90deg : 上下反転、時計周りに90度回転
8rotate 270deg : 時計周りに270度回転
値は8個ですが、5番と7番が頭の中では処理できないぐらいややこしいです・・・ これをエレメントで表現すると以下のようになります。
  1. F
  2. F
  3. F
  4. F
  5. F
  6. F
  7. F
  8. F
そして、これをPHPのclass-functionでGDライブラリで処理するコードは以下の通りです。 public static function orientation($img=null , $orientation=0){ switch($orientation){ case 0: // normal case 1: // normal break; case 2: // flip width imageflip($img, IMG_FLIP_HORIZONTAL); break; case 3: // rotate 180deg $col = imagecolorallocate($img, 0, 0, 0); $img = imagerotate($img, -180 , $col); break; case 4: // flip height imageflip($img, IMG_FLIP_VERTICAL); break; case 5: // flip width + rotate 270deg imageflip($img, IMG_FLIP_HORIZONTAL); $col = imagecolorallocate($img, 0, 0, 0); $img = imagerotate($img, -90 , $col); break; case 6: // rotate 90deg $col = imagecolorallocate($img, 0, 0, 0); $img = imagerotate($img, -90 , $col); break; case 7: // flip height + rotate 90deg imageflip($img, IMG_FLIP_VERTICAL); $col = imagecolorallocate($img, 0, 0, 0); $img = imagerotate($img, -90 , $col); break; case 8: // rotate 270deg $col = imagecolorallocate($img, 0, 0, 0); $img = imagerotate($img, -270 , $col); break; } return $img; }

さらに回転値を追加するとどうなるのか?

写真撮影をするが、撮影状態が悪く、横に取ったつもりが写真が縦になってしまうときがありますが、その場合はorientationにさらに回転処理を追加しなければいけません。 これがとにかく厄介! 基本的には、90度、180度、270度の回転を行う単純な処理として、orientation値をその回転に沿って調整後のorientation値を返すコードを作ってみます。 この時の回転値は、全て時計回りになることを前提にします。 ※orientation基準とcssのdeg基準でもあるので、その方がやりやすいはずです。 とりあえず、理解しやすいようにマトリクスtableを作っておきます。
# Orientation Rotate-90 Rotate-180 Rotate-270
1
F
F
F
F
2
F
F
F
F
3
F
F
F
F
4
F
F
F
F
5
F
F
F
F
6
F
F
F
F
7
F
F
F
F
8
F
F
F
F
public static function rotate2orientation($orientation , $rotate){ switch($orientation){ case 0: // normal case 1: // normal switch($rotate){ case 90 : $orientation = 6; break; case 180 : $orientation = 3; break; case 270 : $orientation = 8; break; } break; case 2: // flip width switch($rotate){ case 90 : $orientation = 5; break; case 180 : $orientation = 4; break; case 270 : $orientation = 7; break; } break; case 3: // rotate 180deg switch($rotate){ case 90 : $orientation = 8; break; case 180 : $orientation = 0;break; case 270 : $orientation = 6;break; } break; case 4: // flip height switch($rotate){ case 90 : $orientation = 7; break; case 180 : $orientation = 2; break; case 270 : $orientation = 5; break; } break; case 5: // flip width + rotate 270deg switch($rotate){ case 90 : $orientation = 4; break; case 180 : $orientation = 7; break; case 270 : $orientation = 2; break; } break; case 6: // rotate 90deg switch($rotate){ case 90 : $orientation = 3; break; case 180 : $orientation = 8; break; case 270 : $orientation = 1; break; } break; case 7: // flip height + rotate 90deg switch($rotate){ case 90 : $orientation = 2; break; case 180 : $orientation = 5; break; case 270 : $orientation = 4; break; } break; case 8: // rotate 270deg switch($rotate){ case 90 : $orientation = 0; break; case 180 : $orientation = 6; break; case 270 : $orientation = 3; break; } break; } return $orientation; } めちゃくちゃややこしく見えますが、orientation値をrotate値をもとに、正常に見える状態のorientation値を返すようにしています。 この返ってきた値で上記のorientation画像処理をして表示をすれば、正常の見栄えになること間違いなしです。 扱いづらいかもしれないので、関数は適宜環境に合わせて書き直してお使いください。 考え方だけご理解いただければ幸いです。

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。