Improved thumb creation and fixed wrong sizes after EXIF rotation

This commit is contained in:
Tobias Reich 2014-10-18 16:57:09 +02:00
parent 2421db7469
commit 9698629c31

View File

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