iPhoneやiPadで撮影した画像を他のデバイスで見ると自動で回転してしまう場合の対処法

先日WordPressでギャラリープラグイン「Nextgen Gallery」を利用してサイトを構築した際に、対処するのに苦労した問題が表題のケースだ。
具体的には、iPhoneやiPadといったiOS系のデバイスで撮影された画像がアップロードされた場合、(iOSに標準搭載された)Safari以外のブラウザでそのアップロード画像を表示すると、意図しない方向に回転されて表示されてしまうという症状。
原因は、iOSで撮影された写真では専用のExif(写真に付与される撮影状態のメタ情報)が付与され、端末を縦方向にして撮影しても、横向きで表示した際に最適化されるようにExifが付与されてしまうのだ。iOS端末で撮影した写真をそのままiOS端末で閲覧する際には端末側でそのExifを自動解釈してくれるので、問題なく表示されるのだが、iOS以外の端末(PCやAndroid端末)などでその画像を表示してしまうと、意図しない方向に回転してしまい、正常な表示が行えないことがあるのだ。
実際には、撮影画像の向きと、アップロード後に他デバイスで表示した場合の向きは、下記のようになっている。

撮影時の端末の向き Orientation 補正の対処法
6(Rotate 90 CW) 時計回りに90°回転させる
8(Rotate 270 CW) 時計回りに180°回転させる
3(Rotate 180) 反時計回りに90°回転させる
1(Horizontal (normal)) 回転させない(そのまま表示する)

※ 対処法はWordPressの「NextGen Gallery」プラグイン(ImageMagick利用時)準拠での補正方法になります。

実際の対応方法としては、画像がアップロードされた際に、上記の表に合わせて、Orientation値に基づいて画像を回転させてしまい、特定デバイスで悪さをしないように、Exif情報も削除してしまうという方法だ。
また、2013年3月25日現在の最新バージョン「NextGen Gallery 1.9.12」のプラグイン内のImageMagickライブラリ「lib/imagemagick.inc.php」には根本的にimagemagickのコマンド部分にバグがあって、convertコマンドが正常に動いていなかった。
具体的には、ImageMagickのコマンドの記述順として、「convert (画像処理コマンド) (オリジナル画像ファイル名) (画像処理後ファイル名)」という書式にてコマンドが実行されないといけないのだが、該当のライブラリ(クラス)での記述順は「convert (オリジナル画像ファイル名) (画像処理コマンド) (画像処理後ファイル名)」となっているのだ。なので、WordPressの管理パネルで画像ライブラリにImageMagickを設定しても画像処理が行われずに登録されたり表示されたりしてしまう次第。
そこで今回は、このコマンドを正常化しつつ、iOSで撮影・アップロードされた画像を全てのクライアントで正常に表示されるように修正してみたので、その手順をナレッジとして残しておく。
まず、「lib/imagemagick.inc.php」の画像回転処理をiOSで撮影された画像向けに最適化する。
[php firstline=”374″]
function rotateImage($dir = ‘CW’) {
if($dir == ‘CW’){
$angle = 90;
}else if($dir == ‘CCW’){
$angle = -90;
}else if((int)$dir == 180){
$angle = 180;
}else{
$angle = ”;
}
if(!empty($angle)){
if(strpos($this->imageMagickExec, ‘-strip’) === false){
$this->imageMagickExec .= ‘ -rotate "’. $angle .’>" ‘;
$this->imageMagickExec .= ‘-strip ‘;
}
}
$newWidth = $this->currentDimensions[‘height’];
$newHeight = $this->currentDimensions[‘width’];
$this->currentDimensions[‘width’] = $newWidth;
$this->currentDimensions[‘height’] = $newHeight;
}
[/php]
※ImageMagickの「-strip」オプションは画像のExif情報を削除することができる。

次に、convertコマンドを生成する処理の記述順を修正する。
[php firstline=”584″]
function show( $quality = 85, $name = ”) {
//save the image if we get a filename
if( $name != ” ) {
$args = "{$this->imageMagickBefore} ";
$args .= " $this->imageMagickExec $this->imageMagickComp -quality ‘$quality’ ";
$args .= escapeshellarg("$this->fileName");
$args .= ‘ ‘ . escapeshellarg("$name");
//$args = "{$this->imageMagickBefore} ‘$this->fileName’ $this->imageMagickExec $this->imageMagickComp -quality $quality ‘$name’";
$this->execute(‘convert’, $args);
//$this->error = true;
} else {
//return a raw image stream
$args = "{$this->imageMagickBefore} $this->imageMagickExec $this->imageMagickComp -quality $quality JPG:- ‘$this->fileName’";
//$args = "{$this->imageMagickBefore} ‘$this->fileName’ $this->imageMagickExec $this->imageMagickComp -quality $quality JPG:-";
$this->execute(‘convert’, $args, true);
$this->error = true;
}
}
[/php]
これで、iOS端末で撮影された画像もどんなデバイスで見ても正常な向きで表示されるようになる。