‪TYPO3CMS  11.5
ImageInfo.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the TYPO3 CMS project.
5  *
6  * It is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU General Public License, either version 2
8  * of the License, or any later version.
9  *
10  * For the full copyright and license information, please read the
11  * LICENSE.txt file that was distributed with this source code.
12  *
13  * The TYPO3 project - inspiring people to share!
14  */
15 
17 
18 use Psr\Log\LoggerAwareInterface;
19 use Psr\Log\LoggerAwareTrait;
23 
27 class ‪ImageInfo extends ‪FileInfo implements LoggerAwareInterface
28 {
29  use LoggerAwareTrait;
30 
34  protected ‪$imageSizes;
35 
41  public function ‪getWidth()
42  {
44  return (int)‪$imageSizes[0];
45  }
46 
52  public function ‪getHeight()
53  {
55  return (int)‪$imageSizes[1];
56  }
57 
64  protected function ‪getExifAwareImageSize(string $imageFile)
65  {
66  $size = false;
67  if (function_exists('getimagesize')) {
68  $size = @getimagesize($imageFile);
69  }
70  if ($size === false) {
71  return false;
72  }
73  [$width, $height] = $size;
74 
75  if (function_exists('exif_read_data')) {
76  $exif = @exif_read_data($imageFile);
77  // see: http://sylvana.net/jpegcrop/exif_orientation.html
78  if (isset($exif['Orientation']) && $exif['Orientation'] >= 5 && $exif['Orientation'] <= 8) {
79  return [$height, $width];
80  }
81  }
82 
83  return [$width, $height];
84  }
85 
89  protected function ‪getImageSizes()
90  {
91  if ($this->imageSizes === null) {
92  $this->imageSizes = $this->‪getExifAwareImageSize($this->getPathname());
93 
94  // Try SVG first as SVG size detection with IM/GM leads to an error output
95  if ($this->imageSizes === false && $this->‪getMimeType() === 'image/svg+xml') {
96  $this->imageSizes = $this->‪extractSvgImageSizes();
97  }
98  // Fallback to IM/GM identify
99  if ($this->imageSizes === false) {
100  $this->imageSizes = $this->‪getImageSizesFromImageMagick();
101  }
102 
103  // In case the image size could not be retrieved, log the incident as a warning.
104  if (empty($this->imageSizes)) {
105  $this->logger->warning('I could not retrieve the image size for file {file}', ['file' => $this->getPathname()]);
106  $this->imageSizes = [0, 0];
107  }
108  }
109  return ‪$this->imageSizes;
110  }
111 
112  protected function ‪getImageSizesFromImageMagick(): ?array
113  {
114  try {
115  $graphicalFunctions = GeneralUtility::makeInstance(GraphicalFunctions::class);
116  return $graphicalFunctions->imageMagickIdentify($this->getPathname());
117  } catch (‪UnsupportedFileException $e) {
118  $this->logger->error(
119  'Error resolving image sizes with ImageMagick: ' . $this->getPathname(),
120  ['exception' => $e]
121  );
122  return null;
123  }
124  }
125 
132  protected function ‪extractSvgImageSizes()
133  {
134  $fileContent = file_get_contents($this->getPathname());
135  if ($fileContent === false) {
136  return false;
137  }
138  // Disables the functionality to allow external entities to be loaded when parsing the XML, must be kept
139  $previousValueOfEntityLoader = null;
140  if (PHP_MAJOR_VERSION < 8) {
141  $previousValueOfEntityLoader = libxml_disable_entity_loader(true);
142  }
143  $xml = simplexml_load_string($fileContent, \SimpleXMLElement::class, LIBXML_NOERROR | LIBXML_NOWARNING);
144  if (PHP_MAJOR_VERSION < 8) {
145  libxml_disable_entity_loader($previousValueOfEntityLoader);
146  }
147  // If something went wrong with simpleXml don't try to read information
148  if ($xml === false) {
149  return false;
150  }
151 
152  $xmlAttributes = $xml->attributes();
153 
154  // First check if width+height are set
155  if (!empty($xmlAttributes['width']) && !empty($xmlAttributes['height'])) {
156  $imagesSizes = [(int)$xmlAttributes['width'], (int)$xmlAttributes['height']];
157  } elseif (!empty($xmlAttributes['viewBox'])) {
158  // Fallback to viewBox
159  $viewBox = explode(' ', $xmlAttributes['viewBox']);
160  $imagesSizes = [(int)$viewBox[2], (int)$viewBox[3]];
161  } else {
162  // To not fail image processing, we just assume an SVG image dimension here
163  $imagesSizes = [64, 64];
164  }
165 
166  return $imagesSizes !== [] ? $imagesSizes : false;
167  }
168 }
‪TYPO3\CMS\Core\Type\File\ImageInfo\getImageSizesFromImageMagick
‪getImageSizesFromImageMagick()
Definition: ImageInfo.php:111
‪TYPO3\CMS\Core\Type\File
Definition: FileInfo.php:16
‪TYPO3\CMS\Core\Type\File\ImageInfo\$imageSizes
‪array false null $imageSizes
Definition: ImageInfo.php:33
‪TYPO3\CMS\Core\Type\File\ImageInfo\getImageSizes
‪array getImageSizes()
Definition: ImageInfo.php:88
‪TYPO3\CMS\Core\Type\File\ImageInfo\extractSvgImageSizes
‪false array extractSvgImageSizes()
Definition: ImageInfo.php:131
‪TYPO3\CMS\Core\Type\File\ImageInfo\getExifAwareImageSize
‪array false getExifAwareImageSize(string $imageFile)
Definition: ImageInfo.php:63
‪TYPO3\CMS\Core\Type\File\ImageInfo\getWidth
‪int getWidth()
Definition: ImageInfo.php:40
‪TYPO3\CMS\Core\Imaging\GraphicalFunctions
Definition: GraphicalFunctions.php:37
‪TYPO3\CMS\Core\Imaging\Exception\UnsupportedFileException
Definition: UnsupportedFileException.php:25
‪TYPO3\CMS\Core\Type\File\ImageInfo
Definition: ImageInfo.php:28
‪TYPO3\CMS\Core\Type\File\FileInfo
Definition: FileInfo.php:25
‪TYPO3\CMS\Core\Type\File\ImageInfo\getHeight
‪int getHeight()
Definition: ImageInfo.php:51
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:50
‪TYPO3\CMS\Core\Type\File\FileInfo\getMimeType
‪string false getMimeType()
Definition: FileInfo.php:34