From 9698629c31b4f6442a6dd19c3b258055d9dec869 Mon Sep 17 00:00:00 2001 From: Tobias Reich Date: Sat, 18 Oct 2014 16:57:09 +0200 Subject: [PATCH] Improved thumb creation and fixed wrong sizes after EXIF rotation --- php/modules/Photo.php | 109 +++++++++++++++++++++++++----------------- 1 file changed, 66 insertions(+), 43 deletions(-) diff --git a/php/modules/Photo.php b/php/modules/Photo.php index 27f1c23..6c1f966 100755 --- a/php/modules/Photo.php +++ b/php/modules/Photo.php @@ -159,15 +159,17 @@ class Photo extends Module { if ($exists===false) { # Set orientation based on EXIF data - if ($file['type']==='image/jpeg'&&isset($info['orientation'], $info['width'], $info['height'])&&$info['orientation']!=='') { - if (!$this->adjustFile($path, $info)) Log::notice($this->database, __METHOD__, __LINE__, 'Could not adjust photo (' . $info['title'] . ')'); + if ($file['type']==='image/jpeg'&&isset($info['orientation'])&&$info['orientation']!=='') { + $adjustFile = $this->adjustFile($path, $info); + if ($adjustFile!==false) $info = $adjustFile; + else Log::notice($this->database, __METHOD__, __LINE__, 'Skipped adjustment of photo (' . $info['title'] . ')'); } # Set original date if ($info['takestamp']!==''&&$info['takestamp']!==0) @touch($path, $info['takestamp']); # Create Thumb - if (!$this->createThumb($path, $photo_name)) { + if (!$this->createThumb($path, $photo_name, $info['type'], $info['width'], $info['height'])) { Log::error($this->database, __METHOD__, __LINE__, 'Could not create thumbnail for photo'); exit('Error: Could not create thumbnail for photo!'); } @@ -235,15 +237,19 @@ class Photo extends Module { } - private function createThumb($url, $filename, $width = 200, $height = 200) { + private function createThumb($url, $filename, $type, $width, $height) { # Check dependencies - self::dependencies(isset($this->database, $this->settings, $url, $filename)); + self::dependencies(isset($this->database, $this->settings, $url, $filename, $type, $width, $height)); # Call plugins $this->plugins(__METHOD__, 0, func_get_args()); - $photoName = explode(".", $filename); + # Size of the thumbnail + $newWidth = 200; + $newHeight = 200; + + $photoName = explode('.', $filename); $newUrl = LYCHEE_UPLOADS_THUMB . $photoName[0] . '.jpeg'; $newUrl2x = LYCHEE_UPLOADS_THUMB . $photoName[0] . '@2x.jpeg'; @@ -260,37 +266,36 @@ class Photo extends Module { $thumb2x = clone $thumb; # Create 1st version - $thumb->cropThumbnailImage($width, $height); + $thumb->cropThumbnailImage($newWidth, $newHeight); $thumb->writeImage($newUrl); $thumb->clear(); $thumb->destroy(); # Create 2nd version - $thumb2x->cropThumbnailImage($width*2, $height*2); + $thumb2x->cropThumbnailImage($newWidth*2, $newHeight*2); $thumb2x->writeImage($newUrl2x); $thumb2x->clear(); $thumb2x->destroy(); } else { - # Get size of photo - $info = getimagesize($url); + # Create image + $thumb = imagecreatetruecolor($newWidth, $newHeight); + $thumb2x = imagecreatetruecolor($newWidth*2, $newHeight*2); - # Set position and size - $thumb = imagecreatetruecolor($width, $height); - $thumb2x = imagecreatetruecolor($width*2, $height*2); - if ($info[0]<$info[1]) { - $newSize = $info[0]; + # Set position + if ($width<$height) { + $newSize = $width; $startWidth = 0; - $startHeight = $info[1]/2 - $info[0]/2; + $startHeight = $height/2 - $width/2; } else { - $newSize = $info[1]; - $startWidth = $info[0]/2 - $info[1]/2; + $newSize = $height; + $startWidth = $width/2 - $height/2; $startHeight = 0; } # Create new image - switch($info['mime']) { + switch($type) { case 'image/jpeg': $sourceImg = imagecreatefromjpeg($url); break; case 'image/png': $sourceImg = imagecreatefrompng($url); break; case 'image/gif': $sourceImg = imagecreatefromgif($url); break; @@ -300,12 +305,12 @@ class Photo extends Module { } # Create thumb - fastimagecopyresampled($thumb, $sourceImg, 0, 0, $startWidth, $startHeight, $width, $height, $newSize, $newSize); + fastimagecopyresampled($thumb, $sourceImg, 0, 0, $startWidth, $startHeight, $newWidth, $newHeight, $newSize, $newSize); imagejpeg($thumb, $newUrl, $this->settings['thumbQuality']); imagedestroy($thumb); # Create retina thumb - fastimagecopyresampled($thumb2x, $sourceImg, 0, 0, $startWidth, $startHeight, $width*2, $height*2, $newSize, $newSize); + fastimagecopyresampled($thumb2x, $sourceImg, 0, 0, $startWidth, $startHeight, $newWidth*2, $newHeight*2, $newSize, $newSize); imagejpeg($thumb2x, $newUrl2x, $this->settings['thumbQuality']); imagedestroy($thumb2x); @@ -329,10 +334,11 @@ class Photo extends Module { # Call plugins $this->plugins(__METHOD__, 0, func_get_args()); + # Size of the medium-photo # When changing these values, # also change the size detection in the front-end - $newWidth = 1920; - $newHeight = 1080; + $newWidth = 1920; + $newHeight = 1080; # Is photo big enough? # Is medium activated? @@ -379,6 +385,8 @@ class Photo extends Module { # Call plugins $this->plugins(__METHOD__, 0, func_get_args()); + $swapSize = false; + if (extension_loaded('imagick')&&$this->settings['imagick']==='1') { $rotateImage = 0; @@ -387,17 +395,20 @@ class Photo extends Module { case 3: $rotateImage = 180; - $imageOrientation = 1; break; case 6: - $rotateImage = 90; - $imageOrientation = 1; + $rotateImage = 90; + $swapSize = true; break; case 8: - $rotateImage = 270; - $imageOrientation = 1; + $rotateImage = 270; + $swapSize = true; + break; + + default: + return false; break; } @@ -406,7 +417,7 @@ class Photo extends Module { $image = new Imagick(); $image->readImage($path); $image->rotateImage(new ImagickPixel(), $rotateImage); - $image->setImageOrientation($imageOrientation); + $image->setImageOrientation(1); $image->writeImage($path); $image->clear(); $image->destroy(); @@ -416,7 +427,6 @@ class Photo extends Module { $newWidth = $info['width']; $newHeight = $info['height']; - $process = false; $sourceImg = imagecreatefromjpeg($path); switch ($info['orientation']) { @@ -424,6 +434,7 @@ class Photo extends Module { case 2: # mirror # not yet implemented + return false; break; case 3: @@ -434,11 +445,13 @@ class Photo extends Module { case 4: # rotate 180 and mirror # not yet implemented + return false; break; case 5: # rotate 90 and mirror # not yet implemented + return false; break; case 6: @@ -446,11 +459,13 @@ class Photo extends Module { $sourceImg = imagerotate($sourceImg, -90, 0); $newWidth = $info['height']; $newHeight = $info['width']; + $swapSize = true; break; case 7: # rotate -90 and mirror # not yet implemented + return false; break; case 8: @@ -458,30 +473,38 @@ class Photo extends Module { $sourceImg = imagerotate($sourceImg, 90, 0); $newWidth = $info['height']; $newHeight = $info['width']; + $swapSize = true; + break; + + default: + return false; break; } - # Need to adjust photo? - if ($process===true) { + # Recreate photo + $newSourceImg = imagecreatetruecolor($newWidth, $newHeight); + imagecopyresampled($newSourceImg, $sourceImg, 0, 0, 0, 0, $newWidth, $newHeight, $newWidth, $newHeight); + imagejpeg($newSourceImg, $path, 100); - # Recreate photo - $newSourceImg = imagecreatetruecolor($newWidth, $newHeight); - imagecopyresampled($newSourceImg, $sourceImg, 0, 0, 0, 0, $newWidth, $newHeight, $newWidth, $newHeight); - imagejpeg($newSourceImg, $path, 100); - - # Free memory - imagedestroy($sourceImg); - imagedestroy($newSourceImg); - - } + # Free memory + imagedestroy($sourceImg); + imagedestroy($newSourceImg); } # Call plugins $this->plugins(__METHOD__, 1, func_get_args()); - return true; + # SwapSize should be true when the image has been rotated + # Return new dimensions in this case + if ($swapSize===true) { + $swapSize = $info['width']; + $info['width'] = $info['height']; + $info['height'] = $swapSize; + } + + return $info; }