スマホで撮影したjpeg画像にはExif情報が含まれていますが、その情報の中のOrientation値というのが若干やっかいな値だったので、サービス構築の際に困らないように、情報のまとめと、簡単なスニペットを作っておきました。
orientationという値は、スマホで撮影する時に縦サイズ(Vertical)と横サイズ(Horizontal)というモードが切り替わるんですが、要するに縦で撮影するか横で撮影するかで、写真の向きが自動に変わりますが、スマホで撮影された写真素材は縦長データでのみ保存されます。
その時にorientationに回転した情報が格納されて、その写真を表示するアプリ側で写真素材を回転して表示するという流れなのですが、WEBサービスで同じ素材を使う時に、サーバー側か、CSSで、orientationの値を元に回転処理を行わなければいけません。
回転と言っても90度回転させるだけでなく、スマホを横向きにする時に、右倒しじゃなく、左倒しにすると、270度の回転が必要になるし、天地を逆にしたら180度の処理をしないといけないのですが、こうしたことからorientation特性のflip処理などがあるので、ややこしさ半端無く感じてしまいます。
orientationについて
色々なサイトでorientationの値を紹介していますが、以下のような情報になります。| Orientation | 内容 |
|---|---|
| 1 | 標準 : default |
| 2 | flip width : 上下反転 |
| 3 | rotate 180deg : 180度回転 |
| 4 | flip height : 左右反転 |
| 5 | flip width + rotate 270deg : 上下反転、時計周りに270度回転 |
| 6 | rotate 90deg : 時計周りに90度回転 |
| 7 | flip height + rotate 90deg : 上下反転、時計周りに90度回転 |
| 8 | rotate 270deg : 時計周りに270度回転 |
- F
- F
- F
- F
- F
- F
- F
- F
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画像処理をして表示をすれば、正常の見栄えになること間違いなしです。
扱いづらいかもしれないので、関数は適宜環境に合わせて書き直してお使いください。
考え方だけご理解いただければ幸いです。
0 件のコメント:
コメントを投稿