Detect EXIF Orientation and Rotate Image using ImageMagick - php

Canon DSLRs appear to save photos in landscape orientation and uses exif::orientation to do the rotation.
Question: How can imagemagick be used to re-save the image into the intended orientation using the exif orientation data such that it no longer requires the exif data to display in the correct orientation?

Use the auto-orient option of ImageMagick's convert to do this.
convert your-image.jpg -auto-orient output.jpg
Or use mogrifyto do it in place
mogrify -auto-orient your-image.jpg

The PHP Imagick way would be to test the image orientation and rotate/flip the image accordingly:
function autorotate(Imagick $image)
{
switch ($image->getImageOrientation()) {
case Imagick::ORIENTATION_TOPLEFT:
break;
case Imagick::ORIENTATION_TOPRIGHT:
$image->flopImage();
break;
case Imagick::ORIENTATION_BOTTOMRIGHT:
$image->rotateImage("#000", 180);
break;
case Imagick::ORIENTATION_BOTTOMLEFT:
$image->flopImage();
$image->rotateImage("#000", 180);
break;
case Imagick::ORIENTATION_LEFTTOP:
$image->flopImage();
$image->rotateImage("#000", -90);
break;
case Imagick::ORIENTATION_RIGHTTOP:
$image->rotateImage("#000", 90);
break;
case Imagick::ORIENTATION_RIGHTBOTTOM:
$image->flopImage();
$image->rotateImage("#000", 90);
break;
case Imagick::ORIENTATION_LEFTBOTTOM:
$image->rotateImage("#000", -90);
break;
default: // Invalid orientation
break;
}
$image->setImageOrientation(Imagick::ORIENTATION_TOPLEFT);
}
The function might be used like this:
$img = new Imagick('/path/to/file');
autorotate($img);
$img->stripImage(); // if you want to get rid of all EXIF data
$img->writeImage();

Related

Imagemagick does not set image to exact sizes

I have an image that i want to set to 1024 x 768 and this is the code i am using
<?php
function autoRotateImage($image) {
$orientation = $image->getImageOrientation();
switch($orientation) {
case imagick::ORIENTATION_BOTTOMRIGHT:
$image->rotateimage("#000", 180); // rotate 180 degrees
break;
case imagick::ORIENTATION_RIGHTTOP:
$image->rotateimage("#000", 90); // rotate 90 degrees CW
break;
case imagick::ORIENTATION_LEFTBOTTOM:
$image->rotateimage("#000", -90); // rotate 90 degrees CCW
break;
}
// Now that it's auto-rotated, make sure the EXIF data is correct in case the EXIF gets saved with the image!
$image->setImageOrientation(imagick::ORIENTATION_TOPLEFT);
}
$image = 'C:\xampp\htdocs\uncompressed_images\20221016_120159.jpg';
// Create new Imagick Object
$imagick = new Imagick($image);
// Set the Compression to COMPRESSION_JPEG
$imagick->setImageCompression(imagick::COMPRESSION_JPEG);
// Set the Compression quality
// This is where that compression method imagick::COMPRESSION_JPEG is
// used in the program.
$imagick->setImageCompressionQuality(26);
$imagick->thumbnailImage(1024,768);
autoRotateImage($imagick);
// Show the output
$imagick->setformat('jpg');
$imagick->writeImage($image);
header("Content-Type: image/jpg");
echo $imagick->getImageBlob();
?>
However the output image is always 768 x 1024 How can i have the resulting to be 1024 x 768?
How can i also write image to a specific directory in this line $imagick->writeImage($image); i.e output directory
You should use autoRotateImage to fix any orientation issue first (so now the image is in right orientation) , and then apply thumbnailImage for resizing
So change
$imagick->thumbnailImage(1024,768);
autoRotateImage($imagick);
to
autoRotateImage($imagick);
$imagick->thumbnailImage(1024,768);

PHP imagecreatefromjpeg while keeping orientation

