Help us understand the problem. What is going on with this article?

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

More than 1 year has 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/

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
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  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
ユーザーは見つかりませんでした