public function execute(Request $request, Config $config, WorkingFolder $workingFolder, ResizedImageRepository $resizedImageRepository, CacheManager $cache) { $fileName = (string) $request->query->get('fileName'); list($requestedWidth, $requestedHeight) = Image::parseSize((string) $request->get('size')); $downloadedFile = new DownloadedFile($fileName, $this->app); $downloadedFile->isValid(); if (!Image::isSupportedExtension(pathinfo($fileName, PATHINFO_EXTENSION), $config->get('thumbnails.bmpSupported'))) { throw new InvalidExtensionException('Unsupported image type or not image file'); } Utils::removeSessionCacheHeaders(); $response = new Response(); $response->setPublic(); $response->setEtag(dechex($downloadedFile->getTimestamp()) . "-" . dechex($downloadedFile->getSize())); $lastModificationDate = new \DateTime(); $lastModificationDate->setTimestamp($downloadedFile->getTimestamp()); $response->setLastModified($lastModificationDate); if ($response->isNotModified($request)) { return $response; } $imagePreviewCacheExpires = (int) $config->get('cache.imagePreview'); if ($imagePreviewCacheExpires > 0) { $response->setMaxAge($imagePreviewCacheExpires); $expireTime = new \DateTime(); $expireTime->modify('+' . $imagePreviewCacheExpires . 'seconds'); $response->setExpires($expireTime); } $cachedInfoPath = Path::combine($workingFolder->getResourceType()->getName(), $workingFolder->getClientCurrentFolder(), $fileName); $cachedInfo = $cache->get($cachedInfoPath); $resultImage = null; // Try to reuse existing resized image if ($cachedInfo && isset($cachedInfo['width']) && isset($cachedInfo['height'])) { // Fix received aspect ratio $size = Image::calculateAspectRatio($requestedWidth, $requestedHeight, $cachedInfo['width'], $cachedInfo['height']); $resizedImage = $resizedImageRepository->getResizedImageBySize($workingFolder->getResourceType(), $workingFolder->getClientCurrentFolder(), $fileName, $size['width'], $size['height']); if ($resizedImage) { $resultImage = Image::create($resizedImage->getImageData()); } } // Fallback - get and resize the original image if (null === $resultImage) { $resultImage = Image::create($downloadedFile->getContents(), $config->get('thumbnails.bmpSupported')); $cache->set($cachedInfoPath, $resultImage->getInfo()); $resultImage->resize($requestedWidth, $requestedHeight); } $mimeType = $resultImage->getMimeType(); if (in_array($mimeType, array('image/bmp', 'image/x-ms-bmp'))) { $mimeType = 'image/jpeg'; // Image::getData() by default converts resized images to JPG } $response->headers->set('Content-Type', $mimeType . '; name="' . $downloadedFile->getFileName() . '"'); $response->setContent($resultImage->getData()); return $response; }
/** * @param ResizedImageRepository $resizedImageRepository Resized image repository object * @param ResourceType $sourceFileResourceType Source image file resource type * @param string $sourceFileDir Resource type relative directory path * @param string $sourceFileName Source image filename * @param int $requestedWidth Requested width * @param int $requestedHeight Requested height * @param bool $forceRequestedSize A flag telling if the requested size should be used, without calculating the aspect ratio * * @throws \Exception if the source image is invalid */ public function __construct(ResizedImageRepository $resizedImageRepository, ResourceType $sourceFileResourceType, $sourceFileDir, $sourceFileName, $requestedWidth, $requestedHeight, $forceRequestedSize = false) { parent::__construct($sourceFileResourceType, $sourceFileDir, $sourceFileName, $requestedWidth, $requestedHeight); $this->resizedImageRepository = $resizedImageRepository; $backend = $this->backend = $sourceFileResourceType->getBackend(); // Check if there's info about source image in cache $app = $this->resizedImageRepository->getContainer(); if (!$forceRequestedSize) { $cacheKey = Path::combine($sourceFileResourceType->getName(), $sourceFileDir, $sourceFileName); $cachedInfo = $app['cache']->get($cacheKey); // No info cached, get original image if (null === $cachedInfo || !isset($cachedInfo['width']) || !isset($cachedInfo['height'])) { $sourceFilePath = Path::combine($sourceFileResourceType->getDirectory(), $sourceFileDir, $sourceFileName); if ($backend->isHiddenFile($sourceFileName) || !$backend->has($sourceFilePath)) { throw new FileNotFoundException('ResizedImage::create(): Source file not found'); } $originalImage = $this->image = Image::create($backend->read($sourceFilePath)); $app['cache']->set($cacheKey, $originalImage->getInfo()); $originalImageWidth = $originalImage->getWidth(); $originalImageHeight = $originalImage->getHeight(); } else { $originalImageWidth = $cachedInfo['width']; $originalImageHeight = $cachedInfo['height']; } $targetSize = Image::calculateAspectRatio($requestedWidth, $requestedHeight, $originalImageWidth, $originalImageHeight); if ($targetSize['width'] >= $originalImageWidth || $targetSize['height'] >= $originalImageHeight) { $this->width = $originalImageWidth; $this->height = $originalImageHeight; $this->requestedSizeIsValid = false; } else { $this->width = $targetSize['width']; $this->height = $targetSize['height']; } } else { $this->width = $requestedWidth; $this->height = $requestedHeight; } $this->resizedImageFileName = static::createFilename($sourceFileName, $this->width, $this->height); }