Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
8
Help us understand the problem. What is going on with this article?
@yoshu

PHPでEXIFのOrientationを元に画像を回転

More than 3 years have passed since last update.

EXIFのOrientationを見て画像を回転させる処理です。
訳あってPHP5系で実装しましたが、PHP7系でも動くと思います。

注意点としては、rotate()関数内でメモリを大量に使用するためmemory_limit()で上限を上げています。
「allowed memory size」が発生するケースもあったので、余裕をもって設定しましょう。
※ 1.7MBの画像で128MBを使い切ったケースがありました。

このあたりでメモリ使用量が一気に上昇します。
imagecreatefromstring()
imagerotate()
imagejpeg()
imagepng()
imagegif()

Image.php
<?php
class Image {

    /**
     * 画像(バイナリ)のEXif情報を元に回転する
     */
    public function rotateFromBinary($binary) {
        $exif_data = $this->getExifFromBinary($binary);
        if (empty($exif_data['Orientation']) || in_array($exif_data['Orientation'], [1, 2])) {
            return $binary;
        }
        return $this->rotate($binary, $exif_data);
    }

    /**
     * バイナリデータからexif情報を取得
     */
    private function getExifFromBinary($binary) {
        $temp = tmpfile();
        fwrite($temp, $binary);
        fseek($temp, 0);

        $meta_data = stream_get_meta_data($temp);
        $exif_data = @exif_read_data($meta_data['uri']);

        fclose($temp);
        return $exif_data;
    }

    /**
     * 画像を回転させる
     */
    private function rotate($binary, $exif_data) {
        ini_set('memory_limit', '256M');

        $src_image = imagecreatefromstring($binary);

        $degrees = 0;
        $mode    = '';
        switch($exif_data['Orientation'])
        {
            case 2: // 水平反転
                $mode = IMG_FLIP_VERTICAL;
                break;
            case 3: // 180度回転
                $degrees = 180;
                break;
            case 4: // 垂直反転
                $mode = IMG_FLIP_HORIZONTAL;
                break;
            case 5: // 水平反転、 反時計回りに270回転
                $degrees = 270;
                $mode    = IMG_FLIP_VERTICAL;
                break;
            case 6: // 反時計回りに270回転
                $degrees = 270;
                break;
            case 7: // 反時計回りに90度回転(反時計回りに90度回転) 水平反転
                $degrees = 90;
                $mode    = IMG_FLIP_VERTICAL;
                break;
            case 8: // 反時計回りに90度回転(反時計回りに90度回転)
                $degrees = 90;
                break;
        }

        if (!empty($mode))
        {
            imageflip($src_image, $mode);
        }
        if ($degrees > 0)
        {
            $src_image = imagerotate($src_image, $degrees, 0);
        }

        ob_start();
        if (empty($exif_data['MimeType']) || $exif_data['MimeType'] == 'image/jpeg') {
            imagejpeg($src_image);
        } elseif ($exif_data['MimeType'] == 'image/png') {
            imagepng($src_image);
        } elseif ($exif_data['MimeType'] == 'image/gif') {
            imagegif($src_image);
        }
        imagedestroy($src_image);
        return ob_get_clean();
    }
 }

// 使い方
$Image = new Image();
$binary = $Image->rotateFromBinary(file_get_contents($path_to_file));

参考URL

http://php.o0o0.jp/article/php-orientation
http://blog.diginnovation.com/archives/1104/

8
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
yoshu

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
8
Help us understand the problem. What is going on with this article?