Pimcore\Model\Asset\Image\Thumbnail\Processor::process PHP Метод

process() публичный статический Метод

public static process ( $asset, Config $config, null $fileSystemPath = null, boolean $deferred = false, boolean $returnAbsolutePath = false, boolean &$generated = false ) : mixed | string
$asset
$config Config
$fileSystemPath null
$deferred boolean deferred means that the image will be generated on-the-fly (details see below)
$returnAbsolutePath boolean
$generated boolean
Результат mixed | string
    public static function process($asset, Config $config, $fileSystemPath = null, $deferred = false, $returnAbsolutePath = false, &$generated = false)
    {
        $generated = false;
        $errorImage = PIMCORE_PATH . "/static6/img/filetype-not-supported.png";
        $format = strtolower($config->getFormat());
        $contentOptimizedFormat = false;
        if (!$fileSystemPath && $asset instanceof Asset) {
            $fileSystemPath = $asset->getFileSystemPath();
        }
        if ($asset instanceof Asset) {
            $id = $asset->getId();
        } else {
            $id = "dyn~" . crc32($fileSystemPath);
        }
        $fileExt = File::getFileExtension(basename($fileSystemPath));
        // simple detection for source type if SOURCE is selected
        if ($format == "source" || empty($format)) {
            $format = self::getAllowedFormat($fileExt, ["jpeg", "gif", "png"], "png");
            $contentOptimizedFormat = true;
            // format can change depending of the content (alpha-channel, ...)
        }
        if ($format == "print") {
            $format = self::getAllowedFormat($fileExt, ["svg", "jpeg", "png", "tiff"], "png");
            if (($format == "tiff" || $format == "svg") && \Pimcore\Tool::isFrontentRequestByAdmin()) {
                // return a webformat in admin -> tiff cannot be displayed in browser
                $format = "png";
                $deferred = false;
                // deferred is default, but it's not possible when using isFrontentRequestByAdmin()
            } elseif ($format == "tiff") {
                $transformations = $config->getItems();
                if (is_array($transformations) && count($transformations) > 0) {
                    foreach ($transformations as $transformation) {
                        if (!empty($transformation)) {
                            if ($transformation["method"] == "tifforiginal") {
                                return self::returnPath($fileSystemPath, $returnAbsolutePath);
                            }
                        }
                    }
                }
            } elseif ($format == "svg") {
                return self::returnPath($fileSystemPath, $returnAbsolutePath);
            }
        } elseif ($format == "tiff") {
            if (\Pimcore\Tool::isFrontentRequestByAdmin()) {
                // return a webformat in admin -> tiff cannot be displayed in browser
                $format = "png";
                $deferred = false;
                // deferred is default, but it's not possible when using isFrontentRequestByAdmin()
            }
        }
        $thumbDir = $asset->getImageThumbnailSavePath() . "/thumb__" . $config->getName();
        $filename = preg_replace("/\\." . preg_quote(File::getFileExtension($asset->getFilename())) . "/", "", $asset->getFilename());
        // add custom suffix if available
        if ($config->getFilenameSuffix()) {
            $filename .= "~-~" . $config->getFilenameSuffix();
        }
        // add high-resolution modifier suffix to the filename
        if ($config->getHighResolution() > 1) {
            $filename .= "@" . $config->getHighResolution() . "x";
        }
        $fileExtension = $format;
        if ($format == "original") {
            $fileExtension = \Pimcore\File::getFileExtension($fileSystemPath);
        }
        $filename .= "." . $fileExtension;
        $fsPath = $thumbDir . "/" . $filename;
        // deferred means that the image will be generated on-the-fly (when requested by the browser)
        // the configuration is saved for later use in Pimcore\Controller\Plugin\Thumbnail::routeStartup()
        // so that it can be used also with dynamic configurations
        if ($deferred) {
            // only add the config to the TmpStore if necessary (the config is auto-generated)
            if (!Config::getByName($config->getName())) {
                $configId = "thumb_" . $id . "__" . md5(str_replace(PIMCORE_TEMPORARY_DIRECTORY, "", $fsPath));
                TmpStore::add($configId, $config, "thumbnail_deferred");
            }
            return self::returnPath($fsPath, $returnAbsolutePath);
        }
        // all checks on the file system should be below the deferred part for performance reasons (remote file systems)
        if (!file_exists($fileSystemPath)) {
            return self::returnPath($errorImage, $returnAbsolutePath);
        }
        if (!is_dir(dirname($fsPath))) {
            File::mkdir(dirname($fsPath));
        }
        $path = self::returnPath($fsPath, false);
        // check for existing and still valid thumbnail
        if (is_file($fsPath) and filemtime($fsPath) >= filemtime($fileSystemPath)) {
            return self::returnPath($fsPath, $returnAbsolutePath);
        }
        // transform image
        $image = Asset\Image::getImageTransformInstance();
        $image->setPreserveColor($config->isPreserveColor());
        $image->setPreserveMetaData($config->isPreserveMetaData());
        if (!$image->load($fileSystemPath)) {
            return self::returnPath($errorImage, $returnAbsolutePath);
        }
        $image->setUseContentOptimizedFormat($contentOptimizedFormat);
        $startTime = StopWatch::microtime_float();
        $transformations = $config->getItems();
        // check if the original image has an orientation exif flag
        // if so add a transformation at the beginning that rotates and/or mirrors the image
        if (function_exists("exif_read_data")) {
            $exif = @exif_read_data($fileSystemPath);
            if (is_array($exif)) {
                if (array_key_exists("Orientation", $exif)) {
                    $orientation = intval($exif["Orientation"]);
                    if ($orientation > 1) {
                        $angleMappings = [2 => 180, 3 => 180, 4 => 180, 5 => 90, 6 => 90, 7 => 90, 8 => 270];
                        if (array_key_exists($orientation, $angleMappings)) {
                            array_unshift($transformations, ["method" => "rotate", "arguments" => ["angle" => $angleMappings[$orientation]]]);
                        }
                        // values that have to be mirrored, this is not very common, but should be covered anyway
                        $mirrorMappings = [2 => "vertical", 4 => "horizontal", 5 => "vertical", 7 => "horizontal"];
                        if (array_key_exists($orientation, $mirrorMappings)) {
                            array_unshift($transformations, ["method" => "mirror", "arguments" => ["mode" => $mirrorMappings[$orientation]]]);
                        }
                    }
                }
            }
        }
        if (is_array($transformations) && count($transformations) > 0) {
            $sourceImageWidth = PHP_INT_MAX;
            $sourceImageHeight = PHP_INT_MAX;
            if ($asset instanceof Asset\Image) {
                $sourceImageWidth = $asset->getWidth();
                $sourceImageHeight = $asset->getHeight();
            }
            $highResFactor = $config->getHighResolution();
            $calculateMaxFactor = function ($factor, $original, $new) {
                $newFactor = $factor * $original / $new;
                if ($newFactor < 1) {
                    // don't go below factor 1
                    $newFactor = 1;
                }
                return $newFactor;
            };
            // sorry for the goto/label - but in this case it makes life really easier and the code more readable
            prepareTransformations:
            foreach ($transformations as $transformation) {
                if (!empty($transformation)) {
                    $arguments = [];
                    $mapping = self::$argumentMapping[$transformation["method"]];
                    if (is_array($transformation["arguments"])) {
                        foreach ($transformation["arguments"] as $key => $value) {
                            $position = array_search($key, $mapping);
                            if ($position !== false) {
                                // high res calculations if enabled
                                if (!in_array($transformation["method"], ["cropPercent"]) && in_array($key, ["width", "height", "x", "y"])) {
                                    if ($highResFactor && $highResFactor > 1) {
                                        $value *= $highResFactor;
                                        $value = (int) ceil($value);
                                        // check if source image is big enough otherwise adjust the high-res factor
                                        if (in_array($key, ["width", "x"])) {
                                            if ($sourceImageWidth < $value) {
                                                $highResFactor = $calculateMaxFactor($highResFactor, $sourceImageWidth, $value);
                                                goto prepareTransformations;
                                            }
                                        } elseif (in_array($key, ["height", "y"])) {
                                            if ($sourceImageHeight < $value) {
                                                $highResFactor = $calculateMaxFactor($highResFactor, $sourceImageHeight, $value);
                                                goto prepareTransformations;
                                            }
                                        }
                                    }
                                }
                                $arguments[$position] = $value;
                            }
                        }
                    }
                    ksort($arguments);
                    if (method_exists($image, $transformation["method"])) {
                        call_user_func_array([$image, $transformation["method"]], $arguments);
                    }
                }
            }
        }
        $image->save($fsPath, $format, $config->getQuality());
        $generated = true;
        if ($contentOptimizedFormat) {
            $tmpStoreKey = str_replace(PIMCORE_TEMPORARY_DIRECTORY . "/", "", $fsPath);
            TmpStore::add($tmpStoreKey, "-", "image-optimize-queue");
        }
        clearstatcache();
        Logger::debug("Thumbnail " . $path . " generated in " . (StopWatch::microtime_float() - $startTime) . " seconds");
        // set proper permissions
        @chmod($fsPath, File::getDefaultMode());
        // quick bugfix / workaround, it seems that imagemagick / image optimizers creates sometimes empty PNG chunks (total size 33 bytes)
        // no clue why it does so as this is not continuous reproducible, and this is the only fix we can do for now
        // if the file is corrupted the file will be created on the fly when requested by the browser (because it's deleted here)
        if (is_file($fsPath) && filesize($fsPath) < 50) {
            unlink($fsPath);
        }
        return self::returnPath($fsPath, $returnAbsolutePath);
    }

