1. トップ
  2. iphoneで撮影した写真がWEBで表示すると回転してしまう問題をphpとnginxで解決した

iphoneで撮影した写真アップロードすると向きおかしくなっちゃうな〜

やだな〜

かといって画像いちいち編集してアップロードしたくないな〜〜

ImageMagickなんていれたくねえな〜〜

と思ってやりました

早く知りたい人むけ

nginxのimage_filter rotate使った

公式リファレンス

 

<画像アップロード時のphp処理>

public function getRotate($file){
    $exif = @exif_read_data($file);
    $deg = 0;
    if(!empty($exif['Orientation'])){
        switch($exif['Orientation']){
            case 5:
            case 6:
                $deg = 3;// 右に270度
                break;
            case 3:
            case 4:
                $deg = 2;// 右に180度
                break;
            case 8:
            case 7:
                $deg = 1;// 右に90度
                break;
        }
    }
    return $deg;
}

$degを画像テーブルに保存。

 

<画像表示部分>

public function calcRotateDeg($deg){
    return ($deg * 90);
}

<img src=”/resize/400x400_/hoge.jpg”>

 

<nginxのconf>

location ~ ^/resize/(?\d+)x(?\d+)_(?\d+)/(?.*)$ {
    proxy_cache $cache_name;
    proxy_cache_key $scheme//$host$request_uri$is_args$args;
    proxy_cache_valid  200 7d;
    proxy_cache_valid  404 1m;
    proxy_cache_valid  500 5s;

    image_filter_buffer 50M;
    image_filter resize $width $height;
    image_filter rotate $rotate;
    image_filter_jpeg_quality 90;

    rewrite ^/resize/(\d+)x(\d+)\_(\d+)/(.*)$ /$4 break;
    proxy_pass http://blog;
}

ゆっくりできる人むけ

前提

まず前提として、このブログの構造はDBに画像テーブルがあり、その画像idを記事テーブルに突っ込んで紐付けております(sqlite)

 

<画像テーブルスキーマ>

CREATE TABLE image (
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    status BOOLEAN default true,
    origin_name TEXT,
    name TEXT,
    path TEXT,
    width INTEGER,
    height INTEGER,
    fsize INTEGER,
    mime_type TEXT,
    sumbinary TEXT,
    alt TEXT,
    rotate_deg INTEGER default 0
);

nginxのimage_filter rotateについて

image_filterモジュールは使用できるようになっているのを前提に書きます。

image_filterモジュールについてはこっち

 

簡単に書くとimage_filterは画像に対していろいろ処理できる便利なやつ。

その便利のなかに回転させる機能もついてる。

回転できるのは時計回りに90℃、180℃、270℃のみ。

なのでアップロードした画像ごとに、何℃回転が必要なのかをnginxに教えてあげる必要があり、それをするのがphp側。

php側で必要な処理

画像のアップロード処理はphpでやっているので、それに加えて画像ファイルの向きがどうなっているかを判定し、前述の画像テーブルに保存する。

画像ファイルの向きというのは、画像ファイルのEXIF情報に書いてあるんだけど、それを読んでくれるphpの関数があるからそれを使う。

exif_read_data - Manual - PHP

 

public function getRotate($file){
    $exif = @exif_read_data($file);
    $deg = 0;
    if(!empty($exif['Orientation'])){
        switch($exif['Orientation']){
            case 5:
            case 6:
                $deg = 3;// 右に270度
                break;
            case 3:
            case 4:
                $deg = 2;// 右に180度
                break;
            case 8:
            case 7:
                $deg = 1;// 右に90度
                break;
        }
    }
    return $deg;
}

 

これで取得した$degを画像テーブルに保存し、画像表示側は

に変更する

これで無事に、iphoneで撮影した写真をWEBにアップロードしても、写真の向きが正常になりました、というお話でした