php resizing image on upload rotates the image when i don't want it to

14,510

Solution 1

The EXIF data is probably being ignored by this basic script.

Investigate whether your images have embedded rotation information using exif_read_data, and then auto-correct the rotation with a function like this.

In your case,

  1. take the script I just linked,
  2. paste it above the first line of your code,
  3. change all the $image-> bits to $resizeObj->
    (vim-style grep: %s/image->/resizeObj->/g)

Solution 2

This is my code, resize image and don't rotates images with exif inside

PHP must be enabled: extension=php_mbstring.dll extension=php_exif.dll if error, See more: PHP:exif_read_data() not defined

function CreateThumbnail($pic,$thumb,$thumbwidth, $quality = 100)
{

        $im1=ImageCreateFromJPEG($pic);

        //if(function_exists("exif_read_data")){
                $exif = exif_read_data($pic);
                if(!empty($exif['Orientation'])) {
                switch($exif['Orientation']) {
                case 8:
                    $im1 = imagerotate($im1,90,0);
                    break;
                case 3:
                    $im1 = imagerotate($im1,180,0);
                    break;
                case 6:
                    $im1 = imagerotate($im1,-90,0);
                    break;
                } 
                }
        //}
        $info = @getimagesize($pic);

        $width = $info[0];

        $w2=ImageSx($im1);
        $h2=ImageSy($im1);
        $w1 = ($thumbwidth <= $info[0]) ? $thumbwidth : $info[0]  ;

        $h1=floor($h2*($w1/$w2));
        $im2=imagecreatetruecolor($w1,$h1);

        imagecopyresampled ($im2,$im1,0,0,0,0,$w1,$h1,$w2,$h2); 
        $path=addslashes($thumb);
        ImageJPEG($im2,$path,$quality);
        ImageDestroy($im1);
        ImageDestroy($im2);
}

Solution 3

When you take a picture your phone saves any rotation metadata in EXIF headers. When you upload the image to your server, that metadata is still sitting there but it's your job to apply it to the image to rotate it (if you want). In PHP you can use a function called exif_read_data:

function correctImageOrientation($filename)
{
    $exif = exif_read_data($filename);
    if ($exif && isset($exif['Orientation'])) {
        $orientation = $exif['Orientation'];
        if ($orientation != 1) {
            $img = imagecreatefromjpeg($filename);
            $deg = 0;
            switch ($orientation) {
                case 3:
                    $deg = 180;
                    break;
                case 6:
                    $deg = 270;
                    break;
                case 8:
                    $deg = 90;
                    break;
            }
            if ($deg) {
                $img = imagerotate($img, $deg, 0);
            }
            imagejpeg($img, $filename, 95);
        }
    }
}

To use the function as-is simply call it after you save the file. For more info and an additional PHP solution see the original source.

Share:
14,510
neeko
Author by

neeko

Updated on June 25, 2022

Comments

  • neeko
    neeko almost 2 years

    I Have an upload script that resizes the images uploaded, however, some images are being saved as a rotated image when i dont want them to, any way to preserve the original image direction?

     if (($resizeObj->width > 400) || ($resizeObj->height > 600)){
    
        // *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
        $resizeObj -> resizeImage(400, 400, 'crop');
    
        // *** 3) Save image
        $resizeObj -> saveImage($path, 95);
    
        }
    

    this is my class file:

     <?php
    
       # ========================================================================#
       #
       #  Author:    Jarrod Oberto
       #  Version:   1.0
       #  Date:      17-Jan-10
       #  Purpose:   Resizes and saves image
       #  Requires : Requires PHP5, GD library.
       #  Usage Example:
       #                     include("classes/resize_class.php");
       #                     $resizeObj = new resize('images/cars/large/input.jpg');
       #                     $resizeObj -> resizeImage(150, 100, 0);
       #                     $resizeObj -> saveImage('images/cars/large/output.jpg', 100);
       #
       #
       # ========================================================================#
    
    
            Class resize
            {
                // *** Class variables
                private $image;
                public $width;
                public $height;
                private $imageResized;
    
                function __construct($fileName)
                {
                    // *** Open up the file
                    $this->image = $this->openImage($fileName);
    
                    // *** Get width and height
                    $this->width  = imagesx($this->image);
                    $this->height = imagesy($this->image);
                }
    
                ## --------------------------------------------------------
    
                private function openImage($file)
                {
                    // *** Get extension
                    $extension = strtolower(strrchr($file, '.'));
    
                    switch($extension)
                    {
                        case '.jpg':
                        case '.jpeg':
                            $img = @imagecreatefromjpeg($file);
                            break;
                        case '.gif':
                            $img = @imagecreatefromgif($file);
                            break;
                        case '.png':
                            $img = @imagecreatefrompng($file);
                            break;
                        default:
                            $img = false;
                            break;
                    }
                    return $img;
                }
    
                ## --------------------------------------------------------
    
                public function resizeImage($newWidth, $newHeight, $option="auto")
                {
                    // *** Get optimal width and height - based on $option
                    $optionArray = $this->getDimensions($newWidth, $newHeight, $option);
    
                    $optimalWidth  = $optionArray['optimalWidth'];
                    $optimalHeight = $optionArray['optimalHeight'];
    
    
                    // *** Resample - create image canvas of x, y size
                    $this->imageResized = imagecreatetruecolor($optimalWidth, $optimalHeight);
                    imagecopyresampled($this->imageResized, $this->image, 0, 0, 0, 0, $optimalWidth, $optimalHeight, $this->width, $this->height);
    
    
                    // *** if option is 'crop', then crop too
                    if ($option == 'crop') {
                        $this->crop($optimalWidth, $optimalHeight, $newWidth, $newHeight);
                    }
                }
    
                ## --------------------------------------------------------
    
                private function getDimensions($newWidth, $newHeight, $option)
                {
    
                   switch ($option)
                    {
                        case 'exact':
                            $optimalWidth = $newWidth;
                            $optimalHeight= $newHeight;
                            break;
                        case 'portrait':
                            $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                            $optimalHeight= $newHeight;
                            break;
                        case 'landscape':
                            $optimalWidth = $newWidth;
                            $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                            break;
                        case 'auto':
                            $optionArray = $this->getSizeByAuto($newWidth, $newHeight);
                            $optimalWidth = $optionArray['optimalWidth'];
                            $optimalHeight = $optionArray['optimalHeight'];
                            break;
                        case 'crop':
                            $optionArray = $this->getOptimalCrop($newWidth, $newHeight);
                            $optimalWidth = $optionArray['optimalWidth'];
                            $optimalHeight = $optionArray['optimalHeight'];
                            break;
                    }
                    return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
                }
    
                ## --------------------------------------------------------
    
                private function getSizeByFixedHeight($newHeight)
                {
                    $ratio = $this->width / $this->height;
                    $newWidth = $newHeight * $ratio;
                    return $newWidth;
                }
    
                private function getSizeByFixedWidth($newWidth)
                {
                    $ratio = $this->height / $this->width;
                    $newHeight = $newWidth * $ratio;
                    return $newHeight;
                }
    
                private function getSizeByAuto($newWidth, $newHeight)
                {
                    if ($this->height < $this->width)
                    // *** Image to be resized is wider (landscape)
                    {
                        $optimalWidth = $newWidth;
                        $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                    }
                    elseif ($this->height > $this->width)
                    // *** Image to be resized is taller (portrait)
                    {
                        $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                        $optimalHeight= $newHeight;
                    }
                    else
                    // *** Image to be resizerd is a square
                    {
                        if ($newHeight < $newWidth) {
                            $optimalWidth = $newWidth;
                            $optimalHeight= $this->getSizeByFixedWidth($newWidth);
                        } else if ($newHeight > $newWidth) {
                            $optimalWidth = $this->getSizeByFixedHeight($newHeight);
                            $optimalHeight= $newHeight;
                        } else {
                            // *** Sqaure being resized to a square
                            $optimalWidth = $newWidth;
                            $optimalHeight= $newHeight;
                        }
                    }
    
                    return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
                }
    
                ## --------------------------------------------------------
    
                private function getOptimalCrop($newWidth, $newHeight)
                {
    
                    $heightRatio = $this->height / $newHeight;
                    $widthRatio  = $this->width /  $newWidth;
    
                    if ($heightRatio < $widthRatio) {
                        $optimalRatio = $heightRatio;
                    } else {
                        $optimalRatio = $widthRatio;
                    }
    
                    $optimalHeight = $this->height / $optimalRatio;
                    $optimalWidth  = $this->width  / $optimalRatio;
    
                    return array('optimalWidth' => $optimalWidth, 'optimalHeight' => $optimalHeight);
                }
    
                ## --------------------------------------------------------
    
                private function crop($optimalWidth, $optimalHeight, $newWidth, $newHeight)
                {
                    // *** Find center - this will be used for the crop
                    $cropStartX = ( $optimalWidth / 2) - ( $newWidth /2 );
                    $cropStartY = ( $optimalHeight/ 2) - ( $newHeight/2 );
    
                    $crop = $this->imageResized;
                    //imagedestroy($this->imageResized);
    
                    // *** Now crop from center to exact requested size
                    $this->imageResized = imagecreatetruecolor($newWidth , $newHeight);
                    imagecopyresampled($this->imageResized, $crop , 0, 0, $cropStartX, $cropStartY, $newWidth, $newHeight , $newWidth, $newHeight);
                }
    
                ## --------------------------------------------------------
    
                public function saveImage($savePath, $imageQuality="100")
                {
                    // *** Get extension
                    $extension = strrchr($savePath, '.');
                    $extension = strtolower($extension);
    
                    switch($extension)
                    {
                        case '.jpg':
                        case '.jpeg':
                            if (imagetypes() & IMG_JPG) {
                                imagejpeg($this->imageResized, $savePath, $imageQuality);
                            }
                            break;
    
                        case '.gif':
                            if (imagetypes() & IMG_GIF) {
                                imagegif($this->imageResized, $savePath);
                            }
                            break;
    
                        case '.png':
                            // *** Scale quality from 0-100 to 0-9
                            $scaleQuality = round(($imageQuality/100) * 9);
    
                            // *** Invert quality setting as 0 is best, not 9
                            $invertScaleQuality = 9 - $scaleQuality;
    
                            if (imagetypes() & IMG_PNG) {
                                 imagepng($this->imageResized, $savePath, $invertScaleQuality);
                            }
                            break;
    
                        // ... etc
    
                        default:
                            // *** No extension - No save.
                            break;
                    }
    
                    imagedestroy($this->imageResized);
                }
    
    
                ## --------------------------------------------------------
    
            }
    ?>
    
  • neeko
    neeko over 11 years
    sorry but i am very new to this, how would i make this script take the embedded rotation information in to account
  • neeko
    neeko over 11 years
    sorry, i am a bit confused, thank you for your help, could you show me a code example?
  • New Alexandria
    New Alexandria over 11 years
    I linked directly to a function there at the end, which interprets the EXIF bits and performs the appropriate rotation. Did you read it?
  • neeko
    neeko over 11 years
    yes i read it, a bit confused how to implement this in to my script thankyou for helping me out on this matter
  • New Alexandria
    New Alexandria over 11 years
    @neeko ok. I have a test to complete now, so I hope my explicit answer was the solution for you.
  • New Alexandria
    New Alexandria over 11 years
    Then just change them all by-hand until you figure out the nuances of Dreamweaver find-replace
  • Vahid Naghash
    Vahid Naghash over 2 years
    thank you so much, it's been about a week since I'm working on this problem.