* thumbnail generation refactored
* thumbnail dimensions are also cached in db now
This commit is contained in:
parent
998d825d46
commit
71253ff1ac
@ -7,7 +7,6 @@ use Interop\Http\ServerMiddleware\DelegateInterface;
|
|||||||
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
|
use Interop\Http\ServerMiddleware\MiddlewareInterface as ServerMiddlewareInterface;
|
||||||
use Psr\Http\Message\ServerRequestInterface;
|
use Psr\Http\Message\ServerRequestInterface;
|
||||||
use Zend\Diactoros\Response;
|
use Zend\Diactoros\Response;
|
||||||
use Zend\Diactoros\Response\JsonResponse;
|
|
||||||
use Zend\Diactoros\Stream;
|
use Zend\Diactoros\Stream;
|
||||||
|
|
||||||
class GetImageAction implements ServerMiddlewareInterface
|
class GetImageAction implements ServerMiddlewareInterface
|
||||||
@ -25,18 +24,18 @@ class GetImageAction implements ServerMiddlewareInterface
|
|||||||
$image = $request->getAttribute('image', false);
|
$image = $request->getAttribute('image', false);
|
||||||
$thumb = $request->getAttribute('thumb', false);
|
$thumb = $request->getAttribute('thumb', false);
|
||||||
|
|
||||||
$imageFileName = $this->galleryService->getImage($slug, $image, $thumb);
|
$imageFileName = $this->galleryService->getImageFileName($slug, $image, $thumb);
|
||||||
$stream = new Stream(fopen($imageFileName, 'r'));
|
$imageStream = new Stream(fopen($imageFileName, 'r'));
|
||||||
$response = new Response();
|
$response = new Response();
|
||||||
return $response
|
return $response
|
||||||
->withHeader('Content-Type', (new \finfo(FILEINFO_MIME))->file($imageFileName))
|
->withHeader('Content-Type', (new \finfo(FILEINFO_MIME))->file($imageFileName))
|
||||||
->withHeader('Content-Disposition', 'attachment; filename=' . basename($imageFileName))
|
->withHeader('Content-Disposition', 'inline; filename=' . basename($imageFileName))
|
||||||
->withHeader('Content-Transfer-Encoding', 'Binary')
|
->withHeader('Content-Transfer-Encoding', 'Binary')
|
||||||
->withHeader('Content-Description', 'File Transfer')
|
->withHeader('Content-Description', 'File Transfer')
|
||||||
->withHeader('Pragma', 'public')
|
->withHeader('Pragma', 'public')
|
||||||
// ->withHeader('Expires', '0')
|
// ->withHeader('Expires', '0')
|
||||||
// ->withHeader('Cache-Control', 'must-revalidate')
|
// ->withHeader('Cache-Control', 'must-revalidate')
|
||||||
->withBody($stream)
|
->withBody($imageStream)
|
||||||
->withHeader('Content-Length', "{$stream->getSize()}");
|
->withHeader('Content-Length', "{$imageStream->getSize()}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -56,6 +56,18 @@ class Image implements \JsonSerializable
|
|||||||
*/
|
*/
|
||||||
private $height = 0;
|
private $height = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="thumb_width", type="integer")
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $thumbWidth = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ORM\Column(name="thumb_type", type="integer")
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $thumbHeight = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return int
|
* @return int
|
||||||
*/
|
*/
|
||||||
@ -164,6 +176,42 @@ class Image implements \JsonSerializable
|
|||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getThumbWidth(): ?int
|
||||||
|
{
|
||||||
|
return $this->thumbWidth;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $width
|
||||||
|
* @return Image
|
||||||
|
*/
|
||||||
|
public function setThumbWidth(?int $width): Image
|
||||||
|
{
|
||||||
|
$this->thumbWidth = $width;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getThumbHeight(): ?int
|
||||||
|
{
|
||||||
|
return $this->thumbHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $height
|
||||||
|
* @return Image
|
||||||
|
*/
|
||||||
|
public function setThumbHeight(?int $height): Image
|
||||||
|
{
|
||||||
|
$this->thumbHeight = $height;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function jsonSerialize()
|
public function jsonSerialize()
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
@ -172,6 +220,8 @@ class Image implements \JsonSerializable
|
|||||||
'path' => $this->getPath(),
|
'path' => $this->getPath(),
|
||||||
'width' => $this->getWidth(),
|
'width' => $this->getWidth(),
|
||||||
'height' => $this->getHeight(),
|
'height' => $this->getHeight(),
|
||||||
|
'thumbWidth' => $this->getThumbWidth(),
|
||||||
|
'thumbHeight' => $this->getThumbHeight(),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -36,98 +36,6 @@ class GalleryService
|
|||||||
$this->em = $entityManager;
|
$this->em = $entityManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function loadGalleryData($includeHidden = false)
|
|
||||||
{
|
|
||||||
$config = $this->getConfig();
|
|
||||||
$albums = [];
|
|
||||||
foreach ($config['galleries'] as $id => $data) {
|
|
||||||
if ($includeHidden || $data['public']) {
|
|
||||||
$albums[] = [
|
|
||||||
'slug' => $id,
|
|
||||||
'name' => $data['name'],
|
|
||||||
'coverImage' => isset($data['cover'])
|
|
||||||
? $this->getCoverImage($data['cover'])
|
|
||||||
: null,
|
|
||||||
'date' => $this->getGalleryDate($data['dir']),
|
|
||||||
'type' => $data['type'],
|
|
||||||
'isNew' => $data['new'],
|
|
||||||
'isPublic' => $data['public'],
|
|
||||||
'images' => $this->loadGalleryImages($data['dir']),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $albums;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getGalleryDate(string $dir): string
|
|
||||||
{
|
|
||||||
$timestamp = sprintf("@%s", filemtime(sprintf(self::IMAGE_BASEDIR, $dir)));
|
|
||||||
$date = new \DateTime($timestamp);
|
|
||||||
return $date->format("Y-m-d");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $dir
|
|
||||||
* @return Image[]
|
|
||||||
* @todo implement label for image in some way
|
|
||||||
*/
|
|
||||||
private function loadGalleryImages(string $dir): array
|
|
||||||
{
|
|
||||||
$images = array_map('basename', glob(
|
|
||||||
sprintf(self::IMAGE_BASEDIR . "*.{jpg,jpeg,png}", $dir),
|
|
||||||
GLOB_BRACE
|
|
||||||
));
|
|
||||||
$imagine = new Imagine();
|
|
||||||
return array_map(function ($image) use ($dir, $imagine) {
|
|
||||||
$imageEntity = $this->em->getRepository(Image::class)->findOneBy([
|
|
||||||
'dir' => $dir,
|
|
||||||
'path' => $image,
|
|
||||||
]);
|
|
||||||
if (null === $imageEntity) {
|
|
||||||
$imageEntity = new Image();
|
|
||||||
$imageEntity->setLabel("")
|
|
||||||
->setDir($dir)
|
|
||||||
->setPath($image);
|
|
||||||
$this->processImageSizes($dir, $imageEntity, $imagine);
|
|
||||||
$this->em->persist($imageEntity);
|
|
||||||
$this->em->flush();
|
|
||||||
}
|
|
||||||
return $imageEntity;
|
|
||||||
}, $images);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function processImageSizes(string $dir, Image $image, Imagine $imagine)
|
|
||||||
{
|
|
||||||
$img = $imagine->open(sprintf(self::IMAGE_BASEDIR, $dir) . $image->getPath());
|
|
||||||
$imgSize = $img->getSize();
|
|
||||||
$image->setWidth($imgSize->getWidth())
|
|
||||||
->setHeight($imgSize->getHeight());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $image
|
|
||||||
* @return Image
|
|
||||||
*/
|
|
||||||
private function getCoverImage(string $image): Image
|
|
||||||
{
|
|
||||||
$img = new Image();
|
|
||||||
return $img->setLabel("")
|
|
||||||
->setPath($image)
|
|
||||||
->setWidth(0)
|
|
||||||
->setHeight(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getImage(string $slug, string $image, $size = false): string
|
|
||||||
{
|
|
||||||
$config = $this->getConfig();
|
|
||||||
$galleryDir = sprintf(self::IMAGE_BASEDIR, $config['galleries'][$slug]['dir']);
|
|
||||||
$imageFileName = $size
|
|
||||||
? $this->getResizedImageName($galleryDir, $image, $size)
|
|
||||||
: ($galleryDir . $image);
|
|
||||||
|
|
||||||
return $imageFileName;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function exportGallery(string $slug)
|
public function exportGallery(string $slug)
|
||||||
{
|
{
|
||||||
$config = $this->getConfig();
|
$config = $this->getConfig();
|
||||||
@ -149,18 +57,98 @@ class GalleryService
|
|||||||
return $zipName;
|
return $zipName;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getResizedImageName($galleryDirectory, $imageName, $size): string
|
public function loadGalleryData($includeHidden = false)
|
||||||
{
|
{
|
||||||
$numericSize = $size == 'thumb' ? self::THUMBNAIL_SIZE : $size;
|
$config = $this->getConfig();
|
||||||
|
$albums = [];
|
||||||
|
foreach ($config['galleries'] as $id => $data) {
|
||||||
|
if ($includeHidden || $data['public']) {
|
||||||
|
$galleryImages = $this->loadGalleryImages($data['dir']);
|
||||||
|
$albums[] = [
|
||||||
|
'slug' => $id,
|
||||||
|
'name' => $data['name'],
|
||||||
|
'coverImage' => isset($data['cover'])
|
||||||
|
? $this->getCoverImage($galleryImages, $data['cover'])
|
||||||
|
: null,
|
||||||
|
'date' => $this->getGalleryDate($data['dir']),
|
||||||
|
'type' => $data['type'],
|
||||||
|
'isNew' => $data['new'],
|
||||||
|
'isPublic' => $data['public'],
|
||||||
|
'images' => $galleryImages,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $albums;
|
||||||
|
}
|
||||||
|
|
||||||
$thumbPath = $galleryDirectory . "thumb_" . $numericSize;
|
private function getCoverImage(array &$images, string $coverFileName): Image
|
||||||
|
{
|
||||||
|
$filtered = array_values(array_filter($images, function(Image $image) use ($coverFileName) {
|
||||||
|
return $image->getPath() == $coverFileName;
|
||||||
|
}));
|
||||||
|
return array_pop($filtered);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getGalleryDate(string $dir): string
|
||||||
|
{
|
||||||
|
$timestamp = sprintf("@%s", filemtime($this->getImageDir($dir)));
|
||||||
|
$date = new \DateTime($timestamp);
|
||||||
|
return $date->format("Y-m-d");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $dir
|
||||||
|
* @return Image[]
|
||||||
|
* @todo implement label for image in some way
|
||||||
|
*/
|
||||||
|
private function loadGalleryImages(string $dir): array
|
||||||
|
{
|
||||||
|
$images = array_map('basename', glob(
|
||||||
|
sprintf(self::IMAGE_BASEDIR . "*.{jpg,jpeg,png}", $dir),
|
||||||
|
GLOB_BRACE
|
||||||
|
));
|
||||||
|
$imagine = new Imagine();
|
||||||
|
return array_map(function ($imagePath) use ($dir, $imagine) {
|
||||||
|
$imageEntity = $this->em->getRepository(Image::class)->findOneBy([
|
||||||
|
'dir' => $dir,
|
||||||
|
'path' => $imagePath,
|
||||||
|
]);
|
||||||
|
$this->ensureThumbnailExists($dir, $imagePath);
|
||||||
|
if (null === $imageEntity) {
|
||||||
|
$image = $imagine->open($this->getImageDir($dir) . $imagePath);
|
||||||
|
$imageSize = $image->getSize();
|
||||||
|
unset($image);
|
||||||
|
|
||||||
|
$thumb = $imagine->open($this->getThumbDir($dir) . $imagePath);
|
||||||
|
$thumbSize = $thumb->getSize();
|
||||||
|
unset($thumb);
|
||||||
|
|
||||||
|
$imageEntity = new Image();
|
||||||
|
$imageEntity->setLabel("")
|
||||||
|
->setDir($dir)
|
||||||
|
->setPath($imagePath)
|
||||||
|
->setWidth($imageSize->getWidth())
|
||||||
|
->setHeight($imageSize->getHeight())
|
||||||
|
->setThumbWidth($thumbSize->getWidth())
|
||||||
|
->setThumbHeight($thumbSize->getHeight())
|
||||||
|
;
|
||||||
|
$this->em->persist($imageEntity);
|
||||||
|
$this->em->flush();
|
||||||
|
}
|
||||||
|
return $imageEntity;
|
||||||
|
}, $images);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function ensureThumbnailExists(string $dir, string $imageName) {
|
||||||
|
$imageDir = $this->getImageDir($dir);
|
||||||
|
$thumbPath = $imageDir . "thumb_" . self::THUMBNAIL_SIZE;
|
||||||
@mkdir($thumbPath);
|
@mkdir($thumbPath);
|
||||||
$thumbImageName = $thumbPath . "/" . $imageName;
|
$thumbImageName = $thumbPath . "/" . $imageName;
|
||||||
|
|
||||||
if (!file_exists($thumbImageName)) {
|
if (!file_exists($thumbImageName)) {
|
||||||
$thumbSize = new Box($numericSize, $numericSize*10);
|
$thumbSize = new Box(self::THUMBNAIL_SIZE, self::THUMBNAIL_SIZE * 10);
|
||||||
$imagine = new Imagine();
|
$imagine = new Imagine();
|
||||||
$image = $imagine->open($galleryDirectory . $imageName)
|
$image = $imagine->open($imageDir . $imageName)
|
||||||
->thumbnail($thumbSize, ImageInterface::THUMBNAIL_INSET);
|
->thumbnail($thumbSize, ImageInterface::THUMBNAIL_INSET);
|
||||||
$image->effects()->sharpen();
|
$image->effects()->sharpen();
|
||||||
$image->save($thumbImageName);
|
$image->save($thumbImageName);
|
||||||
@ -169,7 +157,25 @@ class GalleryService
|
|||||||
return $thumbImageName;
|
return $thumbImageName;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getConfig()
|
public function getImageFileName(string $slug, string $image, $isThumbnail = false): string
|
||||||
|
{
|
||||||
|
$config = $this->getConfig();
|
||||||
|
$dir = $config['galleries'][$slug]['dir'];
|
||||||
|
$this->ensureThumbnailExists($config['galleries'][$slug]['dir'], $image);
|
||||||
|
return $isThumbnail
|
||||||
|
? ($this->getThumbDir($dir) . $image)
|
||||||
|
: ($this->getImageDir($dir) . $image);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getImageDir($dir): string {
|
||||||
|
return sprintf(self::IMAGE_BASEDIR, $dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getThumbDir($dir): string {
|
||||||
|
return sprintf(self::IMAGE_BASEDIR, "{$dir}/thumb_" . self::THUMBNAIL_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getConfig()
|
||||||
{
|
{
|
||||||
if (null === $this->config) {
|
if (null === $this->config) {
|
||||||
$parser = new Parser();
|
$parser = new Parser();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user