2
votes

I'm using the Imagick libray in PHP to do some some image manipulation with imagemagick. The user uploads an photo, I resize it, and then use the compositeImage function to place a transparent PNG layer over it. The code looks roughly like this:

$image = new Imagick($imagepath);
$overlay = new Imagick("filters/photo-filter-flat.png");

$geo = $image->getImageGeometry();

if ($geo['height'] > $geo['width']) {
    $image->scaleImage(0, 480);
} else {
    $image->scaleImage(320, 0);
}

$image->compositeImage($overlay, imagick::COMPOSITE_ATOP, 0, 0);

return $image;

So the strange thing is, with some photos the overlay gets rotated 90 degrees when it's placed on top. I'm thinking this has to do with different file formats, is there an accepted way to normalize images before you composite them to prevent this?

1
that's.... weird. Are you sure they're actually not rotated like that to begin with. Ie maybe the exif data has the rotation and your image viewer is 'fixing' it?Hamish
@Hamish +1 good call.Orangepill
The really weird thing is, the photo is always oriented corrected regardless of how I open it. The PNG I created as an overlay is what gets rotated ... sometimes. The photos this happens with are created from my smartphone.FriendOfFuture
bizarre. maybe imagik is doing something clever with the exif. does it have any metadata?Hamish
There's some meta-data, nothing related to orientation. Check this out: Photoshop "Save for Web" corrects the issue. Using the Imagick "stripImage" function makes is so the image is rotated and the overlay is oriented correctly. I feel like I'm taking crazy pills, I'm sure someone who knows image formats well could tell me what this issue was in 2 seconds.FriendOfFuture

1 Answers

0
votes

So it turns out it was the issue was exif orientation value. There's some good information about the topic in general here: http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/.

Basically you have to resolve the image's orientation before you composite it. There's a good function in the comments on the PHP documentation site: http://www.php.net/manual/en/imagick.getimageorientation.php

// Note: $image is an Imagick object, not a filename! See example use below. 
    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); 
}