I have been working on my image upload website. I am trying to take pictures from my IPhone and upload them to my web server.
My files are uploading fine, However the problem i am running into is all of my images rotate 90 degrees to the left.
My Image upload process
$imageObject = imagecreatefromjpeg($_FILES["fileToUpload"]["tmp_name"]);
imagejpeg($imageObject, $target_file, 75);
Creating a new image and uploading it to my web directory. I create a new image to remove all of the EXIF Data (GPS location, all of my personal information)
The problem is that when i upload the image it does not save the file in portrait orientation (6). It doesn't actually save ANY orientation information. This being an obvious side effect of imagecreatefromjpeg. But all of my portrait style images save as landscape format.
My question is, is there any way for me to simply re-write the orientation Data into the NEW image after it is saved to my server?
Thank you all for your time!
You can read the exif information and use that to rotate or flip your image. Then you don't need the orientation data anymore.
Something like:
$imageObject = imagecreatefromjpeg($_FILES["fileToUpload"]["tmp_name"]);
# Get exif information
$exif = exif_read_data($_FILES["fileToUpload"]["tmp_name"]);
# Add some error handling
# Get orientation
$orientation = $exif['Orientation'];
# Manipulate image
switch ($orientation) {
case 2:
imageflip($imageObject, IMG_FLIP_HORIZONTAL);
break;
case 3:
$imageObject = imagerotate($imageObject, 180, 0);
break;
case 4:
imageflip($imageObject, IMG_FLIP_VERTICAL);
break;
case 5:
$imageObject = imagerotate($imageObject, -90, 0);
imageflip($imageObject, IMG_FLIP_HORIZONTAL);
break;
case 6:
$imageObject = imagerotate($imageObject, -90, 0);
break;
case 7:
$imageObject = imagerotate($imageObject, 90, 0);
imageflip($imageObject, IMG_FLIP_HORIZONTAL);
break;
case 8:
$imageObject = imagerotate($imageObject, 90, 0);
break;
}
# Write image
imagejpeg($imageObject, $target_file, 75);
Create Image maintains Aspect Ratio:
Answer is Here

Php Image Rotation in Google App Enggine

I am trying to fix orientation of images from mobile devices, using EXIF to get the orientation and switch/case to fix the orientation. Apparently my function was working offline and now it's not working on Google Apps Engine. Could Google have a specific function to do this?
The function:
$image = imagecreatefromjpeg($path);
$exif = exif_read_data($path);
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;
}
imagejpeg($image, $path);
}

Image is rotated correctly on mobile device, not on desktop

I'm having a weird issue with my uploaded images. They're rotated correctly when I view them on iPhones and iPads, but whenever I try to view them on desktop, they're displayed with their wrong orientation.
I can't find the error, and after spending hours messing with the EXIF data I'm close to giving up.
After fixing the orientation, I'm also resizing the images, but that shouldn't interfere with the other code. In case it does, I'm including it.
I don't have enough reputation to upload images, but here's a link to them:
http://i.imgur.com/ARwSUuV.png
http://i.imgur.com/00yj7OJ.png
Here's the code I'm using to upload:
$path_parts = pathinfo($_FILES["file"]["name"]);
$filepath = $_FILES['file']['tmp_name'];
$image = imagecreatefromstring(file_get_contents($filepath));
// Rotate image correctly!
$exif = exif_read_data($image);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']){
case 1: // nothing
break;
case 2: // horizontal flip
$image = imageflip($image, IMG_FLIP_HORIZONTAL);
break;
case 3: // 180 rotate left
$image = imagerotate($image,180,0);
break;
case 4: // vertical flip
$image = imageflip($image, IMG_FLIP_VERTICAL);
break;
case 5: // vertical flip + 90 rotate right
$image = imageflip($image, IMG_FLIP_VERTICAL);
$image = imagerotate($image,-90,0);
break;
case 6: // 90 rotate right
$image = imagerotate($image,-90,0);
break;
case 7: // horizontal flip + 90 rotate right
$image = imageflip($image, IMG_FLIP_HORIZONTAL);
$image = imagerotate($image,-90,0);
break;
case 8: // 90 rotate left
$image = imagerotate($image,90,0);
break;
}
}
switch ($path_parts['extension']) {
case 'gif' :
$im = imagecreatefromgif($image);
break;
case 'jpg' :
$im = imagecreatefromjpeg($image);
break;
case 'png' :
$im = imagecreatefrompng($image);
break;
case 'bmp' :
$im = imagecreatefrombmp($image);
break;
}
if($im){
imagejpeg($im, $_FILES['file']['tmp_name'], 40);
}
$image_path = 'd_'.time() . "." . $path_parts['extension'];
$move_result = move_uploaded_file($_FILES['file']['tmp_name'], '../img/results/' . $image_path);
If you have any idea why it's only rotating correctly on some platforms, I'd be very grateful!
EDIT: Should probably clarify that images will most often be uploaded from smartphones or tablets.
There are some errors that stop the code working. Try turning on error reporting to help you debug problems like this.
exif_read_data() works on a file, not a GD resource, so pass $filepath instead of $image.
imageflip() manipulates the resource directly and returns a bool so assigning the return value to $image destroys the resource.
The second switch() statement isn't needed at all. The imagecreatefrom___() functions create a resource from a file, but you're passing them an already created resource - all you want to do is output it.
Otherwise the orientation correction seems accurate and should work for you (it does on the various test photos I took with my phone).
Here's the corrected code:
$path_parts = pathinfo($_FILES["file"]["name"]);
$filepath = $_FILES['file']['tmp_name'];
$image = imagecreatefromstring(file_get_contents($filepath));
// Rotate image correctly!
$exif = exif_read_data($filepath);
if (!empty($exif['Orientation'])) {
switch ($exif['Orientation']) {
case 1: // nothing
break;
case 2: // horizontal flip
imageflip($image, IMG_FLIP_HORIZONTAL);
break;
case 3: // 180 rotate left
$image = imagerotate($image, 180, 0);
break;
case 4: // vertical flip
imageflip($image, IMG_FLIP_VERTICAL);
break;
case 5: // vertical flip + 90 rotate right
imageflip($image, IMG_FLIP_VERTICAL);
$image = imagerotate($image, -90, 0);
break;
case 6: // 90 rotate right
$image = imagerotate($image, -90, 0);
break;
case 7: // horizontal flip + 90 rotate right
imageflip($image, IMG_FLIP_HORIZONTAL);
$image = imagerotate($image, -90, 0);
break;
case 8: // 90 rotate left
$image = imagerotate($image, 90, 0);
break;
}
}
imagejpeg($image, $_FILES['file']['tmp_name'], 40);
$image_path = 'd_'.time() . "." . $path_parts['extension'];
$move_result = move_uploaded_file($_FILES['file']['tmp_name'], '../img/results/' . $image_path);

