I am using the following code to rotate an uploaded jpeg image if the orientation is off. I am only having problems with images uploaded from iPhones and Android.
if(move_uploaded_file($_FILES['photo']['tmp_name'], $upload_path . $newfilename)){ chmod($upload_path . $newfilename, 0755); $exif = exif_read_data($upload_path . $newfilename); $ort = $exif['IFD0']['Orientation']; switch($ort) { case 3: // 180 rotate left $image->imagerotate($upload_path . $newfilename, 180, -1); break; case 6: // 90 rotate right $image->imagerotate($upload_path . $newfilename, -90, -1); break; case 8: // 90 rotate left $image->imagerotate($upload_path . $newfilename, 90, -1); break; } imagejpeg($image, $upload_path . $newfilename, 100); $success_message = 'Photo Successfully Uploaded'; }else{ $error_count++; $error_message = 'Error: Upload Unsuccessful<br />Please Try Again'; }
Am I doing something wrong with the way I am reading the EXIF data from the jpeg? It is not rotating the images as it is supposed to.
This is what happens when I run a var_dump($exif);
array(41) { ["FileName"]=> string(36) "126e7c0efcac2b76b3320e6187d03cfd.JPG" ["FileDateTime"]=> int(1316545667) ["FileSize"]=> int(1312472) ["FileType"]=> int(2) ["MimeType"]=> string(10) "image/jpeg" ["SectionsFound"]=> string(30) "ANY_TAG, IFD0, THUMBNAIL, EXIF" ["COMPUTED"]=> array(8) { ["html"]=> string(26) "width="2048" height="1536"" ["Height"]=> int(1536) ["Width"]=> int(2048) ["IsColor"]=> int(1) ["ByteOrderMotorola"]=> int(1) ["ApertureFNumber"]=> string(5) "f/2.8" ["Thumbnail.FileType"]=> int(2) ["Thumbnail.MimeType"]=> string(10) "image/jpeg" } ["Make"]=> string(5) "Apple" ["Model"]=> string(10) "iPhone 3GS" ["Orientation"]=> int(6) ["XResolution"]=> string(4) "72/1" ["YResolution"]=> string(4) "72/1" ["ResolutionUnit"]=> int(2) ["Software"]=> string(5) "4.3.5" ["DateTime"]=> string(19) "2011:09:16 21:18:46" ["YCbCrPositioning"]=> int(1) ["Exif_IFD_Pointer"]=> int(194) ["THUMBNAIL"]=> array(6) { ["Compression"]=> int(6) ["XResolution"]=> string(4) "72/1" ["YResolution"]=> string(4) "72/1" ["ResolutionUnit"]=> int(2) ["JPEGInterchangeFormat"]=> int(658) ["JPEGInterchangeFormatLength"]=> int(8231) } ["ExposureTime"]=> string(4) "1/15" ["FNumber"]=> string(4) "14/5" ["ExposureProgram"]=> int(2) ["ISOSpeedRatings"]=> int(200) ["ExifVersion"]=> string(4) "0221" ["DateTimeOriginal"]=> string(19) "2011:09:16 21:18:46" ["DateTimeDigitized"]=> string(19) "2011:09:16 21:18:46" ["ComponentsConfiguration"]=> string(4) "" ["ShutterSpeedValue"]=> string(8) "3711/949" ["ApertureValue"]=> string(9) "4281/1441" ["MeteringMode"]=> int(1) ["Flash"]=> int(32) ["FocalLength"]=> string(5) "77/20" ["SubjectLocation"]=> array(4) { [0]=> int(1023) [1]=> int(767) [2]=> int(614) [3]=> int(614) } ["FlashPixVersion"]=> string(4) "0100" ["ColorSpace"]=> int(1) ["ExifImageWidth"]=> int(2048) ["ExifImageLength"]=> int(1536) ["SensingMethod"]=> int(2) ["ExposureMode"]=> int(0) ["WhiteBalance"]=> int(0) ["SceneCaptureType"]=> int(0) ["Sharpness"]=> int(1) }
Solution 1 — Reading EXIF data The function above uses the PHP in-built exif_read_data() function to read the Orientation EXIF data from the image, and uses imagerotate and imagejpeg to recreate the image with the correct orientation.
The EXIF orientation value is used by Photoshop and other photo editing software to automatically rotate photos, saving you a manual task.
The EXIF (Exchangeable image file format) PHP extension enables to work with the metadata from the images taken by digital devices like digital cameras, cell phones, etc. It depends on the image file format. We can retrieve embedded thumbnails of images.
Based on Daniel's code I wrote a function that simply rotates an image if necessary, without resampling.
function image_fix_orientation(&$image, $filename) { $exif = exif_read_data($filename); if (!empty($exif['Orientation'])) { switch ($exif['Orientation']) { case 3: $image = imagerotate($image, 180, 0); break; case 6: $image = imagerotate($image, 90, 0); break; case 8: $image = imagerotate($image, -90, 0); break; } } }
function image_fix_orientation(&$image, $filename) { $image = imagerotate($image, array_values([0, 0, 0, 180, 0, 0, -90, 0, 90])[@exif_read_data($filename)['Orientation'] ?: 0], 0); }
function image_fix_orientation($image) { if (method_exists($image, 'getImageProperty')) { $orientation = $image->getImageProperty('exif:Orientation'); } else { $filename = $image->getImageFilename(); if (empty($filename)) { $filename = 'data://image/jpeg;base64,' . base64_encode($image->getImageBlob()); } $exif = exif_read_data($filename); $orientation = isset($exif['Orientation']) ? $exif['Orientation'] : null; } if (!empty($orientation)) { switch ($orientation) { case 3: $image->rotateImage('#000000', 180); break; case 6: $image->rotateImage('#000000', 90); break; case 8: $image->rotateImage('#000000', -90); break; } } }
The documentation for imagerotate refers to a different type for the first parameter than you use:
An image resource, returned by one of the image creation functions, such as imagecreatetruecolor().
Here is a small example for using this function:
function resample($jpgFile, $thumbFile, $width, $orientation) { // Get new dimensions list($width_orig, $height_orig) = getimagesize($jpgFile); $height = (int) (($width / $width_orig) * $height_orig); // Resample $image_p = imagecreatetruecolor($width, $height); $image = imagecreatefromjpeg($jpgFile); imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig); // Fix Orientation switch($orientation) { case 3: $image_p = imagerotate($image_p, 180, 0); break; case 6: $image_p = imagerotate($image_p, 90, 0); break; case 8: $image_p = imagerotate($image_p, -90, 0); break; } // Output imagejpeg($image_p, $thumbFile, 90); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With