/** * Insert an image * * @param EventInterface $event An event instance */ public function insertImage(EventInterface $event) { $request = $event->getRequest(); $user = $request->getUser(); $image = $request->getImage(); $imageIdentifier = $image->getImageIdentifier(); $blob = $image->getBlob(); try { $exists = $event->getStorage()->imageExists($user, $imageIdentifier); $event->getStorage()->store($user, $imageIdentifier, $blob); } catch (StorageException $e) { $event->getDatabase()->deleteImage($user, $imageIdentifier); throw $e; } $event->getResponse()->setStatusCode($exists ? 200 : 201); }
/** * Handle GET requests * * @param EventInterface $event The current event */ public function get(EventInterface $event) { $response = $event->getResponse(); $database = $event->getDatabase(); $storage = $event->getStorage(); $databaseStatus = $database->getStatus(); $storageStatus = $storage->getStatus(); if (!$databaseStatus || !$storageStatus) { if (!$databaseStatus && !$storageStatus) { $message = 'Database and storage error'; } else { if (!$storageStatus) { $message = 'Storage error'; } else { $message = 'Database error'; } } $response->setStatusCode(503, $message); } $response->setMaxAge(0)->setPrivate(); $response->headers->addCacheControlDirective('no-store'); $statusModel = new Model\Status(); $statusModel->setDate(new DateTime('now', new DateTimeZone('UTC')))->setDatabaseStatus($databaseStatus)->setStorageStatus($storageStatus); $response->setModel($statusModel); }
/** * Choose an image variation based on the transformations and the original size of the image * * @param EventInterface $event The current event */ public function chooseVariation(EventInterface $event) { $request = $event->getRequest(); $response = $event->getResponse(); $publicKey = $request->getPublicKey(); $imageIdentifier = $request->getImageIdentifier(); // Fetch the original width / height of the image to use for ratio calculations $image = $response->getModel(); $imageWidth = $image->getWidth(); $imageHeight = $image->getHeight(); // Fetch the transformations from the request and find the max width used in the set $transformations = $request->getTransformations(); if (!$transformations) { // No transformations in the request return; } $maxWidth = $this->getMaxWidth($imageWidth, $imageHeight, $transformations); if (!$maxWidth) { // No need to use a variation based on the set of transformations return; } // Fetch the index of the transformation that decided the max width, and the width itself list($transformationIndex, $maxWidth) = each($maxWidth); if ($maxWidth >= $imageWidth) { // The width is the same or above the original, use the original return; } // WE HAVE A WINNER! Find the best variation. The width of the variation is the first // available one above the $maxWidth value $variation = $this->database->getBestMatch($publicKey, $imageIdentifier, $maxWidth); if (!$variation) { // Could not find any :( return; } // Now that we have a variation we can use we need to adjust some of the transformation // parameters. $event->getManager()->trigger('image.transformations.adjust', ['transformationIndex' => $transformationIndex, 'ratio' => $imageWidth / $variation['width']]); // Fetch the image variation blob from the storage adapter $imageBlob = $this->storage->getImageVariation($publicKey, $imageIdentifier, $variation['width']); if (!$imageBlob) { // The image blob does not exist in the storage, which it should. Trigger an error and // return trigger_error('Image variation storage is not in sync with the image variation database', E_USER_WARNING); return; } // Set some data that the storage operations listener usually sets, since that will be // skipped since we have an image variation $lastModified = $event->getStorage()->getLastModified($publicKey, $imageIdentifier); $response->setLastModified($lastModified); // Update the model $model = $response->getModel(); $model->setBlob($imageBlob)->setWidth($variation['width'])->setHeight($variation['height']); // Set a HTTP header that informs the user agent on which image variation that was used in // the transformations $response->headers->set('X-Imbo-ImageVariation', $variation['width'] . 'x' . $variation['height']); // Stop the propagation of this event $event->stopPropagation(); $event->getManager()->trigger('image.loaded'); }
/** * Transform the image * * @param EventInterface $event The event instance */ public function transform(EventInterface $event) { $image = $event->getArgument('image'); $params = $event->getArgument('params'); $width = !empty($params['width']) ? (int) $params['width'] : 0; $height = !empty($params['height']) ? (int) $params['height'] : 0; $imageIdentifier = !empty($params['img']) ? $params['img'] : $this->defaultImage; $position = !empty($params['position']) ? $params['position'] : $this->position; $x = !empty($params['x']) ? (int) $params['x'] : $this->x; $y = !empty($params['y']) ? (int) $params['y'] : $this->y; $opacity = (!empty($params['opacity']) ? (int) $params['opacity'] : 100) / 100; if (empty($imageIdentifier)) { throw new TransformationException('You must specify an image identifier to use for the watermark', 400); } // Try to load watermark image from storage try { $watermarkData = $event->getStorage()->getImage($event->getRequest()->getUser(), $imageIdentifier); $watermark = new Imagick(); $watermark->readImageBlob($watermarkData); $watermarkSize = $watermark->getImageGeometry(); $watermark->setImageOpacity($opacity); } catch (StorageException $e) { if ($e->getCode() == 404) { throw new TransformationException('Watermark image not found', 400); } throw $e; } // Should we resize the watermark? if ($height || $width) { // Calculate width or height if not both have been specified if (!$height) { $height = $watermarkSize['height'] / $watermarkSize['width'] * $width; } else { if (!$width) { $width = $watermarkSize['width'] / $watermarkSize['height'] * $height; } } $watermark->thumbnailImage($width, $height); } else { $width = $watermarkSize['width']; $height = $watermarkSize['height']; } // Determine placement of the watermark if ($position === 'top-right') { $x = $image->getWidth() - $width + $x; } else { if ($position === 'bottom-left') { $y = $image->getHeight() - $height + $y; } else { if ($position === 'bottom-right') { $x = $image->getWidth() - $width + $x; $y = $image->getHeight() - $height + $y; } else { if ($position === 'center') { $x = $image->getWidth() / 2 - $width / 2 + $x; $y = $image->getHeight() / 2 - $height / 2 + $y; } } } } // Now make a composite try { $this->imagick->compositeImage($watermark, Imagick::COMPOSITE_OVER, $x, $y); $image->hasBeenTransformed(true); } catch (ImagickException $e) { throw new TransformationException($e->getMessage(), 400, $e); } }