vendor/contao/core-bundle/src/Resources/contao/library/Contao/Image.php line 412

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of Contao.
  4.  *
  5.  * (c) Leo Feyer
  6.  *
  7.  * @license LGPL-3.0-or-later
  8.  */
  9. namespace Contao;
  10. use Contao\Image\DeferredImageInterface;
  11. use Contao\Image\Image as NewImage;
  12. use Contao\Image\ImageDimensions;
  13. use Contao\Image\ImportantPart;
  14. use Contao\Image\ResizeConfiguration;
  15. use Contao\Image\ResizeOptions;
  16. use Imagine\Image\Box;
  17. /**
  18.  * Resizes images
  19.  *
  20.  * The class resizes images and stores them in the image target folder.
  21.  *
  22.  * Usage:
  23.  *
  24.  *     $imageObj = new Image(new File('example.jpg'));
  25.  *
  26.  *     $src = $imageObj->setTargetWidth(640)
  27.  *                     ->setTargetHeight(480)
  28.  *                     ->setResizeMode('center_center')
  29.  *                     ->executeResize()
  30.  *                     ->getResizedPath();
  31.  */
  32. class Image
  33. {
  34.     /**
  35.      * The File instance of the original image
  36.      *
  37.      * @var File
  38.      */
  39.     protected $fileObj;
  40.     /**
  41.      * The resized image path
  42.      *
  43.      * @var string
  44.      */
  45.     protected $resizedPath '';
  46.     /**
  47.      * The target width
  48.      *
  49.      * @var integer
  50.      */
  51.     protected $targetWidth 0;
  52.     /**
  53.      * The target height
  54.      *
  55.      * @var integer
  56.      */
  57.     protected $targetHeight 0;
  58.     /**
  59.      * The resize mode (defaults to crop for backwards compatibility)
  60.      *
  61.      * @var string
  62.      */
  63.     protected $resizeMode 'crop';
  64.     /**
  65.      * The target path
  66.      *
  67.      * @var string
  68.      */
  69.     protected $targetPath '';
  70.     /**
  71.      * Override an existing target
  72.      *
  73.      * @var boolean
  74.      */
  75.     protected $forceOverride false;
  76.     /**
  77.      * Zoom level (between 0 and 100)
  78.      *
  79.      * @var integer
  80.      */
  81.     protected $zoomLevel 0;
  82.     /**
  83.      * Root dir
  84.      * @var string
  85.      */
  86.     protected $strRootDir;
  87.     /**
  88.      * Important part settings
  89.      *
  90.      * @var array
  91.      */
  92.     protected $importantPart = array();
  93.     /**
  94.      * Create a new object to handle an image
  95.      *
  96.      * @param File $file A file instance of the original image
  97.      *
  98.      * @throws \InvalidArgumentException If the file does not exist or cannot be processed
  99.      *
  100.      * @deprecated Deprecated since Contao 4.3, to be removed in Contao 5.0.
  101.      *             Use the contao.image.factory service instead.
  102.      */
  103.     public function __construct(File $file)
  104.     {
  105.         trigger_deprecation('contao/core-bundle''4.3''Using the "Contao\Image" class has been deprecated and will no longer work in Contao 5.0. Use the "contao.image.factory" service instead.');
  106.         // Check whether the file exists
  107.         if (!$file->exists())
  108.         {
  109.             $webDir System::getContainer()->getParameter('contao.web_dir');
  110.             // Handle public bundle resources
  111.             if (file_exists($webDir '/' $file->path))
  112.             {
  113.                 $file = new File(StringUtil::stripRootDir($webDir) . '/' $file->path);
  114.             }
  115.             else
  116.             {
  117.                 throw new \InvalidArgumentException('Image "' $file->path '" could not be found');
  118.             }
  119.         }
  120.         $this->fileObj $file;
  121.         $arrAllowedTypes System::getContainer()->getParameter('contao.image.valid_extensions');
  122.         // Check the file type
  123.         if (!\in_array($this->fileObj->extension$arrAllowedTypes))
  124.         {
  125.             throw new \InvalidArgumentException('Image type "' $this->fileObj->extension '" was not allowed to be processed');
  126.         }
  127.         $this->strRootDir System::getContainer()->getParameter('kernel.project_dir');
  128.     }
  129.     /**
  130.      * Override the target image
  131.      *
  132.      * @param boolean $forceOverride True to override the target image
  133.      *
  134.      * @return $this The image object
  135.      */
  136.     public function setForceOverride($forceOverride)
  137.     {
  138.         $this->forceOverride = (bool) $forceOverride;
  139.         return $this;
  140.     }
  141.     /**
  142.      * Get force override setting
  143.      *
  144.      * @return boolean True if the target image will be overridden
  145.      */
  146.     public function getForceOverride()
  147.     {
  148.         return $this->forceOverride;
  149.     }
  150.     /**
  151.      * Set the important part settings
  152.      *
  153.      * @param array $importantPart The settings array
  154.      *
  155.      * @return $this The image object
  156.      *
  157.      * @throws \InvalidArgumentException If the settings array is malformed
  158.      */
  159.     public function setImportantPart(array $importantPart null)
  160.     {
  161.         if ($importantPart !== null)
  162.         {
  163.             if (!isset($importantPart['x'], $importantPart['y'], $importantPart['width'], $importantPart['height']))
  164.             {
  165.                 throw new \InvalidArgumentException('Malformed array for setting the important part!');
  166.             }
  167.             $this->importantPart = array
  168.             (
  169.                 'x' => max(0min($this->fileObj->viewWidth 1, (int) $importantPart['x'])),
  170.                 'y' => max(0min($this->fileObj->viewHeight 1, (int) $importantPart['y'])),
  171.             );
  172.             $this->importantPart['width'] = max(1min($this->fileObj->viewWidth $this->importantPart['x'], (int) $importantPart['width']));
  173.             $this->importantPart['height'] = max(1min($this->fileObj->viewHeight $this->importantPart['y'], (int) $importantPart['height']));
  174.         }
  175.         else
  176.         {
  177.             $this->importantPart null;
  178.         }
  179.         return $this;
  180.     }
  181.     /**
  182.      * Get the important part settings
  183.      *
  184.      * @return array The settings array
  185.      */
  186.     public function getImportantPart()
  187.     {
  188.         if ($this->importantPart)
  189.         {
  190.             return $this->importantPart;
  191.         }
  192.         return array('x'=>0'y'=>0'width'=>$this->fileObj->viewWidth'height'=>$this->fileObj->viewHeight);
  193.     }
  194.     /**
  195.      * Set the target height
  196.      *
  197.      * @param integer $targetHeight The target height
  198.      *
  199.      * @return $this The image object
  200.      */
  201.     public function setTargetHeight($targetHeight)
  202.     {
  203.         $this->targetHeight = (int) $targetHeight;
  204.         return $this;
  205.     }
  206.     /**
  207.      * Get the target height
  208.      *
  209.      * @return integer The target height
  210.      */
  211.     public function getTargetHeight()
  212.     {
  213.         return $this->targetHeight;
  214.     }
  215.     /**
  216.      * Set the target width
  217.      *
  218.      * @param integer $targetWidth The target width
  219.      *
  220.      * @return $this The image object
  221.      */
  222.     public function setTargetWidth($targetWidth)
  223.     {
  224.         $this->targetWidth = (int) $targetWidth;
  225.         return $this;
  226.     }
  227.     /**
  228.      * Get the target width
  229.      *
  230.      * @return integer The target width
  231.      */
  232.     public function getTargetWidth()
  233.     {
  234.         return $this->targetWidth;
  235.     }
  236.     /**
  237.      * Set the target path
  238.      *
  239.      * @param string $targetPath The target path
  240.      *
  241.      * @return $this The image object
  242.      */
  243.     public function setTargetPath($targetPath)
  244.     {
  245.         $this->targetPath = (string) $targetPath;
  246.         return $this;
  247.     }
  248.     /**
  249.      * Get the target path
  250.      *
  251.      * @return string The target path
  252.      */
  253.     public function getTargetPath()
  254.     {
  255.         return $this->targetPath;
  256.     }
  257.     /**
  258.      * Set the zoom level
  259.      *
  260.      * @param integer $zoomLevel The zoom level
  261.      *
  262.      * @return $this The object instance
  263.      *
  264.      * @throws \InvalidArgumentException If the zoom level is out of bounds
  265.      */
  266.     public function setZoomLevel($zoomLevel)
  267.     {
  268.         $zoomLevel = (int) $zoomLevel;
  269.         if ($zoomLevel || $zoomLevel 100)
  270.         {
  271.             throw new \InvalidArgumentException('Zoom level must be between 0 and 100!');
  272.         }
  273.         $this->zoomLevel $zoomLevel;
  274.         return $this;
  275.     }
  276.     /**
  277.      * Get the zoom level
  278.      *
  279.      * @return integer The zoom level
  280.      */
  281.     public function getZoomLevel()
  282.     {
  283.         return $this->zoomLevel;
  284.     }
  285.     /**
  286.      * Set the resize mode
  287.      *
  288.      * @param string $resizeMode The resize mode
  289.      *
  290.      * @return $this The image object
  291.      */
  292.     public function setResizeMode($resizeMode)
  293.     {
  294.         $this->resizeMode $resizeMode;
  295.         return $this;
  296.     }
  297.     /**
  298.      * Get the resize mode
  299.      *
  300.      * @return string The resize mode
  301.      */
  302.     public function getResizeMode()
  303.     {
  304.         return $this->resizeMode;
  305.     }
  306.     /**
  307.      * Get the path of the original image
  308.      *
  309.      * @return string The path of the original image
  310.      */
  311.     public function getOriginalPath()
  312.     {
  313.         return $this->fileObj->path;
  314.     }
  315.     /**
  316.      * Get the path of the resized image
  317.      *
  318.      * @return string The path of the resized image
  319.      */
  320.     public function getResizedPath()
  321.     {
  322.         $path $this->resizedPath;
  323.         $webDir StringUtil::stripRootDir(System::getContainer()->getParameter('contao.web_dir'));
  324.         // Strip the contao.web_dir directory prefix (see #337)
  325.         if (strncmp($path$webDir '/', \strlen($webDir) + 1) === 0)
  326.         {
  327.             $path substr($path, \strlen($webDir) + 1);
  328.         }
  329.         return $path;
  330.     }
  331.     /**
  332.      * Get the cache name
  333.      *
  334.      * @return string The cache name
  335.      */
  336.     public function getCacheName()
  337.     {
  338.         $importantPart $this->getImportantPart();
  339.         $strCacheKey substr(md5
  340.         (
  341.             '-w' $this->getTargetWidth()
  342.             . '-h' $this->getTargetHeight()
  343.             . '-o' $this->getOriginalPath()
  344.             . '-m' $this->getResizeMode()
  345.             . '-z' $this->getZoomLevel()
  346.             . '-x' $importantPart['x']
  347.             . '-y' $importantPart['y']
  348.             . '-i' $importantPart['width']
  349.             . '-e' $importantPart['height']
  350.             . '-t' $this->fileObj->mtime
  351.         ), 08);
  352.         return StringUtil::stripRootDir(System::getContainer()->getParameter('contao.image.target_dir')) . '/' substr($strCacheKey, -1) . '/' $this->fileObj->filename '-' $strCacheKey '.' $this->fileObj->extension;
  353.     }
  354.     /**
  355.      * Resize the image
  356.      *
  357.      * @return $this The image object
  358.      */
  359.     public function executeResize()
  360.     {
  361.         $image $this->prepareImage();
  362.         $resizeConfig $this->prepareResizeConfig();
  363.         if (
  364.             $this->getTargetPath()
  365.             && !$this->getForceOverride()
  366.             && !System::getContainer()->getParameter('contao.image.bypass_cache')
  367.             && file_exists($this->strRootDir '/' $this->getTargetPath())
  368.             && $this->fileObj->mtime <= filemtime($this->strRootDir '/' $this->getTargetPath())
  369.         ) {
  370.             // HOOK: add custom logic
  371.             if (isset($GLOBALS['TL_HOOKS']['executeResize']) && \is_array($GLOBALS['TL_HOOKS']['executeResize']))
  372.             {
  373.                 foreach ($GLOBALS['TL_HOOKS']['executeResize'] as $callback)
  374.                 {
  375.                     $return System::importStatic($callback[0])->{$callback[1]}($this);
  376.                     if (\is_string($return))
  377.                     {
  378.                         $this->resizedPath System::urlEncode($return);
  379.                         return $this;
  380.                     }
  381.                 }
  382.             }
  383.             $this->resizedPath System::urlEncode($this->getTargetPath());
  384.             return $this;
  385.         }
  386.         $image System::getContainer()
  387.             ->get('contao.image.legacy_resizer')
  388.             ->resize(
  389.                 $image,
  390.                 $resizeConfig,
  391.                 (new ResizeOptions())
  392.                     ->setImagineOptions(System::getContainer()->getParameter('contao.image.imagine_options'))
  393.                     ->setTargetPath($this->targetPath $this->strRootDir '/' $this->targetPath null)
  394.                     ->setBypassCache(System::getContainer()->getParameter('contao.image.bypass_cache'))
  395.                     ->setSkipIfDimensionsMatch(true)
  396.             )
  397.         ;
  398.         $this->resizedPath $image->getUrl($this->strRootDir);
  399.         return $this;
  400.     }
  401.     /**
  402.      * Prepare image object.
  403.      *
  404.      * @return NewImage
  405.      */
  406.     protected function prepareImage()
  407.     {
  408.         if ($this->fileObj->isSvgImage)
  409.         {
  410.             $imagine System::getContainer()->get('contao.image.imagine_svg');
  411.         }
  412.         else
  413.         {
  414.             $imagine System::getContainer()->get('contao.image.imagine');
  415.         }
  416.         $image = new NewImage($this->strRootDir '/' $this->fileObj->path$imagineSystem::getContainer()->get('filesystem'));
  417.         $image->setImportantPart($this->prepareImportantPart());
  418.         return $image;
  419.     }
  420.     /**
  421.      * Prepare important part object.
  422.      *
  423.      * @return ImportantPart
  424.      */
  425.     protected function prepareImportantPart()
  426.     {
  427.         $importantPart $this->getImportantPart();
  428.         if (substr_count($this->resizeMode'_') === 1)
  429.         {
  430.             $importantPart = array
  431.             (
  432.                 'x' => 0,
  433.                 'y' => 0,
  434.                 'width' => $this->fileObj->viewWidth,
  435.                 'height' => $this->fileObj->viewHeight,
  436.             );
  437.             $mode explode('_'$this->resizeMode);
  438.             if ($mode[0] === 'left')
  439.             {
  440.                 $importantPart['width'] = 1;
  441.             }
  442.             elseif ($mode[0] === 'right')
  443.             {
  444.                 $importantPart['x'] = $importantPart['width'] - 1;
  445.                 $importantPart['width'] = 1;
  446.             }
  447.             if ($mode[1] === 'top')
  448.             {
  449.                 $importantPart['height'] = 1;
  450.             }
  451.             elseif ($mode[1] === 'bottom')
  452.             {
  453.                 $importantPart['y'] = $importantPart['height'] - 1;
  454.                 $importantPart['height'] = 1;
  455.             }
  456.         }
  457.         if (!$importantPart['width'] || !$importantPart['height'])
  458.         {
  459.             return null;
  460.         }
  461.         return new ImportantPart(
  462.             $importantPart['x'] / $this->fileObj->viewWidth,
  463.             $importantPart['y'] / $this->fileObj->viewHeight,
  464.             $importantPart['width'] / $this->fileObj->viewWidth,
  465.             $importantPart['height'] / $this->fileObj->viewHeight
  466.         );
  467.     }
  468.     /**
  469.      * Prepare resize configuration object.
  470.      *
  471.      * @return ResizeConfiguration
  472.      */
  473.     protected function prepareResizeConfig()
  474.     {
  475.         $resizeConfig = new ResizeConfiguration();
  476.         $resizeConfig->setWidth($this->targetWidth);
  477.         $resizeConfig->setHeight($this->targetHeight);
  478.         $resizeConfig->setZoomLevel($this->zoomLevel);
  479.         if (substr_count($this->resizeMode'_') === 1)
  480.         {
  481.             $resizeConfig->setMode(ResizeConfiguration::MODE_CROP);
  482.             $resizeConfig->setZoomLevel(0);
  483.         }
  484.         else
  485.         {
  486.             try
  487.             {
  488.                 $resizeConfig->setMode($this->resizeMode);
  489.             }
  490.             catch (\Throwable $exception)
  491.             {
  492.                 $resizeConfig->setMode(ResizeConfiguration::MODE_CROP);
  493.             }
  494.         }
  495.         return $resizeConfig;
  496.     }
  497.     /**
  498.      * Calculate the resize coordinates
  499.      *
  500.      * @return array The resize coordinates (width, height, target_x, target_y, target_width, target_height)
  501.      */
  502.     public function computeResize()
  503.     {
  504.         $resizeCoordinates System::getContainer()
  505.             ->get('contao.image.resize_calculator')
  506.             ->calculate(
  507.                 $this->prepareResizeConfig(),
  508.                 new ImageDimensions(
  509.                     new Box($this->fileObj->viewWidth$this->fileObj->viewHeight),
  510.                     $this->fileObj->viewWidth !== $this->fileObj->width
  511.                 ),
  512.                 $this->prepareImportantPart()
  513.             )
  514.         ;
  515.         return array
  516.         (
  517.             'width' => $resizeCoordinates->getCropSize()->getWidth(),
  518.             'height' => $resizeCoordinates->getCropSize()->getHeight(),
  519.             'target_x' => -$resizeCoordinates->getCropStart()->getX(),
  520.             'target_y' => -$resizeCoordinates->getCropStart()->getY(),
  521.             'target_width' => $resizeCoordinates->getSize()->getWidth(),
  522.             'target_height' => $resizeCoordinates->getSize()->getHeight(),
  523.         );
  524.     }
  525.     /**
  526.      * Get the relative path to an image
  527.      *
  528.      * @param string $src The image name or path
  529.      *
  530.      * @return string The relative path
  531.      */
  532.     public static function getPath($src)
  533.     {
  534.         if (!$src)
  535.         {
  536.             return '';
  537.         }
  538.         $src rawurldecode($src);
  539.         if (strpos($src'/') !== false)
  540.         {
  541.             return $src;
  542.         }
  543.         $projectDir System::getContainer()->getParameter('kernel.project_dir');
  544.         if (strncmp($src'icon'4) === 0)
  545.         {
  546.             if (pathinfo($srcPATHINFO_EXTENSION) == 'svg')
  547.             {
  548.                 return 'assets/contao/images/' $src;
  549.             }
  550.             $filename pathinfo($srcPATHINFO_FILENAME);
  551.             // Prefer SVG icons
  552.             if (file_exists($projectDir '/assets/contao/images/' $filename '.svg'))
  553.             {
  554.                 return 'assets/contao/images/' $filename '.svg';
  555.             }
  556.             return 'assets/contao/images/' $src;
  557.         }
  558.         $theme Backend::getTheme();
  559.         if (pathinfo($srcPATHINFO_EXTENSION) == 'svg')
  560.         {
  561.             return 'system/themes/' $theme '/icons/' $src;
  562.         }
  563.         $filename pathinfo($srcPATHINFO_FILENAME);
  564.         // Prefer SVG icons
  565.         if (file_exists($projectDir '/system/themes/' $theme '/icons/' $filename '.svg'))
  566.         {
  567.             return 'system/themes/' $theme '/icons/' $filename '.svg';
  568.         }
  569.         return 'system/themes/' $theme '/images/' $src;
  570.     }
  571.     /**
  572.      * Generate an image tag and return it as string
  573.      *
  574.      * @param string $src        The image path
  575.      * @param string $alt        An optional alt attribute
  576.      * @param string $attributes A string of other attributes
  577.      *
  578.      * @return string The image HTML tag
  579.      */
  580.     public static function getHtml($src$alt=''$attributes='')
  581.     {
  582.         $src = static::getPath($src);
  583.         if (!$src)
  584.         {
  585.             return '';
  586.         }
  587.         $container System::getContainer();
  588.         $projectDir $container->getParameter('kernel.project_dir');
  589.         $webDir StringUtil::stripRootDir($container->getParameter('contao.web_dir'));
  590.         if (!is_file($projectDir '/' $src))
  591.         {
  592.             try
  593.             {
  594.                 $deferredImage $container->get('contao.image.factory')->create($projectDir '/' $src);
  595.             }
  596.             catch (\Exception $e)
  597.             {
  598.                 $deferredImage null;
  599.             }
  600.             // Handle public bundle resources
  601.             if (file_exists($projectDir '/' $webDir '/' $src))
  602.             {
  603.                 $src $webDir '/' $src;
  604.             }
  605.             elseif (!$deferredImage instanceof DeferredImageInterface)
  606.             {
  607.                 return '';
  608.             }
  609.         }
  610.         $objFile = new File($src);
  611.         // Strip the contao.web_dir directory prefix (see #337)
  612.         if (strncmp($src$webDir '/', \strlen($webDir) + 1) === 0)
  613.         {
  614.             $src substr($src, \strlen($webDir) + 1);
  615.         }
  616.         $context = (strncmp($src'assets/'7) === 0) ? 'assets_context' 'files_context';
  617.         return '<img src="' Controller::addStaticUrlTo(System::urlEncode($src), $container->get('contao.assets.' $context)) . '" width="' $objFile->width '" height="' $objFile->height '" alt="' StringUtil::specialchars($alt) . '"' . ($attributes ' ' $attributes '') . '>';
  618.     }
  619.     /**
  620.      * Resize or crop an image and replace the original with the resized version
  621.      *
  622.      * @param string  $image  The image path
  623.      * @param integer $width  The target width
  624.      * @param integer $height The target height
  625.      * @param string  $mode   The resize mode
  626.      *
  627.      * @return boolean True if the image could be resized successfully
  628.      *
  629.      * @deprecated Deprecated since Contao 4.3, to be removed in Contao 5.0.
  630.      *             Use the contao.image.factory service instead.
  631.      */
  632.     public static function resize($image$width$height$mode='')
  633.     {
  634.         trigger_deprecation('contao/core-bundle''4.3''Using "Contao\Image::resize()" has been deprecated and will no longer work in Contao 5.0. Use the "contao.image.factory" service instead.');
  635.         return static::get($image$width$height$mode$imagetrue) ? true false;
  636.     }
  637.     /**
  638.      * Create an image instance from the given image path and size
  639.      *
  640.      * @param string|File          $image The image path or File instance
  641.      * @param array|integer|string $size  The image size as array (width, height, resize mode) or a tl_image_size ID or a predefined image size key
  642.      *
  643.      * @return static The created image instance
  644.      *
  645.      * @deprecated Deprecated since Contao 4.3, to be removed in Contao 5.0.
  646.      *             Use the contao.image.factory service instead.
  647.      */
  648.     public static function create($image$size=null)
  649.     {
  650.         trigger_deprecation('contao/core-bundle''4.3''Using "Contao\Image::create()" has been deprecated and will no longer work in Contao 5.0. Use the "contao.image.factory" service instead.');
  651.         if (\is_string($image))
  652.         {
  653.             $image = new File(rawurldecode($image));
  654.         }
  655.         $imageObj = new static($image);
  656.         if (\is_array($size) && !empty($size[2]))
  657.         {
  658.             // tl_image_size ID as resize mode
  659.             if (is_numeric($size[2]))
  660.             {
  661.                 $size = (int) $size[2];
  662.             }
  663.             // Predefined image size as resize mode
  664.             elseif (\is_string($size[2]) && $size[2][0] === '_')
  665.             {
  666.                 $size $size[2];
  667.             }
  668.         }
  669.         if (\is_array($size))
  670.         {
  671.             $size += array(00'crop');
  672.             $imageObj
  673.                 ->setTargetWidth($size[0])
  674.                 ->setTargetHeight($size[1])
  675.                 ->setResizeMode($size[2])
  676.             ;
  677.         }
  678.         // Load the image size from the database if $size is an ID or a predefined size
  679.         elseif (($imageSize self::getImageSizeConfig($size)) !== null)
  680.         {
  681.             $imageObj
  682.                 ->setTargetWidth($imageSize->width)
  683.                 ->setTargetHeight($imageSize->height)
  684.                 ->setResizeMode($imageSize->resizeMode)
  685.                 ->setZoomLevel($imageSize->zoom)
  686.             ;
  687.         }
  688.         $fileRecord FilesModel::findByPath($image->path);
  689.         $currentSize $image->imageViewSize;
  690.         // Set the important part
  691.         if ($fileRecord !== null && $fileRecord->importantPartWidth && $fileRecord->importantPartHeight)
  692.         {
  693.             $imageObj->setImportantPart(array
  694.             (
  695.                 'x' => (int) ($fileRecord->importantPartX $currentSize[0]),
  696.                 'y' => (int) ($fileRecord->importantPartY $currentSize[1]),
  697.                 'width' => (int) ($fileRecord->importantPartWidth $currentSize[0]),
  698.                 'height' => (int) ($fileRecord->importantPartHeight $currentSize[1]),
  699.             ));
  700.         }
  701.         return $imageObj;
  702.     }
  703.     private static function getImageSizeConfig($size)
  704.     {
  705.         if (is_numeric($size))
  706.         {
  707.             return ImageSizeModel::findByPk($size);
  708.         }
  709.         if (!\is_string($size) || $size[0] !== '_')
  710.         {
  711.             return null;
  712.         }
  713.         static $predefinedSizes null;
  714.         if ($predefinedSizes === null)
  715.         {
  716.             $factory System::getContainer()->get('contao.image.factory');
  717.             $predefinedSizes = (new \ReflectionObject($factory))->getProperty('predefinedSizes');
  718.             $predefinedSizes->setAccessible(true);
  719.             $predefinedSizes $predefinedSizes->getValue($factory) ?? array();
  720.         }
  721.         if (!isset($predefinedSizes[$size]))
  722.         {
  723.             return null;
  724.         }
  725.         $imageSize = new \stdClass();
  726.         $imageSize->width $predefinedSizes[$size]['width'];
  727.         $imageSize->height $predefinedSizes[$size]['height'];
  728.         $imageSize->resizeMode $predefinedSizes[$size]['resizeMode'];
  729.         $imageSize->zoom $predefinedSizes[$size]['zoom'];
  730.         return $imageSize;
  731.     }
  732.     /**
  733.      * Resize an image and store the resized version in the image target folder
  734.      *
  735.      * @param string  $image  The image path
  736.      * @param integer $width  The target width
  737.      * @param integer $height The target height
  738.      * @param string  $mode   The resize mode
  739.      * @param string  $target An optional target path
  740.      * @param boolean $force  Override existing target images
  741.      *
  742.      * @return string|null The path of the resized image or null
  743.      *
  744.      * @deprecated Deprecated since Contao 4.3, to be removed in Contao 5.0.
  745.      *             Use the contao.image.factory service instead.
  746.      */
  747.     public static function get($image$width$height$mode=''$target=null$force=false)
  748.     {
  749.         trigger_deprecation('contao/core-bundle''4.3''Using "Contao\Image::get()" has been deprecated and will no longer work in Contao 5.0. Use the "contao.image.factory" service instead.');
  750.         if (!$image)
  751.         {
  752.             return null;
  753.         }
  754.         try
  755.         {
  756.             $imageObj = static::create($image, array($width$height$mode));
  757.             $imageObj->setTargetPath($target);
  758.             $imageObj->setForceOverride($force);
  759.             if ($path $imageObj->executeResize()->getResizedPath())
  760.             {
  761.                 return $path;
  762.             }
  763.         }
  764.         catch (\Exception $e)
  765.         {
  766.             System::getContainer()->get('monolog.logger.contao.error')->error('Image "' $image '" could not be processed: ' $e->getMessage());
  767.         }
  768.         return null;
  769.     }
  770.     /**
  771.      * Convert sizes like 2em, 10cm or 12pt to pixels
  772.      *
  773.      * @param string $size The size string
  774.      *
  775.      * @return integer The pixel value
  776.      *
  777.      * @deprecated Deprecated since Contao 4.3, to be removed in Contao 5.0.
  778.      *             Use the contao.image.factory service instead.
  779.      */
  780.     public static function getPixelValue($size)
  781.     {
  782.         trigger_deprecation('contao/core-bundle''4.3''Using "Contao\Image::getPixelValue()" has been deprecated and will no longer work in Contao 5.0. Use the "contao.image.factory" service instead.');
  783.         $value preg_replace('/[^0-9.-]+/'''$size);
  784.         $unit preg_replace('/[^acehimnprtvwx%]/'''$size);
  785.         // Convert 16px = 1em = 2ex = 12pt = 1pc = 1/6in = 2.54/6cm = 25.4/6mm = 100%
  786.         switch ($unit)
  787.         {
  788.             case '':
  789.             case 'px':
  790.                 return (int) round($value);
  791.             case 'pc':
  792.             case 'em':
  793.                 return (int) round($value 16);
  794.             case 'ex':
  795.                 return (int) round($value 16 2);
  796.             case 'pt':
  797.                 return (int) round($value 16 12);
  798.             case 'in':
  799.                 return (int) round($value 16 6);
  800.             case 'cm':
  801.                 return (int) round($value 16 / (2.54 6));
  802.             case 'mm':
  803.                 return (int) round($value 16 / (25.4 6));
  804.             case '%':
  805.                 return (int) round($value 16 100);
  806.         }
  807.         return 0;
  808.     }
  809. }
  810. class_alias(Image::class, 'Image');