[hello world 動かない ][検索]

プログラミング関連で自分が調べた事をメモる

画像 アップロード 回転 Exif

画像ファイルの向きを調整する

iPhoneで撮った画像をアップロードし、サーバーに保存後iPhone、PCのfirefoxで表示してみると
画像の向きが異なる。
撮影した画像ファイルにExifが埋め込まれており、ブラウザによってこのExifを元に画像の向きを調整するかしないかの動作が異なるらしい。

ExifのOrientationと言うタグの中に1~8までの数値が設定されており、
この値を元にサーバー側のPHPで反転や回転を行い画像を調整し、画像を保存し直す。

Orientationの値を取得する
$exif = exif_read_data($file_name, 'EXIF');
$exif['Orientation'];

これだけでOK
のはずだったのだけど、今回使う環境ではExifが使えなかったので、
javascriptでOrientationを取得する方法に変更する。

exif-jsと言う便利なライブラリがあったので利用させて頂く。
https://github.com/jseidelin/exif-js

$('#file').change(function() {
  setExifOrientation(this.files[0]);
});

var setExifOrientation = function(imageFile) {
  EXIF.getData(imageFile, function() {
    $('#orientation').val(imageFile.exifdata.Orientation);
  });
};

画像ファイル設定時にFormにOrientationの値を埋め込んで一緒に送信


後は、受け取ったサーバー側で画像を調整。
主に下記のサイトを参考にさせて頂き、ちょこっと修正。php.o0o0.jp

private function imageRotation($file_name, $orientation)
{
    // 存在チェック
    if (! file_exists($file_name)) {
        exit;
    }

    // 読み込み
    $im = imagecreatefromjpeg($file_name);

    $degrees = 0;
    $mode = '';

    switch($orientation) {
        case 1: // 通常
            break;
        case 2: // 水平反転
            $mode = 'IMG_FLIP_VERTICAL';
            break;
        case 3: // 180°回転
            $degrees = 180;
            break;
        case 4: // 垂直反転
            $mode = 'IMG_FLIP_HORIZONTAL';
            break;
        case 5: // 水平反転、 時計回りに90°回転(反時計回りに270°回転)
            $degrees = 270;
            $mode = 'IMG_FLIP_VERTICAL';
            break;
        case 6: // 時計回りに90°回転(反時計回りに270°回転)
            $degrees = 270;
            break;
        case 7: // 時計回りに270°回転(反時計回りに90°回転) 水平反転
            $degrees = 90;
            $mode = 'IMG_FLIP_VERTICAL';
            break;
        case 8: // 時計回りに270°回転(反時計回りに90°回転)
            $degrees = 90;
            break;
    }

    // 反転
    if (! empty($mode)) {
        $im = imageflip($im, $mode);
    }

    // 回転
    if ($degrees > 0) {
        $im = imagerotate($im, $degrees, 0);
    }

    // 保存
    imagejpeg($im, $file_name, 100);

    // メモリの解放
    imagedestroy($im);
}