From: Alexander Ebert Date: Wed, 27 Jul 2011 13:19:16 +0000 (+0200) Subject: Improved image adapters, removed old Thumbnail-class X-Git-Tag: 2.0.0_Beta_1~1936 X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=a3399fc58a1bf8f9b23adedce30817b62dfbca30;p=GitHub%2FWoltLab%2FWCF.git Improved image adapters, removed old Thumbnail-class --- diff --git a/wcfsetup/install/files/lib/system/image/Thumbnail.class.php b/wcfsetup/install/files/lib/system/image/Thumbnail.class.php deleted file mode 100644 index ab94a82e4b..0000000000 --- a/wcfsetup/install/files/lib/system/image/Thumbnail.class.php +++ /dev/null @@ -1,447 +0,0 @@ - - * @package com.woltlab.wcf - * @subpackage system.image - * @category Community Framework - */ -class Thumbnail { - /** - * path to source file - * - * @var string - */ - protected $sourceFile = ''; - - /** - * maximum image width - * - * @var integer - */ - protected $maxWidth = 0; - - /** - * maximum image height - * - * @var integer - */ - protected $maxHeight = 0; - - /** - * true, to show source information in thumbnail - * - * @var boolean - */ - protected $appendSourceInfo = false; - - /** - * true, to prefer embedded thumbnails - * - * @var boolean - */ - protected $useEmbedded = true; - - /** - * true, to generate quadratic thumbnails - * - * @var boolean - */ - protected $quadratic = false; - - /** - * mime type of the thumbnail - * - * @var string - */ - protected $mimeType = ''; - - /** - * name of the source image - * - * @var string - */ - protected $sourceName = ''; - - /** - * width of the source image - * - * @var integer - */ - protected $sourceWidth = 0; - - /** - * height of the source image - * - * @var integer - */ - protected $sourceHeight = 0; - - /** - * file size of the source image - * - * @var integer - */ - protected $sourceSize = 0; - - /** - * height of the source information - * - * @var integer - */ - protected static $sourceInfoLineHeight = 16; - - /** - * image type of the source image - * - * @var integer - */ - protected $imageType = 0; - - /** - * Creates a new Thumbnail object. - * - * @param string $sourceFile - * @param integer $maxWidth - * @param integer $maxHeight - * @param boolean $appendSourceInfo - */ - public function __construct($sourceFile, $maxWidth = 100, $maxHeight = 100, $appendSourceInfo = false, $sourceName = null, $useEmbedded = true, $quadratic = false) { - $this->sourceFile = $sourceFile; - $this->maxWidth = $maxWidth; - $this->maxHeight = $maxHeight; - $this->appendSourceInfo = $appendSourceInfo; - $this->useEmbedded = $useEmbedded; - $this->quadratic = $quadratic; - if ($this->appendSourceInfo) { - // get source info - if ($sourceName != null) $this->sourceName = $sourceName; - else $this->sourceName = basename($this->sourceFile); - list($this->sourceWidth, $this->sourceHeight, $type) = @getImageSize($this->sourceFile); - $this->sourceSize = @filesize($sourceFile); - } - } - - /** - * Creates a thumbnail picture (jpg/png) of a big image - * - * @param boolean $rescale - * @return string thumbnail - */ - public function makeThumbnail($rescale = false) { - list($width, $height, $this->imageType) = @getImageSize($this->sourceFile); - - // check image size - if ($this->checkSize($width, $height, $rescale)) { - return false; - } - - // try to extract the embedded thumbnail first (faster) - $thumbnail = false; - if (!$rescale && $this->useEmbedded) { - $thumbnail = $this->extractEmbeddedThumbnail(); - } - if (!$thumbnail) { - // calculate uncompressed filesize - // and cancel to avoid a memory_limit error - $memoryLimit = ini_get('memory_limit'); - if ($memoryLimit != '') { - $memoryLimit = substr($memoryLimit, 0, -1) * 1024 * 1024; - $fileSize = $width * $height * ($this->imageType == 3 ? 4 : 3); - - if (($fileSize * 2.1) + memory_get_usage() > ($memoryLimit)) { - return false; - } - } - - // calculate new picture size - $x = $y = 0; - if ($this->quadratic) { - $newWidth = $newHeight = $this->maxWidth; - if ($this->appendSourceInfo) $newHeight -= self::$sourceInfoLineHeight * 2; - - if ($width > $height) { - $x = ceil(($width - $height) / 2); - $width = $height; - } - else { - $y = ceil(($height - $width) / 2); - $height = $width; - } - } - else { - $maxHeight = $this->maxHeight; - if ($this->appendSourceInfo) $maxHeight -= self::$sourceInfoLineHeight * 2; - if ($this->maxWidth / $width < $maxHeight / $height) { - $newWidth = $this->maxWidth; - $newHeight = round($height * ($newWidth / $width)); - } - else { - $newHeight = $maxHeight; - $newWidth = round($width * ($newHeight / $height)); - } - } - - // resize image - $imageResource = false; - - // jpeg image - if ($this->imageType == 2 && function_exists('imagecreatefromjpeg')) { - $imageResource = @imageCreateFromJPEG($this->sourceFile); - } - // gif image - if ($this->imageType == 1 && function_exists('imagecreatefromgif')) { - $imageResource = @imageCreateFromGIF($this->sourceFile); - } - // png image - if ($this->imageType == 3 && function_exists('imagecreatefrompng')) { - $imageResource = @imageCreateFromPNG($this->sourceFile); - } - - // could not create image - if (!$imageResource) { - return false; - } - - // resize image - if (function_exists('imageCreateTrueColor') && function_exists('imageCopyResampled')) { - $imageNew = @imageCreateTrueColor($newWidth, $newHeight); - imageAlphaBlending($imageNew, false); - @imageCopyResampled($imageNew, $imageResource, 0, 0, $x, $y, $newWidth, $newHeight, $width, $height); - imageSaveAlpha($imageNew, true); - } - else if (function_exists('imageCreate') && function_exists('imageCopyResized')) { - $imageNew = @imageCreate($newWidth, $newHeight); - imageAlphaBlending($imageNew, false); - @imageCopyResized($imageNew, $imageResource, 0, 0, $x, $y, $newWidth, $newHeight, $width, $height); - imageSaveAlpha($imageNew, true); - } - else return false; - - // create thumbnail - ob_start(); - - if ($this->imageType == 1 && function_exists('imageGIF')) { - @imageGIF($imageNew); - $this->mimeType = 'image/gif'; - } - else if (($this->imageType == 1 || $this->imageType == 3) && function_exists('imagePNG')) { - @imagePNG($imageNew); - $this->mimeType = 'image/png'; - } - else if (function_exists('imageJPEG')) { - @imageJPEG($imageNew, '', 90); - $this->mimeType = 'image/jpeg'; - } - else { - return false; - } - - @imageDestroy($imageNew); - $thumbnail = ob_get_contents(); - ob_end_clean(); - } - - if ($thumbnail && $this->appendSourceInfo && !$rescale) { - $thumbnail = $this->appendSourceInfo($thumbnail); - } - - return $thumbnail; - } - - /** - * Appends information about the source image to the thumbnail. - * - * @param string $thumbnail - * @return string - */ - protected function appendSourceInfo($thumbnail) { - if (!function_exists('imageCreateFromString') || !function_exists('imageCreateTrueColor')) { - return $thumbnail; - } - - $imageSrc = imageCreateFromString($thumbnail); - - // get image size - $width = imageSX($imageSrc); - $height = imageSY($imageSrc); - - // increase height - $heightDst = $height + self::$sourceInfoLineHeight * 2; - - // create new image - $imageDst = imageCreateTrueColor($width, $heightDst); - imageAlphaBlending($imageDst, false); - - // set background color - $background = imageColorAllocate($imageDst, 102, 102, 102); - imageFill($imageDst, 0, 0, $background); - - // copy image - imageCopy($imageDst, $imageSrc, 0, 0, 0, 0, $width, $height); - imageSaveAlpha($imageDst, true); - - // get font size - $font = 2; - $fontWidth = imageFontWidth($font); - $fontHeight = imageFontHeight($font); - $fontColor = imageColorAllocate($imageDst, 255, 255, 255); - - // write source info - $line1 = $this->sourceName; - - // imageString supports only ISO-8859-1 encoded strings - $line1 = StringUtil::convertEncoding('UTF-8', 'ISO-8859-1', $line1); - - // truncate text if necessary - $maxChars = floor($width / $fontWidth); - if (strlen($line1) > $maxChars) { - $line1 = $this->truncateSourceName($line1, $maxChars); - } - - $line2 = $this->sourceWidth.'x'.$this->sourceHeight.' '.FileUtil::formatFilesize($this->sourceSize); - - // write line 1 - // calculate text position - $textX = 0; - $textY = 0; - - if ($fontHeight < self::$sourceInfoLineHeight) { - $textY = intval(round((self::$sourceInfoLineHeight - $fontHeight) / 2)); - } - if (strlen($line1) * $fontWidth < $width) { - $textX = intval(round(($width - strlen($line1) * $fontWidth) / 2)); - } - - imageString($imageDst, $font, $textX, $height + $textY, $line1, $fontColor); - - // write line 2 - // calculate text position - $textX = 0; - $textY = 0; - - if ($fontHeight < self::$sourceInfoLineHeight) { - $textY = self::$sourceInfoLineHeight + intval(round((self::$sourceInfoLineHeight - $fontHeight) / 2)); - } - if (strlen($line2) * $fontWidth < $width) { - $textX = intval(round(($width - strlen($line2) * $fontWidth) / 2)); - } - - imageString($imageDst, $font, $textX, $height + $textY, $line2, $fontColor); - - - // output image - ob_start(); - - if ($this->imageType == 1 && function_exists('imageGIF')) { - @imageGIF($imageDst); - $this->mimeType = 'image/gif'; - } - else if (($this->imageType == 1 || $this->imageType == 3) && function_exists('imagePNG')) { - @imagePNG($imageDst); - $this->mimeType = 'image/png'; - } - else if (function_exists('imageJPEG')) { - @imageJPEG($imageDst, '', 90); - $this->mimeType = 'image/jpeg'; - } - else { - return false; - } - - @imageDestroy($imageDst); - $thumbnail = ob_get_contents(); - ob_end_clean(); - - return $thumbnail; - } - - - /** - * Extracts the embedded thumbnail picture of a jpeg or tiff image - * - * @return string thumbnail - */ - protected function extractEmbeddedThumbnail() { - if (!function_exists('exif_thumbnail')) { - return false; - } - - $width = $height = $type = 0; - $thumbnail = @exif_thumbnail($this->sourceFile, $width, $height, $type); - if ($thumbnail && $type && $width && $height) { - // resize the extracted thumbnail again if necessary - // (normally the thumbnail size is set to 160px - // which is recommended in EXIF >2.1 and DCF) - $this->mimeType = image_type_to_mime_type($type); - if (!$this->checkSize($width, $height)) { - // get temporary file name - $this->sourceFile = FileUtil::getTemporaryFilename('thumbnail_'); - - // create tmp file - $tmpFile = new File($this->sourceFile); - $tmpFile->write($thumbnail); - $tmpFile->close(); - unset($thumbnail, $tmpFile); - - // resize tmp file again - return $this->makeThumbnail(true); - } - - return $thumbnail; - } - - return false; - } - - /** - * Checks the size of an image. - */ - protected function checkSize($width, $height, $rescale = true) { - $maxHeight = $this->maxHeight; - if ($this->appendSourceInfo && $rescale) { - $maxHeight -= self::$sourceInfoLineHeight * 2; - } - - if ($width > $this->maxWidth || $height > $maxHeight) { - return false; - } - - return true; - } - - /** - * Returns the mime type of the generated thumbnail. - * - * @return string - */ - public function getMimeType() { - return $this->mimeType; - } - - /** - * Truncates the given file name to needed length. - * - * @param string $name - * @param string $maxChars - * @return string - */ - protected static function truncateSourceName($name, $maxChars) { - $extension = ''; - $lastPosition = strrpos($name, '.'); - if ($lastPosition !== null) { - $extension = substr($name, $lastPosition); - $name = substr($name, 0, $lastPosition); - $maxChars -= strlen($extension); - } - - return substr($name, 0, $maxChars - 3) . '...' . $extension; - } -} diff --git a/wcfsetup/install/files/lib/system/image/adapter/GDImageAdapter.class.php b/wcfsetup/install/files/lib/system/image/adapter/GDImageAdapter.class.php index 1cb1658526..c5de8ae30f 100644 --- a/wcfsetup/install/files/lib/system/image/adapter/GDImageAdapter.class.php +++ b/wcfsetup/install/files/lib/system/image/adapter/GDImageAdapter.class.php @@ -1,5 +1,6 @@ width; - $heightScale = $maxHeight / $this->height; - - if ($widthScale > $heightScale) { - $width = round($this->width * $heightScale, 0); - $height = $maxHeight; + if ($maxWidth / $this->width < $maxHeight / $this->height) { + $width = $maxWidth; + $height = round($this->height * ($width / $this->width)); } else { - $width = $maxWidth; - $height = round($this->height * $widthScale, 0); + $height = $maxHeight; + $width = round($this->width * ($height / $this->height)); } + } else { - if ($this->width > $this->height) { - $x = ceil(($this->width - $this->height) / 2); - $width = $height = $this->height; + $width = $height = $maxWidth; + + if ($width > $height) { + $x = ceil(($width - $height) / 2); + $width = $height; } else { - $y = ceil(($this->height - $this->width) / 2); - $height = $width = $this->width; + $y = ceil(($height - $width) / 2); + $height = $width; } } @@ -182,6 +183,10 @@ class GDImageAdapter implements IImageAdapter { * @see wcf\system\image\adapter\IImageAdapter::writeImage() */ public function writeImage($image, $filename) { + if (!is_resource($image)) { + throw new SystemException("Given image is not a valid image resource."); + } + ob_start(); if ($this->type == IMAGETYPE_GIF) { @@ -200,6 +205,20 @@ class GDImageAdapter implements IImageAdapter { file_put_contents($filename, $thumbnail); } + /** + * @see wcf\system\image\adapter\IImageAdapter::getWidth() + */ + public function getWidth() { + return $this->width; + } + + /** + * @see wcf\system\image\adapter\IImageAdapter::getHeight() + */ + public function getHeight() { + return $this->height; + } + /** * @see wcf\system\image\adapter\IImageAdapter::getImage() */ diff --git a/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php b/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php index d11ad04cd9..99efd8c141 100644 --- a/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php +++ b/wcfsetup/install/files/lib/system/image/adapter/ImagickImageAdapter.class.php @@ -1,5 +1,6 @@ writeImage($filename); }