[FEATURE] Add SVG support 22/38422/8
authorFrans Saris <franssaris@gmail.com>
Wed, 1 Apr 2015 20:32:44 +0000 (22:32 +0200)
committerWouter Wolters <typo3@wouterwolters.nl>
Thu, 9 Apr 2015 20:42:46 +0000 (22:42 +0200)
Added rendering support for SVG images. When a SVG image is scaled
there is no processed file created but only a sys_file_processedfile
record with the calculated new dimensions.

When a mask or explicit cropping is set for an SVG image a
processed file is created like for all other images.

An extra fallback is added to ImageInfo to determine SVG dimensions when
IM/GM fails.

Resolves: #50136
Releases: master
Change-Id: I9d4e298f0329059e83783a94209c80558ed83e27
Reviewed-on: http://review.typo3.org/38422
Reviewed-by: Markus Klein <klein.t3@reelworx.at>
Reviewed-by: Benjamin Kott <info@bk2k.info>
Tested-by: Benjamin Kott <info@bk2k.info>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
17 files changed:
typo3/sysext/backend/Classes/Clipboard/Clipboard.php
typo3/sysext/backend/Classes/Controller/ContentElement/ElementInformationController.php
typo3/sysext/backend/Classes/Form/Element/InlineElement.php
typo3/sysext/backend/Classes/Utility/BackendUtility.php
typo3/sysext/backend/Classes/Utility/IconUtility.php
typo3/sysext/core/Classes/Resource/Hook/FileInfoHook.php
typo3/sysext/core/Classes/Resource/ProcessedFile.php
typo3/sysext/core/Classes/Resource/Processing/LocalCropScaleMaskHelper.php
typo3/sysext/core/Classes/Resource/Processing/LocalImageProcessor.php
typo3/sysext/core/Classes/Resource/Processing/LocalPreviewHelper.php
typo3/sysext/core/Classes/Type/File/ImageInfo.php
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Documentation/Changelog/master/Feature-50136-AddSVGSupport.rst [new file with mode: 0644]
typo3/sysext/filelist/Classes/FileList.php
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Classes/Controller/ShowImageController.php
typo3/sysext/recordlist/Classes/Browser/ElementBrowser.php

index 5ccd300..353ad72 100644 (file)
@@ -362,7 +362,10 @@ class Clipboard {
                                                                $processedFile = $fileObject->process(\TYPO3\CMS\Core\Resource\ProcessedFile::CONTEXT_IMAGEPREVIEW, array());
                                                                if ($processedFile) {
                                                                        $thumbUrl = $processedFile->getPublicUrl(TRUE);
-                                                                       $thumb .= '<br /><img src="' . htmlspecialchars($thumbUrl) . '" title="' . htmlspecialchars($fileObject->getName()) . '" alt="" />';
+                                                                       $thumb .= '<br /><img src="' . htmlspecialchars($thumbUrl) . '" ' .
+                                                                                       'width="' . $processedFile->getProperty('width') . '" ' .
+                                                                                       'height="' . $processedFile->getProperty('height') . '" ' .
+                                                                                       'title="' . htmlspecialchars($fileObject->getName()) . '" alt="" />';
                                                                }
                                                        }
                                                        $lines[] = '
