I try to autorotate some images from a zip with php. For the autorotate I'am using the Exif:Orientation informations of the image.
The code does work, but I have problems with some images which seems to have wrong exif informations. I have this problem only with images taken by an iPhone..
What my Code do:
The function "autoRotateImage" only handle the exif orientation and do the correct steps for each.
Parts of the php code:
try{
$img_content = $zip->getFromIndex($zip->locateName($img->getAttribute('xlink:href')));
$tmpPic = tempnam(sys_get_temp_dir(), $img->getAttribute('xlink:href'));
file_put_contents($tmpPic,$img_content);
$imagick_img = new \Imagick();
$imagick_img->readImageBlob($img_content);
if (PNGMetadata::isPNG($tmpPic)){
$png_metadata = new PNGMetadata($tmpPic);
$orientation_arr[$img->getAttribute('xlink:href')] = $png_metadata->get('exif:IFD0:Orientation');
$org_orientation = $png_metadata->get('exif:IFD0:Orientation');
}else{
$orientation_arr[$img->getAttribute('xlink:href')] = intval($imagick_img->getImageProperty('Exif:Orientation'));
$org_orientation = intval($imagick_img->getImageProperty('Exif:Orientation'));
}
autoRotateImage($imagick_img,new \Imagick(),(isset($manualOrientation[$img->getAttribute('xlink:href')]) ? $manualOrientation[$img->getAttribute('xlink:href')] : $org_orientation));
$imagick_img->clear();
unlink($tmpPic);
}catch(Exception $e){
if(isset($imagick_img)){$imagick_img->clear();}
if(isset($tmpPic)){unlink($tmpPic);}
}
autoRotateImage function:
function autoRotateImage(&$image, $imagick, $orientation) {
switch($orientation) {
case $imagick::ORIENTATION_BOTTOMRIGHT: //3
$image->rotateimage("#000", 180); // rotate 180 degrees
break;
case $imagick::ORIENTATION_BOTTOMLEFT: //4
$image->flipImage(); // mirror vertical
break;
case $imagick::ORIENTATION_RIGHTTOP: //6
$image->rotateimage("#000", 90); // rotate 90 degrees CW
break;
case $imagick::ORIENTATION_LEFTTOP: //5
$image->transverseImage(); // horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.
break;
case $imagick::ORIENTATION_LEFTBOTTOM: //8
$image->rotateimage("#000", 270); // rotate 270 degrees CW
break;
case $imagick::ORIENTATION_RIGHTBOTTOM: //7
$image->transverseImage(); //horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.
$image->rotateimage("#000", -180); // rotate 180 degrees CCW
break;
case $imagick::ORIENTATION_TOPLEFT: //1
//Nothing to do
break;
case $imagick::ORIENTATION_TOPRIGHT: //2
$image->transverseImage(); //horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.
$image->rotateimage("#000", 90); // rotate 90 degrees CW
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);
}
The class "PNGMetadata" is from someone else: https://github.com/joserick/PNGMetadata
So.. this code works fine for like 90% of handled images, except some iPhone images. Current case: Exif Orientation says 5 (mirror at y and turn 270 CW), but it should be 7 (mirror at y and turn 90 CW)
Maybe someone have an idea how to handle those cases?
I already tried to get the exif information in other forms, but the result is everytime the same. Also an commandline exif reader read the wrong exif orientation out of the faulty images.
I need a way to fix the wrong orientations..
It seems that the imagick function "transverseImage()" doesn't work as aspected.. I don't know exactly what it do, but I think the behaviour of it doesn't fit the description..
The desc says "Creates a horizontal mirror image by reflecting the pixels around the central y-axis while rotating them 270-degrees.". For me that means, that the Image get mirrored and after that rotated by 270°CW. But Images will be false rotated after that func.
I tried "Imagick::flopImage" in combination with rotateImage(270) and get different results.
Short: I replaced transverseImage with flopImage + rotateImage and now it seems, that the Images getting rotated correctly.