Thumbnail creation path error

I am uploading image with uploadify V2.1.4. After uploading image I am trying to create thumbnails of size 60x60 and 80x80 in uploadify.php file. Thumbnails are get created for jpg, png, gif file type. But it is not created when file type is jpeg.
$imgsize = getimagesize($targetFile);
switch(strtolower(substr($targetFile, -3)))
{
case "jpeg":
case "jpg":
$image = imagecreatefromjpeg($targetFile);
break;
case "png":
$image = imagecreatefrompng($targetFile);
break;
case "gif":
$image = imagecreatefromgif($targetFile);
break;
default:
exit;
break;
}
$width = 60; //New width of image
$height=60;
$src_w = $imgsize[0];
$src_h = $imgsize[1];
$picture = imagecreatetruecolor($width, $height);
imagealphablending($picture, false);
imagesavealpha($picture, true);
$bool = imagecopyresampled($picture, $image, 0, 0, 0, 0, $width, $height, $src_w, $src_h);
$image_name='';
if($bool)
{
$image_name=$newf_name;
$parts=explode('.',$newf_name);
$newf_name=$parts[0]."_90X90.".$parts[1];
switch(strtolower(substr($targetFile, -3)))
{
case "jpeg":
case "jpg":
header("Content-Type: image/jpeg");
$bool2 = imagejpeg($picture,$path."thumb/".$newf_name,80);
break;
case "png":
header("Content-Type: image/png");
imagepng($picture,$path."thumb/".$newf_name);
break;
case "gif":
header("Content-Type: image/gif");
imagegif($picture,$path."thumb/".$newf_name);
break;
}
}
The the operation system of the computer where you uploading your images from is absolutely irrelevant.
Instead of posting the code here you have to debug it yourself.
There is very little sense in posting code here. You will get but some wild guesses, mostly irrelevant to your case.
So, you have to make your code to tell you what is going wrong. this is called debugging and being the most important programmer's skill.
First of all you have to be sure, that you will be informed of all errors occurred.
add these lines at hthe top of your code
ini_set('display_errors',1);
error_reporting(E_ALL);
and see if if it says something.
if not - trace your program step by step.
add some exit's in your code along with printing relevant variables contents to check if they have desired value.
If you're using codeigniter (as it's been tagged) why not use codeigniter's image manipulation class?
http://codeigniter.com/user_guide/libraries/image_lib.html
It's really simple and theres plenty of documentaion to upload images and create thumbs!

Categories