index 0a04b14..56ac0ce 100644 (file)
@@ -279,17 +279,19 @@ class ElementInformationController {
 
                        // else check if we can create an Image preview
                        } elseif (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileExtension)) {
-                               $thumbUrl = $this->fileObject->process(
+                               $processedFile = $this->fileObject->process(
                                        ProcessedFile::CONTEXT_IMAGEPREVIEW,
                                        array(
                                                'width' => '590m',
                                                'height' => '400m'
                                        )
-                               )->getPublicUrl(TRUE);
-
+                               );
                                // Create thumbnail image?
-                               if ($thumbUrl) {
+                               if ($processedFile) {
+                                       $thumbUrl = $processedFile->getPublicUrl(TRUE);
                                        $previewTag .= '<img class="img-responsive img-thumbnail" src="' . $thumbUrl . '" ' .
+                                               'width="' . $processedFile->getProperty('width') . '" ' .
+                                               'height="' . $processedFile->getProperty('height') . '" ' .
                                                'alt="' . htmlspecialchars(trim($this->fileObject->getName())) . '" ' .
                                                'title="' . htmlspecialchars(trim($this->fileObject->getName())) . '" />';
                                }
index e327686..aad7fdf 100644 (file)
@@ -616,10 +616,14 @@ class InlineElement {
                                        }
                                        $imageSetup = array_merge(array('width' => '45', 'height' => '45c'), $imageSetup);
                                        $processedImage = $fileObject->process(\TYPO3\CMS\Core\Resource\ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, $imageSetup);
-                                       // Only use a thumbnail if the processing was successful.
-                                       if (!$processedImage->usesOriginalFile()) {
+                                       // Only use a thumbnail if the processing process was successful by checking if image width is set
+                                       if ($processedImage->getProperty('width')) {
                                                $imageUrl = $processedImage->getPublicUrl(TRUE);
-                                               $thumbnail = '<img src="' . $imageUrl . '" alt="' . htmlspecialchars($altText) . '" title="' . htmlspecialchars($altText) . '">';
+                                               $thumbnail = '<img src="' . $imageUrl . '" ' .
+                                                                        'width="' . $processedImage->getProperty('width') . '" ' .
+                                                                        'height="' . $processedImage->getProperty('height') . '" ' .
+                                                                        'alt="' . htmlspecialchars($altText) . '" ' .
+                                                                        'title="' . htmlspecialchars($altText) . '">';
                                        }
                                }
                        }
index b9d361c..7d3ed08 100644 (file)
@@ -1624,12 +1624,16 @@ class BackendUtility {
 
                                // Web image
                                if (GeneralUtility::inList($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'], $fileReferenceObject->getExtension())) {
-                                       $imageUrl = $fileObject->process(ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, array(
-                                               'width' => $sizeParts[0],
-                                               'height' => $sizeParts[1] . 'c',
-                                               'crop' => $fileReferenceObject->getProperty('crop')
-                                       ))->getPublicUrl(TRUE);
-                                       $imgTag = '<img src="' . $imageUrl . '" alt="' . htmlspecialchars($fileReferenceObject->getName()) . '" />';
+                                       $processedImage = $fileObject->process(ProcessedFile::CONTEXT_IMAGECROPSCALEMASK, array(
+                                                                               'width' => $sizeParts[0],
+                                                                               'height' => $sizeParts[1] . 'c',
+                                                                               'crop' => $fileReferenceObject->getProperty('crop')
+                                                                       ));
+                                       $imageUrl = $processedImage->getPublicUrl(TRUE);
+                                       $imgTag = '<img src="' . $imageUrl . '" ' .
+                                                       'width="' . $processedImage->getProperty('width') . '" ' .
+                                                       'height="' . $processedImage->getProperty('height') . '" ' .
+                                                       'alt="' . htmlspecialchars($fileReferenceObject->getName()) . '" />';
                                } else {
                                        // Icon
                                        $imgTag = IconUtility::getSpriteIconForResource($fileObject, array('title' => $fileObject->getName()));
index 2e02061..a4c4586 100644 (file)
@@ -62,9 +62,13 @@ class IconUtility {
                'png' => 'mimetypes-media-image',
                'bmp' => 'mimetypes-media-image',
                'tif' => 'mimetypes-media-image',
+               'tiff' => 'mimetypes-media-image',
                'tga' => 'mimetypes-media-image',
                'psd' => 'mimetypes-media-image',
                'eps' => 'mimetypes-media-image',
+               'ai' => 'mimetypes-media-image',
+               'svg' => 'mimetypes-media-image',
+               'pcx' => 'mimetypes-media-image',
                'avi' => 'mimetypes-media-video',
                'mpg' => 'mimetypes-media-video',
                'mpeg' => 'mimetypes-media-video',
index 641292b..205bde4 100644 (file)
@@ -75,7 +75,10 @@ class FileInfoHook {
                                $content .= $flashMessage->render();
                        }
                        if ($previewImage) {
-                               $content .= '<img src="' . htmlspecialchars($previewImage) . '" alt="" class="t3-tceforms-sysfile-imagepreview" />';
+                               $content .= '<img src="' . htmlspecialchars($previewImage) . '" ' .
+                                                       'width="' . $processedFile->getProperty('width') . '" ' .
+                                                       'height="' . $processedFile->getProperty('height') . '" ' .
+                                                       'alt="" class="t3-tceforms-sysfile-imagepreview" />';
                        }
                        $content .= '<strong>' . htmlspecialchars($file->getName()) . '</strong>';
                        $content .= '(' . htmlspecialchars(\TYPO3\CMS\Core\Utility\GeneralUtility::formatSize($file->getSize())) . 'bytes)<br />';
index 0eaee85..85cb84b 100644 (file)
@@ -336,8 +336,10 @@ class ProcessedFile extends AbstractFile {
                        unset($properties['pid']);
                        unset($properties['identifier']);
                        unset($properties['name']);
-                       unset($properties['width']);
-                       unset($properties['height']);
+
+                       // Use width + height set in processed file
+                       $properties['width'] = $this->properties['width'];
+                       $properties['height'] = $this->properties['height'];
                } else {
                        $properties = $this->properties;
                        $properties['identifier'] = $this->getIdentifier();
@@ -362,7 +364,7 @@ class ProcessedFile extends AbstractFile {
         * @return bool
         */
        protected function isUnchanged() {
-               return $this->identifier == NULL || $this->identifier === $this->originalFile->getIdentifier();
+               return !$this->properties['width'] && $this->usesOriginalFile();
        }
 
        /**
@@ -379,7 +381,7 @@ class ProcessedFile extends AbstractFile {
         * @return bool
         */
        public function usesOriginalFile() {
-               return $this->isUnchanged();
+               return $this->identifier == NULL || $this->identifier === $this->originalFile->getIdentifier();
        }
 
        /**
index f9ea7ab..11e687b 100644 (file)
@@ -16,6 +16,7 @@ namespace TYPO3\CMS\Core\Resource\Processing;
 
 use TYPO3\CMS\Core\Resource;
 use TYPO3\CMS\Core\Utility;
+use TYPO3\CMS\Frontend\Imaging\GifBuilder;
 
 /**
  * Helper class to locally perform a crop/scale/mask task with the TYPO3 image processing classes.
@@ -47,6 +48,9 @@ class LocalCropScaleMaskHelper {
         *   height => 200
         *   filePath => /some/path
         *
+        * If filePath isn't set but width and height are the original file is used as ProcessedFile
+        * with the returned width and height. This is for example useful for SVG images.
+        *
         * @param TaskInterface $task
         * @return array|NULL
         */
@@ -56,8 +60,8 @@ class LocalCropScaleMaskHelper {
                $sourceFile = $task->getSourceFile();
 
                $originalFileName = $sourceFile->getForLocalProcessing(FALSE);
-               /** @var $gifBuilder \TYPO3\CMS\Frontend\Imaging\GifBuilder */
-               $gifBuilder = Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Imaging\GifBuilder::class);
+               /** @var $gifBuilder GifBuilder */
+               $gifBuilder = Utility\GeneralUtility::makeInstance(GifBuilder::class);
                $gifBuilder->init();
                $gifBuilder->absPrefix = PATH_site;
 
@@ -82,16 +86,29 @@ class LocalCropScaleMaskHelper {
 
                // Normal situation (no masking)
                if (!(is_array($configuration['maskImages']) && $GLOBALS['TYPO3_CONF_VARS']['GFX']['im'])) {
+
+                       // SVG
+                       if ($croppedImage === NULL && $sourceFile->getExtension() === 'svg') {
+                               $newDimensions = $this->getNewSvgDimensions($sourceFile, $configuration, $options, $gifBuilder);
+                               $result = array(
+                                       0 => $newDimensions['width'],
+                                       1 => $newDimensions['height'],
+                                       3 => '' // no file = use original
+                               );
+
+                       // all other images
+                       } else {
                                // the result info is an array with 0=width,1=height,2=extension,3=filename
-                       $result = $gifBuilder->imageMagickConvert(
-                               $originalFileName,
-                               $configuration['fileExtension'],
-                               $configuration['width'],
-                               $configuration['height'],
-                               $configuration['additionalParameters'],
-                               $configuration['frame'],
-                               $options
-                       );
+                               $result = $gifBuilder->imageMagickConvert(
+                                       $originalFileName,
+                                       $configuration['fileExtension'],
+                                       $configuration['width'],
+                                       $configuration['height'],
+                                       $configuration['additionalParameters'],
+                                       $configuration['frame'],
+                                       $options
+                               );
+                       }
                } else {
                        $targetFileName = $this->getFilenameForImageCropScaleMask($task);
                        $temporaryFileName = $gifBuilder->tempPath . $targetFileName;
@@ -178,6 +195,44 @@ class LocalCropScaleMaskHelper {
        }
 
        /**
+        * Calculate new dimensions for SVG image
+        * No cropping, if cropped info present image is scaled down
+        *
+        * @param Resource\FileInterface $file
+        * @param array $configuration
+        * @param array $options
+        * @param GifBuilder $gifBuilder
+        * @return array width,height
+        */
+       protected function getNewSvgDimensions($file, array $configuration, array $options, GifBuilder $gifBuilder) {
+
+               $info = array($file->getProperty('width'), $file->getProperty('height'));
+               $data = $gifBuilder->getImageScale($info, $configuration['width'], $configuration['height'], $options);
+
+               // Turn cropScaling into scaling
+               if ($data['crs']) {
+                       if (!$data['origW']) {
+                               $data['origW'] = $data[0];
+                       }
+                       if (!$data['origH']) {
+                               $data['origH'] = $data[1];
+                       }
+                       if ($data[0] > $data['origW']) {
+                               $data[1] = (int)(($data['origW'] * $data[1]) / $data[0]);
+                               $data[0] = $data['origW'];
+                       } else {
+                               $data[0] = (int)(($data['origH'] * $data[0]) / $data[1]);
+                               $data[1] = $data['origH'];
+                       }
+               }
+
+               return array(
+                       'width' => $data[0],
+                       'height' => $data[1]
+               );
+       }
+
+       /**
         * @param Resource\ProcessedFile $processedFile
         * @param \TYPO3\CMS\Frontend\Imaging\GifBuilder $gifBuilder
         *
index 1548db5..9a5c980 100644 (file)
@@ -71,8 +71,17 @@ class LocalImageProcessor implements ProcessorInterface {
                                        array('width' => $imageDimensions[0], 'height' => $imageDimensions[1], 'size' => filesize($result['filePath']), 'checksum' => $task->getConfigurationChecksum())
                                );
                                $task->getTargetFile()->updateWithLocalFile($result['filePath']);
+
+                       // New dimensions + no new file (for instance svg)
+                       } elseif (!empty($result['width']) && !empty($result['height'])) {
+                               $task->setExecuted(TRUE);
+                               $task->getTargetFile()->setUsesOriginalFile();
+                               $task->getTargetFile()->updateProperties(
+                                       array('width' => $result['width'], 'height' => $result['height'], 'size' => $task->getSourceFile()->getSize(), 'checksum' => $task->getConfigurationChecksum())
+                               );
+
+                       // Seems we have no valid processing result
                        } else {
-                               // Seems we have no valid processing result
                                $task->setExecuted(FALSE);
                        }
                } catch (\Exception $e) {
index 69dd5b3..46d6b97 100644 (file)
@@ -44,6 +44,14 @@ class LocalPreviewHelper {
         * copies the typo3temp/ file to the processing folder of the target storage
         * removes the typo3temp/ file
         *
+        * The returned array has the following structure:
+        *   width => 100
+        *   height => 200
+        *   filePath => /some/path
+        *
+        * If filePath isn't set but width and height are the original file is used as ProcessedFile
+        * with the returned width and height. This is for example useful for SVG images.
+        *
         * @param TaskInterface $task
         * @return array|NULL
         */
@@ -76,6 +84,21 @@ class LocalPreviewHelper {
                                'No ext!',
                                $sourceFile->getName()
                        );
+                       $result = array(
+                               'filePath' => $temporaryFileName,
+                       );
+               } elseif ($sourceFile->getExtension() === 'svg') {
+                       /** @var $gifBuilder \TYPO3\CMS\Frontend\Imaging\GifBuilder */
+                       $gifBuilder = GeneralUtility::makeInstance(\TYPO3\CMS\Frontend\Imaging\GifBuilder::class);
+                       $gifBuilder->init();
+                       $gifBuilder->absPrefix = PATH_site;
+                       $info = $gifBuilder->getImageDimensions($originalFileName);
+                       $newInfo = $gifBuilder->getImageScale($info, $configuration['width'], $configuration['height'], array());
+                       $result = array(
+                               'width' => $newInfo[0],
+                               'height' => $newInfo[1],
+                               'filePath' => '' // no file = use original
+                       );
                } else {
                                // Create the temporary file
                        if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['im']) {
@@ -96,11 +119,12 @@ class LocalPreviewHelper {
                                        );
                                }
                        }
+                       $result = array(
+                               'filePath' => $temporaryFileName,
+                       );
                }
 
-               return array(
-                       'filePath' => $temporaryFileName,
-               );
+               return $result;
        }
 
 }
index c089258..45c3a1c 100644 (file)
@@ -60,6 +60,11 @@ class ImageInfo extends FileInfo {
                                $this->imageSizes = $this->getGraphicalFunctions()->imageMagickIdentify($this->getPathname());
                        }
 
+                       // Extra fallback for SVG
+                       if (empty($this->imageSizes) && $this->getMimeType() === 'image/svg+xml') {
+                               $this->imageSizes = $this->extractSvgImageSizes();
+                       }
+
                        // In case the image size could not be retrieved, log the incident as a warning.
                        if (empty($this->imageSizes)) {
                                $this->getLogger()->warning('I could not retrieve the image size for file ' . $this->getPathname());
@@ -70,6 +75,31 @@ class ImageInfo extends FileInfo {
        }
 
        /**
+        * Try to read SVG as XML file and
+        * find width and height
+        *
+        * @return FALSE|array
+        */
+       protected function extractSvgImageSizes() {
+               $imagesSizes = array();
+
+               $xml = simplexml_load_file($this->getPathname());
+               $xmlAttributes = $xml->attributes();
+
+               // First check if width+height are set
+               if (!empty($xmlAttributes['width']) && !empty($xmlAttributes['height'])) {
+                       $imagesSizes = array((int)$xmlAttributes['width'], (int)$xmlAttributes['height']);
+
+               // Fallback to viewBox
+               } elseif (!empty($xmlAttributes['viewBox'])) {
+                       $viewBox = explode(' ', $xmlAttributes['viewBox']);
+                       $imagesSizes = array((int)$viewBox[2], (int)$viewBox[3]);
+               }
+
+               return $imagesSizes !== array() ? $imagesSizes : FALSE;
+       }
+
+       /**
         * @return \TYPO3\CMS\Core\Log\Logger
         */
        protected function getLogger(){
index 5441de3..81634f3 100644 (file)
@@ -25,7 +25,7 @@ return array(
                'thumbnails' => TRUE,                                                   // Boolean: Enables the use of thumbnails in the backend interface.
                'thumbnails_png' => 0,                                                  // Bits. Bit0: If set, thumbnails from non-jpegs will be 'png', otherwise 'gif' (0=gif/1=png). Bit1: Even JPG's will be converted to png or gif (2=gif/3=png)
                'gif_compress' => TRUE,                                                 // Boolean: Enables the use of the \TYPO3\CMS\Core\Utility\GeneralUtility::gifCompress() workaround function for compressing giffiles made with GD or IM, which probably use only RLE or no compression at all.
-               'imagefile_ext' => 'gif,jpg,jpeg,tif,tiff,bmp,pcx,tga,png,pdf,ai',// Commalist of file extensions perceived as images by TYPO3. List should be set to 'gif,png,jpeg,jpg' if IM is not available. Lowercase and no spaces between!
+               'imagefile_ext' => 'gif,jpg,jpeg,tif,tiff,bmp,pcx,tga,png,pdf,ai,svg',// Commalist of file extensions perceived as images by TYPO3. List should be set to 'gif,png,jpeg,jpg' if IM is not available. Lowercase and no spaces between!
                'gdlib' => TRUE,                                                                // Boolean: Enables the use of GD.
                'gdlib_png' => FALSE,                                                   // Boolean: Enables the use of GD, with PNG only. This means that all items normally generated as gif-files will be png-files instead!
                'im' => TRUE,                                                                   // Boolean: Enables the use of IM.
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-50136-AddSVGSupport.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-50136-AddSVGSupport.rst
new file mode 100644 (file)
index 0000000..e69b409
--- /dev/null
@@ -0,0 +1,18 @@
+=================================
+Feature - #50136: Add SVG support
+=================================
+
+Description
+===========
+
+Added rendering support for SVG images. When an SVG image is scaled there is no processed file created but only a sys_file_processedfile record with the calculated new dimensions.
+
+When a mask of explicit cropping is set for an SVG image, the a processed file is created like for all other images.
+
+An extra fallback is added to ImageInfo to determine SVG dimensions when IM/GM fails. The new fallback reads the contents of the SVG file as a normal XML file and tries to find width and height in the outer tag. When no width and height are found viewBox is checked and when present the 3th and 4th value are used as width and height.
+
+
+Impact
+======
+
+SVG is added as default supported image file extension to $GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext'].
\ No newline at end of file
index a77473c..1620215 100644 (file)
@@ -719,7 +719,10 @@ class FileList extends AbstractRecordList {
                                                        $processedFile = $fileObject->process(ProcessedFile::CONTEXT_IMAGEPREVIEW, array());
                                                        if ($processedFile) {
                                                                $thumbUrl = $processedFile->getPublicUrl(TRUE);
-                                                               $theData[$field] .= '<br /><img src="' . $thumbUrl . '" title="' . htmlspecialchars($fileName) . '" alt="" />';
+                                                               $theData[$field] .= '<br /><img src="' . $thumbUrl . '" ' .
+                                                                       'width="' . $processedFile->getProperty('width') . '" ' .
+                                                                       'height="' . $processedFile->getProperty('height') . '" ' .
+                                                                       'title="' . htmlspecialchars($fileName) . '" alt="" />';
                                                        }
                                                }
                                                break;
index 1d518d0..400458c 100644 (file)
@@ -4473,6 +4473,7 @@ class ContentObjectRenderer {
                                                $icon = $this->cObjGetSingle($conf['iconCObject'], $conf['iconCObject.'], 'iconCObject');
                                        } else {
                                                $notFoundThumb = TYPO3_mainDir . 'gfx/fileicons/notfound_thumb.gif';
+                                               $sizeParts = array(64, 64);
                                                if ($GLOBALS['TYPO3_CONF_VARS']['GFX']['thumbnails']) {
                                                        // using the File Abstraction Layer to generate a preview image
                                                        try {
@@ -4486,8 +4487,6 @@ class ContentObjectRenderer {
                                                                                if ($conf['icon_thumbSize'] || $conf['icon_thumbSize.']) {
                                                                                        $thumbSize = (isset($conf['icon_thumbSize.']) ? $this->stdWrap($conf['icon_thumbSize'], $conf['icon_thumbSize.']) : $conf['icon_thumbSize']);
                                                                                        $sizeParts = explode('x', $thumbSize);
-                                                                               } else {
-                                                                                       $sizeParts = array(64, 64);
                                                                                }
                                                                                $icon = $fileObject->process(ProcessedFile::CONTEXT_IMAGEPREVIEW, array(
                                                                                        'width' => $sizeParts[0],
@@ -4501,7 +4500,9 @@ class ContentObjectRenderer {
                                                } else {
                                                        $icon = $notFoundThumb;
                                                }
-                                               $icon = '<img src="' . htmlspecialchars($GLOBALS['TSFE']->absRefPrefix . $icon) . '"' . $this->getBorderAttr(' border="0"') . '' . $this->getAltParam($conf) . ' />';
+                                               $icon = '<img src="' . htmlspecialchars($GLOBALS['TSFE']->absRefPrefix . $icon) . '"' .
+                                                               'width="' . $sizeParts[0] . '" height="' . $sizeParts[1] . '" ' .
+                                                               $this->getBorderAttr(' border="0"') . '' . $this->getAltParam($conf) . ' />';
                                        }
                                } else {
                                        $conf['icon.']['widthAttribute'] = isset($conf['icon.']['widthAttribute.']) ? $this->stdWrap($conf['icon.']['widthAttribute'], $conf['icon.']['widthAttribute.']) : $conf['icon.']['widthAttribute'];
index f5f7914..840f908 100644 (file)
@@ -98,7 +98,7 @@ EOF;
        /**
         * @var string
         */
-       protected $imageTag = '<img src="###publicUrl###" alt="###alt###" title="###title###" />';
+       protected $imageTag = '<img src="###publicUrl###" alt="###alt###" title="###title###" width="###width###" height="###height###" />';
 
        /**
         * Init function, setting the input vars in the global space.
@@ -155,7 +155,9 @@ EOF;
                $imageTagMarkers = array(
                        '###publicUrl###' => htmlspecialchars($processedImage->getPublicUrl()),
                        '###alt###' => htmlspecialchars($this->file->getProperty('alternative') ?: $this->title),
-                       '###title###' => htmlspecialchars($this->file->getProperty('title') ?: $this->title)
+                       '###title###' => htmlspecialchars($this->file->getProperty('title') ?: $this->title),
+                       '###width###' => $processedImage->getProperty('width'),
+                       '###height###' => $processedImage->getProperty('height')
                );
                $this->imageTag = str_replace(array_keys($imageTagMarkers), array_values($imageTagMarkers), $this->imageTag);
                if ($this->wrap !== '|') {
index e808b8f..fb310f2 100644 (file)
@@ -1984,16 +1984,20 @@ class ElementBrowser {
                        // Thumbnail/size generation:
                        $imgInfo = array();
                        if (GeneralUtility::inList(strtolower($GLOBALS['TYPO3_CONF_VARS']['GFX']['imagefile_ext']), strtolower($fileExtension)) && !$noThumbs) {
-                               $imageUrl = $fileObject->process(
+                               $processedFile = $fileObject->process(
                                        ProcessedFile::CONTEXT_IMAGEPREVIEW,
                                        array('width' => 64, 'height' => 64)
-                               )->getPublicUrl(TRUE);
+                               );
+                               $imageUrl = $processedFile->getPublicUrl(TRUE);
                                $imgInfo = array(
                                        $fileObject->getProperty('width'),
                                        $fileObject->getProperty('height')
                                );
                                $pDim = $imgInfo[0] . 'x' . $imgInfo[1] . ' pixels';
-                               $clickIcon = '<img src="' . $imageUrl . '" hspace="5" vspace="5" border="1" />';
+                               $clickIcon = '<img src="' . $imageUrl . '" ' .
+                                                       'width="' . $processedFile->getProperty('width') . '" ' .
+                                                       'height="' . $processedFile->getProperty('height') . '" ' .
+                                                       'hspace="5" vspace="5" border="1" />';
                        } else {
                                $clickIcon = '';
                                $pDim = '';