それマグで!

知識はカップより、マグでゆっくり頂きます。 takuya_1stのブログ

習慣に早くから配慮した者は、 おそらく人生の実りも大きい。

画像の写真の向きを修正する@PHP

写真アップロードの際の上向きがうまく取れないか、挑戦してみた。
写真には上向き下向きや、WEBカメラの場合は左右反転させる、一口にデジカメ写真といっても様々なものがある。

Windowsのサムネイルはひどい。

Windowsのマイピクチャのサムネイルが自動回転しない。手動回転させると「劣化するよ」とお節介な警告が出る。GNOMEのNautilusだとマイピクチャはサムネイルをキチンと解釈してくれる。Ubuntuを使ってて自動補正されて驚いた。上下の補正をしてくれる。同じ写真をWindowsとnautilusでプレビューしたときにハッキリと違いが分かる。

EXIF情報を活用する。

デジカメ写真にはデータが埋め込まれている(EXIFモジュールで見られる)
デジカメに埋め込まれている、向き情報は「Orientation」配列に入っている。

Orientationの回転パターンの定義。

Orientationの値で、写真プレビュー時の処理が定義さている。

Exif-orientation-1:通常
Exif-orientation-2:左右反転
Exif-orientation-3:180°回転
Exif-orientation-4:上下反転
Exif-orientation-5:反時計回りに90°回転 上下反転
Exif-orientation-6:時計回りに90°回転
Exif-orientation-7:時計回りに90°回転 上下反転
Exif-orientation-8:反時計回りに90°回転

方向を修正する関数。

これを元に、PHPで向きを修正する関数を作ってみた。

<?php
  public function make_orientation_fixed_blob($raw)
  {
    $img = new Imagick();
    $ver = $img->getVersion();
    
    $img->readImageBlob($raw);
    $orientation = 0;
    if( method_exists($img, "getImageOrientation") ){
      $orientation = $img->getImageOrientation();
    }
    if(!$orientation && function_exists("read_exif_data")){
      $exif = read_exif_data($this->image_path("original").DIRECTORY_SEPARATOR.$this->file_name());
      $orientation = $exif['Orientation'];
    }
    switch((int)$orientation) {
      case 0:#未定義
        break;
      case 1:#通常
        break;
      case 2:#左右反転
        $img->flopImage();
        break;
      case 3:#180°回転
        $img->rotateImage(new ImagickPixel(), 180 );
        break;
      case 4:#上下反転
        $img->flipImage();
        break;
      case 5:#反時計回りに90°回転 上下反転
        $img->rotateImage(new ImagickPixel(), 270 );
        $img->flipImage();
        break;
      case 6:#時計回りに90°回転
        $img->rotateImage(new ImagickPixel(), 90 );
        break;
      case 7:#時計回りに90°回転 上下反転
        $img->rotateImage(new ImagickPixel(), 90 );
        $img->flipImage();
        break;
      case 8:#反時計回りに90°回転
        $img->rotateImage(new ImagickPixel(), 270 );
        break;
    }
    $raw = $img->getImageBlob();
    unset($img);
    return $raw;
  }

動作に必要なモジュールはImageMagick/Exif

ImageMagickのインストールの確認
$> php -r '$img = new Imagick();print_r($img->getVersion());'

ImageMagickはデフォルトインストールされていないことが多い。ImageMagickないときはGDを使えばいい。

EXIF関連の確認

これは、使えることが多い。

$> php -i | grep exif

使用例:写真の向き調整は次に場所の使用しています。

デジカメ写真をアップロード出来ると楽しいな。でも向きが正しくないので悔しかった。
ということで、画像アップロードの際に組み込んでおいた。
実際に動作させてみて特に問題はありませんでした。