‪TYPO3CMS  ‪main
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;
21 use TYPO3\CMS\Core\Imaging\GraphicalFunctions;
23 
27 class ImageInfo extends FileInfo implements LoggerAwareInterface
28 {
29  use LoggerAwareTrait;
30 
34  protected $imageSizes;
35 
41  public function getWidth()
42  {
43  $imageSizes = $this->getImageSizes();
44  return (int)$imageSizes[0];
45  }
46 
52  public function getHeight()
53  {
54  $imageSizes = $this->getImageSizes();
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 
115  protected function getImageSizesFromImageMagick(): ?array
116  {
117  try {
118  $graphicalFunctions = GeneralUtility::makeInstance(GraphicalFunctions::class);
119  return $graphicalFunctions->imageMagickIdentify($this->getPathname());
120  } catch (UnsupportedFileException $e) {
121  $this->logger->error(
122  'Error resolving image sizes with ImageMagick: ' . $this->getPathname(),
123  ['exception' => $e]
124  );
125  return null;
126  }
127  }
128 
134  protected function extractSvgImageSizes()
135  {
136  $fileContent = file_get_contents($this->getPathname());
137  if ($fileContent === false) {
138  return false;
139  }
140  $xml = simplexml_load_string($fileContent, \SimpleXMLElement::class, LIBXML_NOERROR | LIBXML_NOWARNING);
141  // If something went wrong with simpleXml don't try to read information
142  if ($xml === false) {
143  return false;
144  }
145 
146  $xmlAttributes = $xml->attributes();
147 
148  // First check if width+height are set
149  if (!empty($xmlAttributes['width']) && !empty($xmlAttributes['height'])) {
150  return [(int)$xmlAttributes['width'], (int)$xmlAttributes['height']];
151  }
152  if (!empty($xmlAttributes['viewBox'])) {
153  // Fallback to viewBox
154  $viewBox = explode(' ', $xmlAttributes['viewBox']);
155  return [(int)$viewBox[2], (int)$viewBox[3]];
156  }
157 
158  // To not fail image processing, we just assume an SVG image dimension here
159  return [64, 64];
160  }
161 }
‪TYPO3\CMS\Core\Type\File
Definition: FileInfo.php:16
‪TYPO3\CMS\Core\Imaging\Exception\UnsupportedFileException
Definition: UnsupportedFileException.php:25
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52