Skip to content

Instantly share code, notes, and snippets.

@ostretsov
Created February 15, 2018 09:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ostretsov/0e32268df1c68c94c51a45d6e9569a28 to your computer and use it in GitHub Desktop.
Save ostretsov/0e32268df1c68c94c51a45d6e9569a28 to your computer and use it in GitHub Desktop.
class ImageUtil
{
/**
* @see https://github.com/recurser/exif-orientation-examples for test samples
*
* @param string $absoluteFilePath
* @return bool
*/
public static function fixOrientation(string $absoluteFilePath): bool
{
$ext = pathinfo($absoluteFilePath, PATHINFO_EXTENSION);
$ext = strtolower($ext);
if (!in_array($ext, ['jpg', 'jpeg', 'png', 'gif'])) {
return false;
}
if (!file_exists($absoluteFilePath)) {
return false;
}
try {
$data = self::extract($absoluteFilePath);
if (!$data || !is_array($data)) {
return false;
}
} catch (\Throwable $e) {
return false;
}
$exif = array_change_key_case($data, CASE_LOWER);
if (!array_key_exists('ifd0.orientation', $exif)) {
return false;
}
$rotatedImage = self::getImageResource($absoluteFilePath);
if (is_null($rotatedImage)) {
return false;
}
switch ($exif['ifd0.orientation']) {
// Standard/Normal Orientation (no need to do anything, we'll return true as in theory, it was successful)
case 1:
return true;
break;
// Correct orientation, but flipped on the horizontal axis (might do it at some point in the future)
case 2:
imageflip($rotatedImage, IMG_FLIP_HORIZONTAL);
break;
// Upside-Down
case 3:
$rotatedImage = imagerotate($rotatedImage, 180, 0);
break;
// Upside-Down & Flipped along horizontal axis
case 4:
$rotatedImage = imagerotate($rotatedImage, 180, 0);
imageflip($rotatedImage, IMG_FLIP_HORIZONTAL);
break;
// Turned 90 deg to the left and flipped
case 5:
$rotatedImage = imagerotate($rotatedImage, -90, 0);
imageflip($rotatedImage, IMG_FLIP_HORIZONTAL);
break;
// Turned 90 deg to the left
case 6:
$rotatedImage = imagerotate($rotatedImage, -90, 0);
break;
// Turned 90 deg to the right and flipped
case 7:
$rotatedImage = imagerotate($rotatedImage, 90, 0);
imageflip($rotatedImage, IMG_FLIP_HORIZONTAL);
break;
// Turned 90 deg to the right
case 8:
$rotatedImage = imagerotate($rotatedImage, 90, 0);
break;
default:
return false;
}
$parts = pathinfo($absoluteFilePath);
$newAbsoluteFilePath = $parts['dirname'].'/'.$parts['filename'].'.orig';
$newAbsoluteFilePath .= $parts['extension'] ? '.'.$parts['extension'] : '';
rename($absoluteFilePath, $newAbsoluteFilePath);
// Save it and the return the result (true or false)
$done = self::saveImageResource($rotatedImage, $absoluteFilePath);
return $done;
}
private static function getImageResource($absoluteFilePath)
{
$img = null;
$ext = pathinfo($absoluteFilePath, PATHINFO_EXTENSION);
$ext = strtolower($ext);
switch ($ext) {
case 'png':
$img = imagecreatefrompng($absoluteFilePath);
break;
case 'jpg':
case 'jpeg':
$img = imagecreatefromjpeg($absoluteFilePath);
break;
case 'gif':
$img = imagecreatefromgif($absoluteFilePath);
break;
}
return $img;
}
private static function saveImageResource($resource, $absoluteFilePath): bool
{
$result = false;
$ext = pathinfo($absoluteFilePath, PATHINFO_EXTENSION);
$ext = strtolower($ext);
switch ($ext) {
case 'png':
$result = imagepng($resource, $absoluteFilePath);
break;
case 'jpg':
case 'jpeg':
$result = imagejpeg($resource, $absoluteFilePath);
break;
case 'gif':
$result = imagegif($resource, $absoluteFilePath);
break;
}
return $result;
}
private static function extract($path)
{
if (false === $exifData = @exif_read_data($path, null, true, false)) {
return [];
}
$metadata = [];
$sources = ['EXIF' => 'exif', 'IFD0' => 'ifd0'];
foreach ($sources as $name => $prefix) {
if (!isset($exifData[$name])) {
continue;
}
foreach ($exifData[$name] as $prop => $value) {
$metadata[$prefix.'.'.$prop] = $value;
}
}
return $metadata;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment