简体   繁体   English

PHP图像大小调整脚本旋转从iPhone Camera上传的图像

[英]PHP image resize script rotate image uploaded from iPhone Camera

The following script rotate portrait images. 以下脚本旋转人像图像。 How can I change it to maintain the orientation (no rotation, just resize)? 如何更改它以保持方向(不旋转,仅调整大小)?

Update The script only rotates portrait images when uploaded with iPhone using the Camera. 更新脚本仅在使用相机通过iPhone上传时旋转肖像图像。 Portrait images uploaded with iPhone from the Library does not get rotated, and portrait images uploaded on desktop does not get rotated. 从库中用iPhone上传的人像图像不会旋转,在桌面上上传的人像图像也不会旋转。

Preview before upload 上传前预览 上传前预览

Image after resize if the previewed image above was uploaded from iPhone camera (see PHP and Class below) 如果上面的预览图像是从iPhone相机上传的,则调整大小后的图像(请参见下面的PHP和类) 在此处输入图片说明

Image after resize if the previewed image above was uploaded from iPhone library (taken by camera the same way as above) 如果上面的预览图像是从iPhone库上载的,则调整大小后的图像(由照相机以与上述相同的方式拍摄) 在此处输入图片说明

PHP 的PHP

include("classes/resize.class.php");
// *** 1) Initialise / load image
$resizeObj = new resize($fileLocation);
$resizeObj -> resizeImage(320, 320, 'crop');
$resizeObj -> saveImage($fileLocationSq, 100);

Class

<?php


        class resize
        {
            // *** Class variables
            private $image;
            private $width;
            private $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);
                    return 'ok';
                }
            }

            ## --------------------------------------------------------

            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);
            }


            ## --------------------------------------------------------

        }
?>

Images can have extra information about orientation (= landscape or portrait). 图像可以包含有关方向的其他信息(=横向或纵向)。 See: 看到:

http://www.impulseadventure.com/photo/exif-orientation.html http://www.impulseadventure.com/photo/exif-orientation.html

This could explain your problem. 这可以解释您的问题。 If you look at: 如果您看:

http://php.net/manual/en/function.imagecreatefromjpeg.php http://php.net/manual/zh/function.imagecreatefromjpeg.php

Then you can find this in the comments: 然后,您可以在注释中找到它:

This function does not honour EXIF orientation data. 此功能不支持EXIF方向数据。 Pictures that are rotated using EXIF, will show up in the original orientation after being handled by imagecreatefromjpeg(). 使用EXIF旋转的图片在由imagecreatefromjpeg()处理后将以原始方向显示。 Below is a function to create an image from JPEG while honouring EXIF orientation data. 以下是在遵守EXIF方向数据的同时从JPEG创建图像的功能。

And how you can correct for it: 以及如何纠正它:

function imagecreatefromjpegexif($filename)
{
    $img = imagecreatefromjpeg($filename);
    $exif = exif_read_data($filename);
    if ($img && $exif && isset($exif['Orientation']))
    {
        $ort = $exif['Orientation'];

        if ($ort == 6 || $ort == 5)
            $img = imagerotate($img, 270, null);
        if ($ort == 3 || $ort == 4)
            $img = imagerotate($img, 180, null);
        if ($ort == 8 || $ort == 7)
            $img = imagerotate($img, 90, null);

        if ($ort == 5 || $ort == 4 || $ort == 7)
            imageflip($img, IMG_FLIP_HORIZONTAL);
    }
    return $img;
}

KIKO Software's answer is very good, but I would like to make a small addition to it. KIKO Software的回答非常好,但是我想对此做些补充。 exif_read_data is not always available on all machines, so better check if it is available before usage. exif_read_data并非始终在所有机器上都可用,因此最好在使用前检查它是否可用。 Also, it produces some unwanted output, so better prepend it with @: 此外,它会产生一些不必要的输出,因此最好在其前面加上@:

  if(function_exists('exif_read_data'))
  {
      $exif = @exif_read_data($filename);
  }
  else
  {
      return $img;
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM