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/