Usage Example

Пример #1
0
 /**
  *
  */
 public function generate()
 {
     $errorImage = PIMCORE_PATH . '/static6/img/filetype-not-supported.png';
     $deferred = false;
     $generated = false;
     if (!$this->asset) {
         $this->filesystemPath = $errorImage;
     } elseif (!$this->filesystemPath) {
         $cs = $this->asset->getCustomSetting("image_thumbnail_time");
         $im = $this->asset->getCustomSetting("image_thumbnail_asset");
         if ($im || $this->imageAsset) {
             if ($this->imageAsset) {
                 $im = $this->imageAsset;
             } else {
                 $im = Model\Asset::getById($im);
             }
             if ($im instanceof Image) {
                 $imageThumbnail = $im->getThumbnail($this->getConfig());
                 $this->filesystemPath = $imageThumbnail->getFileSystemPath();
             }
         }
         if (!$this->filesystemPath) {
             $timeOffset = $this->timeOffset;
             if (!$this->timeOffset && $cs) {
                 $timeOffset = $cs;
             }
             // fallback
             if (!$timeOffset) {
                 $timeOffset = ceil($this->asset->getDuration() / 3);
             }
             $converter = \Pimcore\Video::getInstance();
             $converter->load($this->asset->getFileSystemPath());
             $path = PIMCORE_TEMPORARY_DIRECTORY . "/video-image-cache/video_" . $this->asset->getId() . "__thumbnail_" . $timeOffset . ".png";
             if (!is_dir(dirname($path))) {
                 File::mkdir(dirname($path));
             }
             if (!is_file($path)) {
                 $lockKey = "video_image_thumbnail_" . $this->asset->getId() . "_" . $timeOffset;
                 Model\Tool\Lock::acquire($lockKey);
                 // after we got the lock, check again if the image exists in the meantime - if not - generate it
                 if (!is_file($path)) {
                     $converter->saveImage($path, $timeOffset);
                     $generated = true;
                 }
                 Model\Tool\Lock::release($lockKey);
             }
             if ($this->getConfig()) {
                 $this->getConfig()->setFilenameSuffix("time-" . $timeOffset);
                 try {
                     $path = Image\Thumbnail\Processor::process($this->asset, $this->getConfig(), $path, $deferred, true, $generated);
                 } catch (\Exception $e) {
                     Logger::error("Couldn't create image-thumbnail of video " . $this->asset->getRealFullPath());
                     Logger::error($e);
                     $path = $errorImage;
                 }
             }
             $this->filesystemPath = $path;
         }
         \Pimcore::getEventManager()->trigger("asset.video.image-thumbnail", $this, ["deferred" => $deferred, "generated" => $generated]);
     }
 }
All Usage Examples Of Pimcore\Model\Asset\Image\Thumbnail\Processor::process